diff --git a/.github/notes/pr53-linux-sandbox-ci-userns.md b/.github/notes/pr53-linux-sandbox-ci-userns.md new file mode 100644 index 0000000..c29e3a9 --- /dev/null +++ b/.github/notes/pr53-linux-sandbox-ci-userns.md @@ -0,0 +1,91 @@ +# PR #53 Linux sandbox CI user-namespace blocker + +PR #53 adds the `codespace-linux-sandbox` helper and requires the Linux +isolation tests to exercise the real bubblewrap + seccomp path in CI rather +than silently skipping a failed probe. + +## Symptom + +GitHub Actions CI run #99 (`35383518697`) reached the dedicated +`crates/linux-sandbox` isolation tests, but all six tests failed at their +common helper probe. With probe stderr enabled, bubblewrap reported: + +```text +bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted +``` + +The helper then exited with status 1, so +`CODESPACE_REQUIRE_LINUX_SANDBOX=1` correctly turned the failed probe into a +hard CI failure. + +This is distinct from the earlier dependency-lock, Clippy, and unit-test +environment issues. The linux-sandbox unit suite, including the helper +self-reexec readable-root check, passed before the integration probe ran. + +## Cause + +The Restricted network profile uses bubblewrap network isolation +(`--unshare-net`). GitHub-hosted Ubuntu images can restrict unprivileged user +namespaces with either `kernel.unprivileged_userns_clone` or Ubuntu 24.04+ +AppArmor's `kernel.apparmor_restrict_unprivileged_userns` gate. In that host +configuration bubblewrap can create the sandbox process far enough to report +its loopback setup, but the netlink address operation is rejected with +`EPERM` / `RTM_NEWADDR`. + +This is a CI host prerequisite, not a reason to weaken the CodeSpace sandbox +profile. OpenAI's `codex-action` handles the same GitHub-hosted Linux condition +before running bubblewrap-backed Codex sandbox modes: + +- https://github.com/openai/codex-action/blob/main/action.yml + +## CI resolution + +The CodeSpace `ubuntu-latest` Rust job prepares the ephemeral GitHub-hosted +runner immediately after installing bubblewrap: + +```bash +current_userns="$(sysctl -n kernel.unprivileged_userns_clone 2>/dev/null || true)" +if [ -n "$current_userns" ] && [ "$current_userns" != "1" ]; then + sudo sysctl -w kernel.unprivileged_userns_clone=1 +fi + +current_apparmor="$(sysctl -n kernel.apparmor_restrict_unprivileged_userns 2>/dev/null || true)" +if [ -n "$current_apparmor" ] && [ "$current_apparmor" != "0" ]; then + sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 +fi +``` + +Both checks are conditional so older Ubuntu images without one of the sysctls +remain valid. The workflow currently runs on GitHub-hosted `ubuntu-latest`; +if a self-hosted runner is introduced, its host policy should be reviewed +explicitly rather than assuming this CI mutation is appropriate there. + +## Security / product scope + +This change is CI-host preparation only. It does **not**: + +- remove `--unshare-net`; +- change Restricted network policy or seccomp enforcement; +- make a failed sandbox probe skippable in Linux CI; +- add an unsandboxed fallback after a successful probe; +- change Runner/MCP wire contracts; or +- change production host sysctls at runtime. + +`CODESPACE_REQUIRE_LINUX_SANDBOX=1` remains scoped to the isolation integration +tests, so the CI contract is still: if the GitHub runner has been prepared for +bubblewrap and the real sandbox cannot start, the job fails. + +## Related PR #53 fixes + +The prior helper-readable-root change remains a separate correctness fix. The +pinned Codex Linux helper re-execs its own executable inside bubblewrap before +applying seccomp, so that infrastructure binary must remain readable in the +Minimal filesystem view. CI run #99 showed that the observed blocker occurs +earlier, during bubblewrap network-namespace setup; therefore the helper-read +fix should not be described as the root cause of the `RTM_NEWADDR` failure. + +References: + +- PR #53: https://github.com/novelKR/CodeSpace/pull/53 +- CI run #99: https://github.com/novelKR/CodeSpace/actions/runs/35383518697 +- helper-readable fix: `446929248e7240a5fe867971a5b666ced78dd58a` diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d6bd70..a67d4f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,8 @@ jobs: SCAN_BASE: ${{ github.event.pull_request.base.sha || github.event.before }} run: ./scripts/check-no-model-deps.sh - rust: + rust-format: + name: Rust / Format + upstream pin runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -26,7 +27,7 @@ jobs: submodules: true - uses: dtolnay/rust-toolchain@stable with: - components: rustfmt, clippy + components: rustfmt - name: Upstream pin run: PIN_ONLY=1 ./scripts/check-upstream-pin.sh - name: Format @@ -36,24 +37,174 @@ jobs: cargo fmt --check --manifest-path crates/codex-runtime/Cargo.toml cargo fmt --check --manifest-path crates/pty/Cargo.toml cargo fmt --check --manifest-path crates/file-system/Cargo.toml + cargo fmt --check --manifest-path crates/linux-sandbox/Cargo.toml + + rust-clippy: + name: Rust / Clippy (${{ matrix.name }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - name: root + command: cargo clippy --locked --all-targets -- -D warnings + - name: adapters + command: | + cargo clippy --locked --manifest-path crates/patch/Cargo.toml --all-targets -- -D warnings + cargo clippy --locked --manifest-path crates/pty/Cargo.toml --all-targets -- -D warnings + cargo clippy --locked --manifest-path crates/file-system/Cargo.toml --all-targets -- -D warnings + - name: codex-adapters + command: | + cargo clippy --locked --manifest-path crates/codex-runtime/Cargo.toml --all-targets -- -D warnings + cargo clippy --locked --manifest-path crates/linux-sandbox/Cargo.toml --all-targets -- -D warnings + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - name: Cache Cargo downloads + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} - name: Clippy + run: ${{ matrix.command }} + + rust-unit: + name: Rust / Unit (${{ matrix.name }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - name: patch + command: cargo test --locked --manifest-path crates/patch/Cargo.toml + - name: codex-runtime + command: cargo test --locked --manifest-path crates/codex-runtime/Cargo.toml + - name: pty + command: cargo test --locked --manifest-path crates/pty/Cargo.toml + - name: file-system + command: cargo test --locked --manifest-path crates/file-system/Cargo.toml + - name: linux-sandbox + command: cargo test --locked --manifest-path crates/linux-sandbox/Cargo.toml --lib + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - uses: dtolnay/rust-toolchain@stable + - name: Cache Cargo downloads + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} + - name: Unit tests + run: ${{ matrix.command }} + + rust-linux-isolation: + name: Rust / Linux isolation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - uses: dtolnay/rust-toolchain@stable + - name: Cache Cargo downloads + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} + - name: Install bubblewrap + run: sudo apt-get update && sudo apt-get install -y bubblewrap + - name: Enable unprivileged user namespaces for bubblewrap run: | - cargo clippy --all-targets -- -D warnings - cargo clippy --manifest-path crates/patch/Cargo.toml --all-targets -- -D warnings - cargo clippy --manifest-path crates/codex-runtime/Cargo.toml --all-targets -- -D warnings - cargo clippy --manifest-path crates/pty/Cargo.toml --all-targets -- -D warnings - cargo clippy --manifest-path crates/file-system/Cargo.toml --all-targets -- -D warnings - - name: Test + set -euo pipefail + + # GitHub-hosted Ubuntu may disable unprivileged user namespaces, or + # gate them through AppArmor. Either condition can make bwrap fail + # while bringing up the isolated loopback device for --unshare-net. + current_userns="$(sysctl -n kernel.unprivileged_userns_clone 2>/dev/null || true)" + if [ -n "$current_userns" ] && [ "$current_userns" != "1" ]; then + echo "Enabling kernel.unprivileged_userns_clone for bubblewrap." + sudo sysctl -w kernel.unprivileged_userns_clone=1 + fi + + current_apparmor="$(sysctl -n kernel.apparmor_restrict_unprivileged_userns 2>/dev/null || true)" + if [ -n "$current_apparmor" ] && [ "$current_apparmor" != "0" ]; then + echo "Disabling kernel.apparmor_restrict_unprivileged_userns for bubblewrap." + sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 + fi + - name: Build Linux sandbox helper + run: cargo build --locked --manifest-path crates/linux-sandbox/Cargo.toml --bin codespace-linux-sandbox + - name: Linux isolation tests + env: + CODESPACE_REQUIRE_LINUX_SANDBOX: "1" + run: cargo test --locked --manifest-path crates/linux-sandbox/Cargo.toml --test isolation + + rust-integration: + name: Rust / Integration + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - uses: dtolnay/rust-toolchain@stable + - name: Cache Cargo downloads + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} + - name: Install bubblewrap + run: sudo apt-get update && sudo apt-get install -y bubblewrap + - name: Enable unprivileged user namespaces for bubblewrap + run: | + set -euo pipefail + + current_userns="$(sysctl -n kernel.unprivileged_userns_clone 2>/dev/null || true)" + if [ -n "$current_userns" ] && [ "$current_userns" != "1" ]; then + sudo sysctl -w kernel.unprivileged_userns_clone=1 + fi + + current_apparmor="$(sysctl -n kernel.apparmor_restrict_unprivileged_userns 2>/dev/null || true)" + if [ -n "$current_apparmor" ] && [ "$current_apparmor" != "0" ]; then + sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 + fi + - name: Build helpers + run: | + cargo build --locked --manifest-path crates/patch/Cargo.toml --bin codespace-patch + cargo build --locked --manifest-path crates/codex-runtime/Cargo.toml --bin codespace-codex-runtime + cargo build --locked --manifest-path crates/linux-sandbox/Cargo.toml --bin codespace-linux-sandbox + - name: Workspace integration tests + env: + CODESPACE_PATCH_BIN: ${{ github.workspace }}/crates/patch/target/debug/codespace-patch + CODESPACE_RUNTIME_BIN: ${{ github.workspace }}/crates/codex-runtime/target/debug/codespace-codex-runtime + CODESPACE_LINUX_SANDBOX_BIN: ${{ github.workspace }}/crates/linux-sandbox/target/debug/codespace-linux-sandbox + run: cargo test --locked --workspace + + rust: + name: rust + if: ${{ always() }} + needs: + - rust-format + - rust-clippy + - rust-unit + - rust-linux-isolation + - rust-integration + runs-on: ubuntu-latest + steps: + - name: Require all Rust checks run: | - cargo test --manifest-path crates/patch/Cargo.toml - cargo build --manifest-path crates/patch/Cargo.toml --bin codespace-patch - cargo test --manifest-path crates/codex-runtime/Cargo.toml - cargo build --manifest-path crates/codex-runtime/Cargo.toml --bin codespace-codex-runtime - cargo test --manifest-path crates/pty/Cargo.toml - cargo test --manifest-path crates/file-system/Cargo.toml - # Worker apply_patch still shells out to the patch helper. Export - # CODESPACE_PATCH_BIN before workspace and UDS tests. RuntimeProcess - # tests spawn the worker when CODESPACE_RUNTIME_BIN is set. - export CODESPACE_PATCH_BIN="${PWD}/crates/patch/target/debug/codespace-patch" - export CODESPACE_RUNTIME_BIN="${PWD}/crates/codex-runtime/target/debug/codespace-codex-runtime" - cargo test --workspace + test "${{ needs.rust-format.result }}" = "success" + test "${{ needs.rust-clippy.result }}" = "success" + test "${{ needs.rust-unit.result }}" = "success" + test "${{ needs.rust-linux-isolation.result }}" = "success" + test "${{ needs.rust-integration.result }}" = "success" diff --git a/Cargo.lock b/Cargo.lock index 65747d2..d5bf8bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,7 +159,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -170,7 +170,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -283,7 +283,7 @@ checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -554,7 +554,7 @@ checksum = "6a1f896587b6f2c069c73d2f0913e2d590c3990285cd2f0b6aa02b786b4c679c" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -577,9 +577,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cc" -version = "1.4.6" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3eb0f42d6c360dc3f8a821f6bf2fdea7f72bfd36b3076eb0e6d1e9e0752fff4" +checksum = "54413ede23c2daf518f35156dfde027feb2374004d63bd497f983c8db9c0e313" dependencies = [ "find-msvc-tools", "jobserver", @@ -589,9 +589,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" [[package]] name = "cfg_aliases" @@ -688,7 +688,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -778,6 +778,19 @@ dependencies = [ "tokio", ] +[[package]] +name = "codespace-linux-sandbox" +version = "0.6.0" +dependencies = [ + "codex-linux-sandbox", + "codex-protocol", + "codex-sandboxing", + "codex-utils-path-uri", + "rama-error", + "rama-macros", + "rama-utils", +] + [[package]] name = "codespace-policy" version = "0.6.0" @@ -802,6 +815,7 @@ version = "0.6.0" dependencies = [ "codespace-domain", "codespace-fs", + "codespace-linux-sandbox", "codespace-policy", "codespace-pty", "hex", @@ -1133,6 +1147,28 @@ dependencies = [ "serde_json", ] +[[package]] +name = "codex-linux-sandbox" +version = "0.154.0" +dependencies = [ + "clap", + "codex-install-context", + "codex-network-proxy", + "codex-process-hardening", + "codex-protocol", + "codex-sandboxing", + "codex-utils-absolute-path", + "globset", + "landlock", + "libc", + "rustix", + "seccompiler", + "serde", + "serde_json", + "sha2", + "url", +] + [[package]] name = "codex-model-provider-info" version = "0.154.0" @@ -1223,6 +1259,13 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "codex-process-hardening" +version = "0.154.0" +dependencies = [ + "libc", +] + [[package]] name = "codex-protocol" version = "0.154.0" @@ -1757,7 +1800,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -1768,7 +1811,7 @@ checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785" dependencies = [ "darling_core", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -1928,7 +1971,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.3", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -1970,7 +2013,7 @@ checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -2162,7 +2205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -2252,7 +2295,7 @@ checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" dependencies = [ "cfg-if", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2293,9 +2336,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" +checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b" [[package]] name = "fixed_decimal" @@ -2454,7 +2497,7 @@ checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -2497,9 +2540,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" +checksum = "54ade96dc9003043bce7c035c85a9df5a858bfb2039c5a2e6fdf00f324f6c551" dependencies = [ "cc", "cfg-if", @@ -4684,7 +4727,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -4793,7 +4836,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5517,9 +5560,9 @@ dependencies = [ [[package]] name = "psl" -version = "2.1.232" +version = "2.1.233" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62834e308cc83aea5e30cd8c80b8aa82cdb104a3240c7f210d4f68d46e29f308" +checksum = "d667537a353e4c20b5d98fd3ea6dc687dfdf6b7e30662c74ce51308cae5b2474" dependencies = [ "psl-types", ] @@ -5626,7 +5669,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -6145,7 +6188,7 @@ checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -6332,7 +6375,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -6375,15 +6418,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ "bitflags 2.13.2", "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -6597,7 +6640,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals 0.30.0", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -6687,7 +6730,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -6709,7 +6752,7 @@ checksum = "f852137cce035d6a4df67ccce505ff6b3e9fd3a10e3e52b24dc71e650bb1a9bd" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -6768,7 +6811,7 @@ checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -6822,7 +6865,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -6975,7 +7018,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -7220,9 +7263,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.5" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ "proc-macro2", "quote", @@ -7257,7 +7300,7 @@ checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -7312,7 +7355,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -7370,7 +7413,7 @@ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -7487,7 +7530,7 @@ checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -7995,9 +8038,9 @@ checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f" [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] name = "unicode-normalization" @@ -8190,7 +8233,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", "wasm-bindgen-shared", ] @@ -8316,7 +8359,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -8807,7 +8850,7 @@ checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", "synstructure 0.14.0", ] @@ -8848,7 +8891,7 @@ checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", "synstructure 0.14.0", ] @@ -8904,7 +8947,7 @@ checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5aee395..899516b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] resolver = "2" members = ["crates/domain", "crates/policy", "crates/runner", "crates/store", "crates/server"] -exclude = ["crates/patch", "crates/codex-runtime", "crates/pty", "crates/file-system", "third_party"] +exclude = ["crates/patch", "crates/codex-runtime", "crates/pty", "crates/file-system", "crates/linux-sandbox", "third_party"] [workspace.package] version = "0.6.0" diff --git a/crates/codex-runtime/Cargo.lock b/crates/codex-runtime/Cargo.lock index 97f48e0..84b653a 100644 --- a/crates/codex-runtime/Cargo.lock +++ b/crates/codex-runtime/Cargo.lock @@ -790,6 +790,19 @@ dependencies = [ "tokio", ] +[[package]] +name = "codespace-linux-sandbox" +version = "0.6.0" +dependencies = [ + "codex-linux-sandbox", + "codex-protocol", + "codex-sandboxing", + "codex-utils-path-uri", + "rama-error", + "rama-macros", + "rama-utils", +] + [[package]] name = "codespace-policy" version = "0.6.0" @@ -813,6 +826,7 @@ version = "0.6.0" dependencies = [ "codespace-domain", "codespace-fs", + "codespace-linux-sandbox", "codespace-policy", "codespace-pty", "hex", @@ -1102,6 +1116,28 @@ dependencies = [ "serde_json", ] +[[package]] +name = "codex-linux-sandbox" +version = "0.154.0" +dependencies = [ + "clap", + "codex-install-context", + "codex-network-proxy", + "codex-process-hardening", + "codex-protocol", + "codex-sandboxing", + "codex-utils-absolute-path", + "globset", + "landlock", + "libc", + "rustix", + "seccompiler", + "serde", + "serde_json", + "sha2", + "url", +] + [[package]] name = "codex-model-provider-info" version = "0.154.0" diff --git a/crates/domain/src/execution.rs b/crates/domain/src/execution.rs index 52b7a8d..ac14a14 100644 --- a/crates/domain/src/execution.rs +++ b/crates/domain/src/execution.rs @@ -217,6 +217,17 @@ impl WorkspaceExecutionInfo { }, } } + + /// Overlay after a successful Linux helper probe. Restricted network + /// advertises OS enforcement; Enabled stays unenforced in this WP. + pub fn with_linux_command_sandbox(mut self, network_restricted: bool) -> Self { + self.isolation.command_sandbox = CommandSandboxState::LinuxSandbox; + if network_restricted { + self.network.enforcement = NetworkEnforcementState::Enforced; + self.network.client_may_escalate = false; + } + self + } } #[cfg(test)] @@ -313,6 +324,29 @@ mod tests { assert_eq!(json["process"]["capabilities"]["tty"]["supported"], true); } + #[test] + fn linux_sandbox_overlay_enforces_restricted_network() { + let exec = compose( + ClientEnvironmentKind::Host, + true, + EffectivePermissionInfo { + read: true, + write: true, + exec: true, + }, + ) + .with_linux_command_sandbox(true); + assert_eq!( + exec.isolation.command_sandbox, + CommandSandboxState::LinuxSandbox + ); + assert_eq!(exec.network.enforcement, NetworkEnforcementState::Enforced); + assert!(!exec.network.client_may_escalate); + let json = serde_json::to_value(&exec).unwrap(); + assert_eq!(json["isolation"]["command_sandbox"], "linux-sandbox"); + assert_eq!(json["network"]["enforcement"], "enforced"); + } + #[test] fn host_read_only_denies_write_and_exec() { let exec = compose( diff --git a/crates/linux-sandbox/Cargo.lock b/crates/linux-sandbox/Cargo.lock new file mode 100644 index 0000000..5759769 --- /dev/null +++ b/crates/linux-sandbox/Cargo.lock @@ -0,0 +1,6944 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocative" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8cf9afc79c83d514444b55df3935d317da54b1ce3b17a133c646889cc260de8" +dependencies = [ + "allocative_derive", + "bumpalo", + "ctor", + "hashbrown 0.16.1", + "num-bigint", +] + +[[package]] +name = "allocative_derive" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614043c56c1173b800acb007b81fd0cbc0a0d7d717b71ba705fc2230d0760a23" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +dependencies = [ + "libc", +] + +[[package]] +name = "annotate-snippets" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaf7e9dfbb6ab22c82e473cd1a8a7bd313c19a5b7e40970f3d89ef5a5c9e81e" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "appcontainer_common" +version = "0.8.0" +source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4" +dependencies = [ + "flatbuffers", + "getrandom 0.2.17", + "learning_mode_core", + "learning_mode_windows", + "process_security_environment_spec", + "sandbox_spec", + "serde", + "serde_json", + "thiserror 2.0.20", + "widestring", + "windows 0.62.2", + "windows-core 0.62.2", + "winreg 0.55.0", + "wxc_common", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" + +[[package]] +name = "asn1-rs" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f43a50ac4fdca5df8e885c21b835997f0a1cdee65494a6847694a98652d9d8" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom 7.1.3", + "num-traits", + "rusticata-macros", + "thiserror 2.0.20", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure 0.13.2", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-trait" +version = "0.1.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "asynk-strim" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52697735bdaac441a29391a9e97102c74c6ef0f9b60a40cf109b1b404e29d2f6" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "atomic" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "aws-lc-rs" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" +dependencies = [ + "aws-lc-sys", + "untrusted 0.7.1", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec 0.8.0", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bit-vec" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest", + "rayon-core", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + +[[package]] +name = "borsh" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "553c5d846a6ba5150c65e3b1b8ec073bcf1abc20f9b7220de384a4443ea4e20a" +dependencies = [ + "bytes", + "cfg_aliases 0.2.2", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bstr" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb31b46c14244e20ee9984b11bf5c992b91fb6939fea616e3512c8baecdbe5f" +dependencies = [ + "memchr", + "serde_core", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a1f896587b6f2c069c73d2f0913e2d590c3990285cd2f0b6aa02b786b4c679c" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "cc" +version = "1.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54413ede23c2daf518f35156dfde027feb2374004d63bd497f983c8db9c0e313" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex 2.0.1", +] + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + +[[package]] +name = "chacha20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "rand_core 0.10.1", +] + +[[package]] +name = "chardetng" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b8f0b65b7b08ae3c8187e8d77174de20cb6777864c6b832d8ad365999cf1ea" +dependencies = [ + "cfg-if", + "encoding_rs", + "memchr", +] + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "cidr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579504560394e388085d0c080ea587dfa5c15f7e251b4d5247d1e1a61d1d6928" + +[[package]] +name = "clap" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "clap_lex" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" + +[[package]] +name = "clipboard-win" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +dependencies = [ + "error-code", +] + +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "cmp_any" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9b18233253483ce2f65329a24072ec414db782531bdbb7d0bbc4bd2ce6b7e21" + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.20", +] + +[[package]] +name = "codespace-linux-sandbox" +version = "0.6.0" +dependencies = [ + "codex-linux-sandbox", + "codex-protocol", + "codex-sandboxing", + "codex-utils-path-uri", + "rama-error", + "rama-macros", + "rama-utils", + "serde_json", + "tempfile", +] + +[[package]] +name = "codex-api" +version = "0.154.0" +dependencies = [ + "async-channel", + "base64 0.22.1", + "bytes", + "chrono", + "codex-client", + "codex-http-client", + "codex-protocol", + "codex-utils-rustls-provider", + "codex-websocket-client", + "eventsource-stream", + "futures", + "http", + "regex-lite", + "schemars 0.8.22", + "serde", + "serde_json", + "thiserror 2.0.20", + "tokio", + "tokio-tungstenite", + "tokio-util", + "tracing", + "tungstenite", + "url", + "uuid", +] + +[[package]] +name = "codex-async-utils" +version = "0.154.0" +dependencies = [ + "tokio", + "tokio-util", +] + +[[package]] +name = "codex-client" +version = "0.154.0" +dependencies = [ + "codex-http-client", + "eventsource-stream", + "futures", + "http", + "rand 0.9.5", + "tokio", + "tracing", +] + +[[package]] +name = "codex-execpolicy" +version = "0.154.0" +dependencies = [ + "anyhow", + "clap", + "codex-utils-absolute-path", + "multimap", + "serde", + "serde_json", + "shlex 1.3.0", + "starlark", + "tempfile", + "thiserror 2.0.20", + "tokio", +] + +[[package]] +name = "codex-extension-items" +version = "0.154.0" +dependencies = [ + "codex-utils-absolute-path", + "schemars 0.8.22", + "serde", + "serde_json", + "ts-rs", +] + +[[package]] +name = "codex-http-client" +version = "0.154.0" +dependencies = [ + "bytes", + "codex-utils-rustls-provider", + "futures", + "http", + "native-tls", + "opentelemetry", + "reqwest", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "serde", + "serde_json", + "sha2", + "system-configuration", + "thiserror 2.0.20", + "tokio", + "tracing", + "tracing-opentelemetry", + "windows-sys 0.52.0", + "zstd", +] + +[[package]] +name = "codex-install-context" +version = "0.154.0" +dependencies = [ + "codex-utils-absolute-path", + "codex-utils-home-dir", + "semver", + "serde", + "serde_json", +] + +[[package]] +name = "codex-linux-sandbox" +version = "0.154.0" +dependencies = [ + "clap", + "codex-install-context", + "codex-network-proxy", + "codex-process-hardening", + "codex-protocol", + "codex-sandboxing", + "codex-utils-absolute-path", + "globset", + "landlock", + "libc", + "rustix", + "seccompiler", + "serde", + "serde_json", + "sha2", + "url", +] + +[[package]] +name = "codex-mxc-sandbox" +version = "0.154.0" +dependencies = [ + "anyhow", + "appcontainer_common", + "codex-protocol", + "learning_mode_windows", + "tracelogging", + "wxc_common", +] + +[[package]] +name = "codex-network-proxy" +version = "0.154.0" +dependencies = [ + "anyhow", + "base64 0.22.1", + "chrono", + "clap", + "codex-utils-absolute-path", + "codex-utils-home-dir", + "codex-utils-rustls-provider", + "globset", + "opentelemetry", + "rama-core", + "rama-http", + "rama-http-backend", + "rama-net", + "rama-socks5", + "rama-tcp", + "rama-tls-rustls", + "rama-unix", + "rand 0.9.5", + "rustls-native-certs", + "schannel", + "security-framework", + "serde", + "serde_json", + "sha2", + "thiserror 2.0.20", + "time", + "tokio", + "tracing", + "url", + "windows-sys 0.52.0", +] + +[[package]] +name = "codex-otel" +version = "0.154.0" +dependencies = [ + "chrono", + "codex-api", + "codex-protocol", + "codex-utils-absolute-path", + "codex-utils-string", + "eventsource-stream", + "gethostname", + "http", + "opentelemetry", + "opentelemetry-appender-tracing", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "opentelemetry_sdk", + "os_info", + "reqwest", + "serde", + "serde_json", + "strum_macros", + "thiserror 2.0.20", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-opentelemetry", + "tracing-subscriber", +] + +[[package]] +name = "codex-process-hardening" +version = "0.154.0" +dependencies = [ + "libc", +] + +[[package]] +name = "codex-protocol" +version = "0.154.0" +dependencies = [ + "chardetng", + "chrono", + "codex-async-utils", + "codex-execpolicy", + "codex-extension-items", + "codex-http-client", + "codex-network-proxy", + "codex-utils-absolute-path", + "codex-utils-image", + "codex-utils-path-uri", + "codex-utils-redacted-string", + "codex-utils-string", + "encoding_rs", + "gix-url", + "globset", + "http", + "icu_decimal", + "icu_locale_core", + "icu_provider", + "landlock", + "quick-xml", + "schemars 0.8.22", + "seccompiler", + "serde", + "serde_json", + "serde_with", + "strum", + "strum_macros", + "sys-locale", + "thiserror 2.0.20", + "tokio", + "tracing", + "ts-rs", + "uuid", + "wildmatch", +] + +[[package]] +name = "codex-sandboxing" +version = "0.154.0" +dependencies = [ + "anyhow", + "codex-mxc-sandbox", + "codex-network-proxy", + "codex-otel", + "codex-protocol", + "codex-utils-absolute-path", + "codex-utils-home-dir", + "codex-utils-path-uri", + "codex-utils-pty", + "codex-windows-sandbox", + "dunce", + "libc", + "regex-lite", + "serde_json", + "tokio", + "tracing", + "url", + "which", +] + +[[package]] +name = "codex-utils-absolute-path" +version = "0.154.0" +dependencies = [ + "dirs", + "dunce", + "schemars 0.8.22", + "serde", + "ts-rs", +] + +[[package]] +name = "codex-utils-cache" +version = "0.154.0" +dependencies = [ + "lru", + "sha1", + "tokio", +] + +[[package]] +name = "codex-utils-home-dir" +version = "0.154.0" +dependencies = [ + "codex-utils-absolute-path", + "dirs", +] + +[[package]] +name = "codex-utils-image" +version = "0.154.0" +dependencies = [ + "base64 0.22.1", + "codex-utils-cache", + "image", + "mime_guess", + "thiserror 2.0.20", + "tokio", +] + +[[package]] +name = "codex-utils-path-uri" +version = "0.154.0" +dependencies = [ + "base64 0.22.1", + "codex-utils-absolute-path", + "schemars 0.8.22", + "serde", + "thiserror 2.0.20", + "ts-rs", + "url", + "urlencoding", +] + +[[package]] +name = "codex-utils-pty" +version = "0.154.0" +dependencies = [ + "anyhow", + "filedescriptor", + "lazy_static", + "libc", + "log", + "portable-pty", + "shared_library", + "tokio", + "winapi", +] + +[[package]] +name = "codex-utils-redacted-string" +version = "0.154.0" +dependencies = [ + "schemars 0.8.22", + "serde", +] + +[[package]] +name = "codex-utils-rustls-provider" +version = "0.154.0" +dependencies = [ + "rustls", +] + +[[package]] +name = "codex-utils-string" +version = "0.154.0" +dependencies = [ + "regex-lite", + "serde", + "serde_json", +] + +[[package]] +name = "codex-websocket-client" +version = "0.154.0" +dependencies = [ + "codex-http-client", + "futures", + "rustls", + "tokio", + "tokio-rustls", + "tokio-tungstenite", + "url", +] + +[[package]] +name = "codex-windows-sandbox" +version = "0.154.0" +dependencies = [ + "anyhow", + "base64 0.22.1", + "chrono", + "codex-otel", + "codex-protocol", + "codex-utils-absolute-path", + "codex-utils-pty", + "codex-utils-string", + "dirs-next", + "dunce", + "glob", + "rand 0.8.8", + "serde", + "serde_json", + "tempfile", + "tokio", + "tracing-appender", + "windows 0.58.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-hex" +version = "1.19.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e59eef12462b0f9b0a3620219be5d639afd79fe39dff0a42c3997061f9298b4" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "proptest", + "serde_core", +] + +[[package]] +name = "const_format" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" +dependencies = [ + "const_format_proc_macros", + "konst", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cookie" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a373e3602691c3cdea496d2f0ee5935151e6168fe87739483c463db1b2f2f87" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206" +dependencies = [ + "cookie", + "document-features", + "idna", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core_detect" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + +[[package]] +name = "crc32fast" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam-channel" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b0cc327b5bc766e7fda9c9260cc0fa81b43a8e240440422dff70788e3f9ef1" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "csv" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde_core", +] + +[[package]] +name = "csv-core" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" +dependencies = [ + "memchr", +] + +[[package]] +name = "ctor" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d" +dependencies = [ + "link-section", + "linktime-proc-macro", +] + +[[package]] +name = "darling" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed17f5901b6630b993ca003def43f2f8ef4014fc13b047b57aad617ff32bc2ec" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6837e2cf7485aaae18f86181d2f0e9a7ed297a025e220aeabf63fdebd3a2ddff" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 3.0.6", +] + +[[package]] +name = "darling_macro" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785" +dependencies = [ + "darling_core", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "dashmap" +version = "6.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" + +[[package]] +name = "debugserver-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf6834a70ed14e8e4e41882df27190bea150f1f6ecf461f1033f8739cd8af4a" +dependencies = [ + "schemafy", + "serde", + "serde_json", +] + +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror 2.0.20", +] + +[[package]] +name = "der-parser" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom 7.1.3", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn 2.0.119", + "unicode-xid", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.5.3", + "windows-sys 0.59.0", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users 0.4.6", + "winapi", +] + +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.13.2", + "objc2", +] + +[[package]] +name = "display_container" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a110a75c96bedec8e65823dea00a1d710288b7a369d95fd8a0f5127639466fa" +dependencies = [ + "either", + "indenter", +] + +[[package]] +name = "displaydoc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "dupe" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed2bc011db9c93fbc2b6cdb341a53737a55bafb46dbb74cf6764fc33a2fbf9c" +dependencies = [ + "dupe_derive", +] + +[[package]] +name = "dupe_derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e195b4945e88836d826124af44fdcb262ec01ef94d44f14f4fb5103f19892a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "either" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "encoding_rs" +version = "0.8.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5ef0006ac9ab233c38522f5ae99cae3625151de8f706cacee1cba4b8e2832a" +dependencies = [ + "cfg-if", + "core_detect", + "multiversion", + "multiversion_no_op", + "rustversion", + "scopeguard", + "simdutf8", +] + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "endian-type" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "869b0adbda23651a9c5c0c3d270aac9fcb52e8622a8f2b17e57802d7791962f2" + +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "env_filter" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" +dependencies = [ + "env_filter", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "error-code" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5343afd4a8365a643ac588dab4cf234a190c7f6c88c9f6dd6ffe00837661b7" + +[[package]] +name = "event-listener" +version = "5.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" +dependencies = [ + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "eventsource-stream" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab" +dependencies = [ + "futures-core", + "nom 7.1.3", + "pin-project-lite", +] + +[[package]] +name = "fancy-regex" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f" +dependencies = [ + "bit-set", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" +dependencies = [ + "getrandom 0.4.3", +] + +[[package]] +name = "fd-lock" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" +dependencies = [ + "cfg-if", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "filedescriptor" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d" +dependencies = [ + "libc", + "thiserror 1.0.69", + "winapi", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b" + +[[package]] +name = "fixed_decimal" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79c3c892f121fff406e5dd6b28c1b30096b95111c30701a899d4f2b18da6d1bd" +dependencies = [ + "displaydoc", + "smallvec", + "writeable", +] + +[[package]] +name = "flatbuffers" +version = "25.12.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3" +dependencies = [ + "bitflags 2.13.2", + "rustc_version", +] + +[[package]] +name = "flate2" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +dependencies = [ + "crc32fast", + "miniz_oxide 0.9.1", + "zlib-rs", +] + +[[package]] +name = "fluent-uri" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "flume" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" +dependencies = [ + "fastrand", + "futures-core", + "futures-sink", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-executor" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" + +[[package]] +name = "futures-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "futures-sink" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generator" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54ade96dc9003043bce7c035c85a9df5a858bfb2039c5a2e6fdf00f324f6c551" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows-link", + "windows-result 0.4.1", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix", + "windows-link", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gix-path" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8fd1fe596dc393b538e1d5492c5585971a9311475b3255f7b889023df208476" +dependencies = [ + "bstr", + "gix-trace", + "gix-validate", + "thiserror 2.0.20", +] + +[[package]] +name = "gix-trace" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be3eb81d9dc914335923e50d52829c551feefd6a72d176c4130c546b67a60814" + +[[package]] +name = "gix-url" +version = "0.35.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a61ead12e33fa52ae92b207ee27554f646a8e7a3dad8b78da1582ec91eda0a6" +dependencies = [ + "bstr", + "gix-path", + "percent-encoding", + "thiserror 2.0.20", +] + +[[package]] +name = "gix-validate" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dae8780f63ed8a803b8bdabbd7aa5f5c5d74592c8b50eed875c1bb4f6545a6a" +dependencies = [ + "bstr", +] + +[[package]] +name = "glob" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + +[[package]] +name = "globset" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c34a9410465b45bd9787443bc7370f37735bad04b0f0cd57ff1a3186c98988" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "h2" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.14.2", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "headers" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" +dependencies = [ + "base64 0.22.1", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hickory-proto" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand 0.9.5", + "ring", + "thiserror 2.0.20", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "moka", + "once_cell", + "parking_lot", + "rand 0.9.5", + "resolv-conf", + "smallvec", + "thiserror 2.0.20", + "tokio", + "tracing", +] + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "http" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_decimal" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eb8f655bba2d0c0459e43a5b0e6cd3cd388109898fb3d85d048165e8b0abd08" +dependencies = [ + "displaydoc", + "fixed_decimal", + "icu_decimal_data", + "icu_locale_core", + "icu_locale_fallback", + "icu_plurals", + "icu_provider", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_decimal_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c887fc7d4c297cf3f9436864af9e3dba7f8be9415a6c2a7f392f3b1636298c" + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "serde", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locale_fallback" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "251af8e57c9400e3eb58242fe5b8b1152b2a64fdf4cf632f923c38ccee6f2fa9" +dependencies = [ + "icu_locale_core", + "icu_locale_fallback_data", + "icu_provider", + "potential_utf", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locale_fallback_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "decf2a22ec8fa68f1a0c1129a3f8583f8f8bc24e8b9ccbe98ead99f62a4dc3a8" + +[[package]] +name = "icu_normalizer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_plurals" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e475e6766ef87b1d3c1f97be6363995b0bfaeddbc789671615df598a97ff0593" +dependencies = [ + "fixed_decimal", + "icu_locale_fallback", + "icu_plurals_data", + "icu_provider", + "zerovec", +] + +[[package]] +name = "icu_plurals_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1251aa39a95e1333888e499b1263e1c196447a28948acf5bdabd82c046f153bf" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "serde", + "stable_deref_trait", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "image" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "gif", + "image-webp", + "moxcms", + "num-traits", + "png", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "indenter" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "inventory" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b" +dependencies = [ + "rustversion", +] + +[[package]] +name = "ipconfig" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222" +dependencies = [ + "socket2", + "widestring", + "windows-registry", + "windows-result 0.4.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "ipnet" +version = "2.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" + +[[package]] +name = "iri-string" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1663ee7d8cf2900cc1414b1e1eec9f348d6eaa3bcab07579f4726a4b8499f447" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jiff" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1baf72f08796de0260609515130699b890ac25f30e610ad894bc5856cafdb" +dependencies = [ + "defmt", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" +dependencies = [ + "defmt", + "log", +] + +[[package]] +name = "jiff-static" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "378268a1116ad67ae6228701118ac9f491d78fda38a40a1f1a9e1348de6f7212" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + +[[package]] +name = "landlock" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cca98e95f35b29d469dade6724c6f96cec9236640f745a0e99b0334ec320ab1" +dependencies = [ + "enumflags2", + "libc", + "thiserror 2.0.20", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "learning_mode_core" +version = "0.8.0" +source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4" +dependencies = [ + "same-file", + "serde", + "serde_json", + "sha2", + "tempfile", + "thiserror 2.0.20", +] + +[[package]] +name = "learning_mode_windows" +version = "0.8.0" +source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4" +dependencies = [ + "learning_mode_core", + "sha2", + "thiserror 2.0.20", + "windows 0.62.2", + "windows-core 0.62.2", + "wxc_common", +] + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "libredox" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6480ccc157a1389bb2e4891b24751b0f798ba640d22386f23143fbcc89da195a" +dependencies = [ + "libc", +] + +[[package]] +name = "link-section" +version = "0.19.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c29a617ce3df32c08497bdc1ab6e2376e0b17948ac166a2fbe5977c5954cd9" + +[[package]] +name = "linktime-proc-macro" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e57c38c1e860fd37c604281cdfb1dd2216977fd76a50f85ba2f388ef3219616" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "lock_free_hashtable" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebf3631712f5b790675292ff827af269f5d9f920c920b77dc41d0485e3719612" +dependencies = [ + "atomic", + "parking_lot", +] + +[[package]] +name = "log" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "logos" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff472f899b4ec2d99161c51f60ff7075eeb3097069a36050d8037a6325eb8154" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "192a3a2b90b0c05b27a0b2c43eecdb7c415e29243acc3f89cc8247a5b693045c" +dependencies = [ + "beef", + "fnv", + "lazy_static", + "proc-macro2", + "quote", + "regex-syntax", + "rustc_version", + "syn 2.0.119", +] + +[[package]] +name = "logos-derive" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "605d9697bcd5ef3a42d38efc51541aa3d6a4a25f7ab6d1ed0da5ac632a26b470" +dependencies = [ + "logos-codegen", +] + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "pin-utils", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lru" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff9840bcc50b71349309900da0ce7279aa336ae71d73250b07998932c7d97c25" +dependencies = [ + "hashbrown 0.17.1", +] + +[[package]] +name = "lru-slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4050469837a6ff301cd14c1f8f24f88549e6d548f24f64e2148eb0f72cebc51f" + +[[package]] +name = "lsp-types" +version = "0.97.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53353550a17c04ac46c585feb189c2db82154fc84b79c7a66c96c2c644f66071" +dependencies = [ + "bitflags 1.3.2", + "fluent-uri", + "serde", + "serde_json", + "serde_repr", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8863b587001c1b9a8a4e36008cebc6b3612cb1226fe2de94858e06092687b608" + +[[package]] +name = "md5" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebb8d8732c6a6df3d8f032a82911cfc747e00efb95cc46e8d0acd5b5b88570c" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "moka" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4293f18e7567a1caf3c584855554377025c65e0aa445344d04171f5ad63d19b9" +dependencies = [ + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "equivalent", + "parking_lot", + "portable-atomic", + "smallvec", + "tagptr", + "uuid", +] + +[[package]] +name = "moxcms" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" +dependencies = [ + "serde", +] + +[[package]] +name = "multiversion" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ca4bea16ffc3f443cf7d866912118196bfef4c6a1556ca00f9f9b00bb43f7c" +dependencies = [ + "multiversion-macros", +] + +[[package]] +name = "multiversion-macros" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d416831a7317ef4b08bee00b69cbbb9c8763da7959a7026244d6266869f9c83" +dependencies = [ + "proc-macro2", + "quote", + "rustversion", + "syn 3.0.6", +] + +[[package]] +name = "multiversion_no_op" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" + +[[package]] +name = "mxc_config_contract" +version = "0.8.0" +source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4" +dependencies = [ + "serde", + "serde_json", + "thiserror 2.0.20", +] + +[[package]] +name = "mxc_telemetry" +version = "0.8.0" +source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4" +dependencies = [ + "tracelogging", + "uuid", +] + +[[package]] +name = "native-tls" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases 0.1.1", + "libc", +] + +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases 0.2.2", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-integer" +version = "0.1.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.13.2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.13.2", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.13.2", + "dispatch2", + "objc2", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-location" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.13.2", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.13.2", + "block2", + "libc", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.13.2", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.13.2", + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image", + "objc2-core-location", + "objc2-core-text", + "objc2-foundation", + "objc2-quartz-core", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "oid-registry" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +dependencies = [ + "critical-section", + "portable-atomic", +] + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "openssl" +version = "0.10.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "foreign-types", + "libc", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "openssl-sys" +version = "0.9.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "opentelemetry" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror 2.0.20", + "tracing", +] + +[[package]] +name = "opentelemetry-appender-tracing" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6a1ac5ca3accf562b8c306fa8483c85f4390f768185ab775f242f7fe8fdcc2" +dependencies = [ + "opentelemetry", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "opentelemetry-http" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" +dependencies = [ + "async-trait", + "bytes", + "http", + "opentelemetry", + "reqwest", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f" +dependencies = [ + "http", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost", + "reqwest", + "serde_json", + "thiserror 2.0.20", + "tokio", + "tonic", + "tracing", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f" +dependencies = [ + "base64 0.22.1", + "const-hex", + "opentelemetry", + "opentelemetry_sdk", + "prost", + "serde", + "serde_json", + "tonic", + "tonic-prost", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e62e29dfe041afb8ed2a6c9737ab57db4907285d999ef8ad3a59092a36bdc846" + +[[package]] +name = "opentelemetry_sdk" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd" +dependencies = [ + "futures-channel", + "futures-executor", + "futures-util", + "opentelemetry", + "percent-encoding", + "rand 0.9.5", + "thiserror 2.0.20", + "tokio", + "tokio-stream", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "os_info" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf20a545b305cf1da722b236b5155c9bb35f1d5ceb28c048bd96ca842f41b5b" +dependencies = [ + "android_system_properties", + "log", + "nix 0.31.3", + "objc2", + "objc2-foundation", + "objc2-ui-kit", + "serde", + "windows-sys 0.61.2", +] + +[[package]] +name = "pagable" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b6c3024f51bd32fc2fbadedb27783151515348f24cdf2e0ad83270b844f449" +dependencies = [ + "allocative", + "anyhow", + "async-trait", + "blake3", + "bytemuck", + "dashmap", + "dupe", + "either", + "erased-serde 0.4.10", + "fancy-regex", + "indexmap 2.14.2", + "inventory", + "num-bigint", + "once_cell", + "pagable_derive", + "parking_lot", + "postcard", + "regex", + "sequence_trie", + "serde", + "serde_json", + "smallvec", + "sorted_vector_map", + "static_assertions", + "static_interner", + "strong_hash", + "take_mut", + "triomphe", +] + +[[package]] +name = "pagable_derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7332d8709796f21d6ffd1b0565e2846717cb56700f3cc1b1a3d0ba242c0b1512" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pem" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d354a98a3d1251555de99e8fdd8afda05573c31b82f59063a7b0a29b5527f120" +dependencies = [ + "base64 0.23.1", + "serde_core", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags 2.13.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.8.9", +] + +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "portable-atomic-util" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "portable-pty" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a596a2b3d2752d94f51fac2d4a96737b8705dddd311a32b9af47211f08671e" +dependencies = [ + "anyhow", + "bitflags 1.3.2", + "downcast-rs", + "filedescriptor", + "lazy_static", + "libc", + "log", + "nix 0.28.0", + "serial2", + "shared_library", + "shell-words", + "winapi", + "winreg 0.10.1", +] + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "crc", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "heapless", + "serde", +] + +[[package]] +name = "potential_utf" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +dependencies = [ + "serde_core", + "writeable", + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "process_security_environment_spec" +version = "0.8.0" +source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4" +dependencies = [ + "flatbuffers", +] + +[[package]] +name = "proptest" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" +dependencies = [ + "bitflags 2.13.2", + "num-traits", + "rand 0.9.5", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "unarray", +] + +[[package]] +name = "prost" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "psl" +version = "2.1.233" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d667537a353e4c20b5d98fd3ea6dc687dfdf6b7e30662c74ce51308cae5b2474" +dependencies = [ + "psl-types", +] + +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "publicsuffix" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" +dependencies = [ + "idna", + "psl-types", +] + +[[package]] +name = "pxfm" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quickcheck" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95c589f335db0f6aaa168a7cd27b1fc6920f5e1470c804f814d9cd6e62a0f70b" +dependencies = [ + "env_logger", + "log", + "rand 0.10.2", +] + +[[package]] +name = "quinn" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4051e23e9185c255a7e33ef59cdbca87a22d359052eecd22fc6b901fb37d9d11" +dependencies = [ + "bytes", + "cfg_aliases 0.2.2", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.20", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9746dbde176634f4f2f1faf2404e30a31b2bc1e9cafb5329c95d8177a18c9fc" +dependencies = [ + "bytes", + "getrandom 0.4.3", + "lru-slab", + "rand 0.10.2", + "rand_pcg", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.20", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" +dependencies = [ + "cfg_aliases 0.2.2", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type 0.1.2", + "nibble_vec", +] + +[[package]] +name = "radix_trie" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b4431027dcd37fc2a73ef740b5f233aa805897935b8bce0195e41bbf9a3289a" +dependencies = [ + "endian-type 0.2.0", + "nibble_vec", +] + +[[package]] +name = "rama-core" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b93751ab27c9d151e84c1100057eab3f2a6a1378bc31b62abd416ecb1847658" +dependencies = [ + "ahash", + "asynk-strim", + "bytes", + "futures", + "parking_lot", + "pin-project-lite", + "rama-error", + "rama-macros", + "rama-utils", + "serde", + "serde_json", + "tokio", + "tokio-graceful", + "tokio-util", + "tracing", +] + +[[package]] +name = "rama-dns" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e340fef2799277e204260b17af01bc23604712092eacd6defe40167f304baed8" +dependencies = [ + "ahash", + "hickory-resolver", + "rama-core", + "rama-net", + "rama-utils", + "serde", + "tokio", +] + +[[package]] +name = "rama-error" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c452aba1beb7e29b873ff32f304536164cffcc596e786921aea64e858ff8f40" + +[[package]] +name = "rama-http" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453d60af031e23af2d48995e41b17023f6150044738680508b63671f8d7417dd" +dependencies = [ + "ahash", + "base64 0.22.1", + "bitflags 2.13.2", + "chrono", + "const_format", + "csv", + "http", + "http-range-header", + "httpdate", + "iri-string", + "matchit", + "parking_lot", + "percent-encoding", + "pin-project-lite", + "radix_trie 0.3.0", + "rama-core", + "rama-error", + "rama-http-headers", + "rama-http-types", + "rama-net", + "rama-utils", + "rand 0.9.5", + "serde", + "serde_html_form", + "serde_json", + "tokio", + "uuid", +] + +[[package]] +name = "rama-http-backend" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ff6a3c8ae690be8167e43777ba0bf6b0c8c2f6de165c538666affe2a32fd81" +dependencies = [ + "h2", + "pin-project-lite", + "rama-core", + "rama-http", + "rama-http-core", + "rama-http-headers", + "rama-http-types", + "rama-net", + "rama-tcp", + "rama-unix", + "rama-utils", + "tokio", +] + +[[package]] +name = "rama-http-core" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3822be6703e010afec0bcfeb5dbb6e5a3b23ca5689d9b1215b66ce6446653b77" +dependencies = [ + "ahash", + "atomic-waker", + "futures-channel", + "httparse", + "httpdate", + "indexmap 2.14.2", + "itoa", + "parking_lot", + "pin-project-lite", + "rama-core", + "rama-http", + "rama-http-types", + "rama-utils", + "slab", + "tokio", + "tokio-test", + "want", +] + +[[package]] +name = "rama-http-headers" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d74fe0cd9bd4440827dc6dc0f504cf66065396532e798891dee2c1b740b2285" +dependencies = [ + "ahash", + "base64 0.22.1", + "chrono", + "const_format", + "httpdate", + "rama-core", + "rama-error", + "rama-http-types", + "rama-macros", + "rama-net", + "rama-utils", + "rand 0.9.5", + "serde", + "sha1", +] + +[[package]] +name = "rama-http-types" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6dae655a72da5f2b97cfacb67960d8b28c5025e62707b4c8c5f0c5c9843a444" +dependencies = [ + "ahash", + "bytes", + "const_format", + "fnv", + "http", + "http-body", + "http-body-util", + "itoa", + "memchr", + "mime", + "mime_guess", + "nom 8.0.0", + "pin-project-lite", + "rama-core", + "rama-error", + "rama-macros", + "rama-utils", + "rand 0.9.5", + "serde", + "serde_json", + "sync_wrapper", + "tokio", +] + +[[package]] +name = "rama-macros" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea18a110bcf21e35c5f194168e6914ccea45ffdd0fea51bc4b169fbeafef6428" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "rama-net" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b28ee9e1e5d39264414b71f5c33e7fbb66b382c3fac456fe0daad39cf5509933" +dependencies = [ + "ahash", + "const_format", + "flume", + "hex", + "ipnet", + "itertools", + "md5", + "nom 8.0.0", + "parking_lot", + "pin-project-lite", + "psl", + "radix_trie 0.3.0", + "rama-core", + "rama-http-types", + "rama-macros", + "rama-utils", + "serde", + "sha2", + "socket2", + "tokio", +] + +[[package]] +name = "rama-socks5" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5468b263516daaf258de32542c1974b7cbe962363ad913dcb669f5d46db0ef3e" +dependencies = [ + "byteorder", + "rama-core", + "rama-net", + "rama-tcp", + "rama-udp", + "rama-utils", + "tokio", +] + +[[package]] +name = "rama-tcp" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe60cd604f91196b3659a1b28945add2e8b10bd0b4e6373c93d024fb3197704b" +dependencies = [ + "pin-project-lite", + "rama-core", + "rama-dns", + "rama-http-types", + "rama-net", + "rama-utils", + "rand 0.9.5", + "tokio", +] + +[[package]] +name = "rama-tls-rustls" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "536d47f6b269fb20dffd45e4c04aa8b340698b3509326e3c36e444b4f33ce0d6" +dependencies = [ + "pin-project-lite", + "rama-core", + "rama-http-types", + "rama-net", + "rama-utils", + "rcgen", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "webpki-roots", + "x509-parser", +] + +[[package]] +name = "rama-udp" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36ed05e0ecac73e084e92a3a8b1fbf16fdae8958c506f0f0eada180a2d99eef4" +dependencies = [ + "rama-core", + "rama-net", + "tokio", + "tokio-util", +] + +[[package]] +name = "rama-unix" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91acb16d571428ba4cece072dfab90d2667cdfa910a7b3cb4530c3f31542d708" +dependencies = [ + "pin-project-lite", + "rama-core", + "rama-net", + "tokio", +] + +[[package]] +name = "rama-utils" +version = "0.3.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf28b18ba4a57f8334d7992d3f8020194ea359b246ae6f8f98b8df524c7a14ef" +dependencies = [ + "const_format", + "parking_lot", + "pin-project-lite", + "rama-macros", + "regex", + "serde", + "smallvec", + "smol_str", + "tokio", + "wildcard", +] + +[[package]] +name = "rand" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core 0.10.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rcgen" +version = "0.14.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8774e05a7d0de114588e6a28fe7e71694b82614ed569d86d8b389dfbc98b8ad8" +dependencies = [ + "aws-lc-rs", + "pem", + "rustls-pki-types", + "time", + "x509-parser", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "redox_users" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60dc65c0ff1a7ae1294b0c67b9f14baf70b644404010370171787bfac1038fc0" +dependencies = [ + "libredox", + "thiserror 2.0.20", +] + +[[package]] +name = "ref-cast" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "cookie", + "cookie_store", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "resolv-conf" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "rustix" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" +dependencies = [ + "bitflags 2.13.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.23.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "rustyline" +version = "14.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e8936da37efd9b6d4478277f4b2b9bb5cdb37a113e8d63222e58da647e63" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "clipboard-win", + "fd-lock", + "home", + "libc", + "log", + "memchr", + "nix 0.28.0", + "radix_trie 0.2.1", + "unicode-segmentation", + "unicode-width", + "utf8parse", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sandbox_spec" +version = "0.8.0" +source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4" +dependencies = [ + "flatbuffers", +] + +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "schemafy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aea5ba40287dae331f2c48b64dbc8138541f5e97ee8793caa7948c1f31d86d5" +dependencies = [ + "Inflector", + "schemafy_core", + "schemafy_lib", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "syn 1.0.109", +] + +[[package]] +name = "schemafy_core" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41781ae092f4fd52c9287efb74456aea0d3b90032d2ecad272bd14dbbcb0511b" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "schemafy_lib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e953db32579999ca98c451d80801b6f6a7ecba6127196c5387ec0774c528befa" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "schemafy_core", + "serde", + "serde_derive", + "serde_json", + "syn 1.0.109", +] + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.119", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "seccompiler" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4ae55de56877481d112a559bbc12667635fdaf5e005712fd4e2b2fa50ffc884" +dependencies = [ + "libc", +] + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "sequence_trie" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee22067b7ccd072eeb64454b9c6e1b33b61cd0d49e895fd48676a184580e0c3" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "serde_html_form" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acf96b1d9364968fce46ebb548f1c0e1d7eceae27bdff73865d42e6c7369d94" +dependencies = [ + "form_urlencoded", + "indexmap 2.14.2", + "itoa", + "ryu", + "serde_core", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_repr" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "935177bb8c0cd8ca1a4e6d1a2ac8988bea69cab4f9d3a31311e012ad27868ea4" +dependencies = [ + "base64 0.23.1", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.2", + "jiff", + "schemars 0.9.0", + "schemars 1.2.2", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d607aa01a3cb0ad757d6fd216136910db3c97b102fe686585689615a02dbcdc" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "serial2" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16809bc35793b19ce4e0c53924bc0dce3937f15487997cfdaed936004180730" +dependencies = [ + "cfg-if", + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "sha1" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared_library" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "shell-words" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba467056f1b547ed52077911161fc86985becbc60e8e1857c8a144dab0def891" +dependencies = [ + "serde", +] + +[[package]] +name = "smol_str" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aaa7368fcf4852a4c2dd92df0cace6a71f2091ca0a23391ce7f3a31833f1523" +dependencies = [ + "borsh", + "serde_core", +] + +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "sorted_vector_map" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94bf565ee1681b4473aa5a9d71d807347c28021bd1d8947cb626b02f42a0141f" +dependencies = [ + "itertools", + "quickcheck", +] + +[[package]] +name = "spin" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "starlark" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9062e866918dc4c9701c98ac99f7f4fa9e4b3b4edce306e147393bc75458c4fc" +dependencies = [ + "allocative", + "anyhow", + "blake3", + "bumpalo", + "cmp_any", + "dashmap", + "debugserver-types", + "derivative", + "derive_more", + "display_container", + "dupe", + "either", + "erased-serde 0.3.31", + "hashbrown 0.16.1", + "indexmap 2.14.2", + "inventory", + "itertools", + "maplit", + "memoffset", + "num-bigint", + "num-traits", + "once_cell", + "pagable", + "paste", + "ref-cast", + "regex", + "rustyline", + "serde", + "serde_json", + "starlark_derive", + "starlark_map", + "starlark_syntax", + "static_assertions", + "strong_hash", + "strsim 0.10.0", + "textwrap", + "thiserror 2.0.20", +] + +[[package]] +name = "starlark_derive" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "797e235eb70936bfa14fabf490bf7453e6f0caaf6b9c56fe4c9aff02aee7e66d" +dependencies = [ + "dupe", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "starlark_map" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234877898fd216af93b2f5798b08cbbdc1a2e8f16a622a258b1db23a61a1c4ba" +dependencies = [ + "allocative", + "dupe", + "equivalent", + "fxhash", + "hashbrown 0.16.1", + "pagable", + "serde", + "strong_hash", +] + +[[package]] +name = "starlark_syntax" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7492c571c531e68099c911cfd909d32659f1cc0910cf3adee9fce66e39d21f14" +dependencies = [ + "allocative", + "annotate-snippets", + "anyhow", + "derivative", + "derive_more", + "dupe", + "logos", + "lsp-types", + "memchr", + "num-bigint", + "num-traits", + "once_cell", + "pagable", + "starlark_map", + "thiserror 2.0.20", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "static_interner" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0a72d2480db611b8ee9287b4a2e0adc63c4d7fdd647d2a1a65d529fc234fd16" +dependencies = [ + "equivalent", + "lock_free_hashtable", +] + +[[package]] +name = "strong_hash" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0831334aea34390b6b6ec7af0a27f9ee6324ad3a69463e6b240d83d6b7bce9c9" +dependencies = [ + "ref-cast", + "strong_hash_derive", +] + +[[package]] +name = "strong_hash_derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace6b48b7c4383a39bd3b966cca41bc999003aab9f690a2f355525c924296928" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "symlink" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "synstructure" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "sys-locale" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" +dependencies = [ + "libc", +] + +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.13.2", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +dependencies = [ + "thiserror-impl 2.0.20", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "thread_local" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" +dependencies = [ + "displaydoc", + "serde_core", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" + +[[package]] +name = "tokio" +version = "1.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-graceful" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45740b38b48641855471cd402922e89156bdfbd97b69b45eeff170369cc18c7d" +dependencies = [ + "loom", + "pin-project-lite", + "slab", + "tokio", + "tracing", +] + +[[package]] +name = "tokio-macros" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c85f2c3ef0b1cd58b36682f4b17aaa995f0e5db534d85692b4903abce21f67" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-test" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6d24790a10a7af737693a3e8f1d03faef7e6ca0cc99aae5066f533766de545" +dependencies = [ + "futures-core", + "tokio", + "tokio-stream", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.28.0" +source = "git+https://github.com/openai-oss-forks/tokio-tungstenite?rev=0e5b2d73aa18dd9f0a50ee9ff199d5aef7594186#0e5b2d73aa18dd9f0a50ee9ff199d5aef7594186" +dependencies = [ + "futures-util", + "log", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "libc", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.15+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1340ea94a5856333492c9064b02c778b191dd2c853778d9609debdcdfea3a614" +dependencies = [ + "indexmap 2.14.2", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" +dependencies = [ + "winnow", +] + +[[package]] +name = "tonic" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bytes", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "rustls-native-certs", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-prost" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" +dependencies = [ + "bytes", + "prost", + "tonic", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 2.14.2", + "pin-project-lite", + "slab", + "sync_wrapper", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags 2.13.2", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracelogging" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4314470f3f54b29d582ff6776fceb7c819b023141828d559f19c790cee40e94" +dependencies = [ + "tracelogging_macros", +] + +[[package]] +name = "tracelogging_macros" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e2d891464ff33bc1814c4cbbb251bae7800458b1efdb6ac8b7c01ee6382563" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c" +dependencies = [ + "crossbeam-channel", + "symlink", + "thiserror 2.0.20", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc" +dependencies = [ + "js-sys", + "opentelemetry", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "triomphe" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b40688ea6389c8171614b25491f71d4a27946e0c7ce2da1c6de27e25abf1a0ae" +dependencies = [ + "serde", + "stable_deref_trait", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "ts-rs" +version = "11.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4994acea2522cd2b3b85c1d9529a55991e3ad5e25cdcd3de9d505972c4379424" +dependencies = [ + "serde_json", + "thiserror 2.0.20", + "ts-rs-macros", + "uuid", +] + +[[package]] +name = "ts-rs-macros" +version = "11.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6ff59666c9cbaec3533964505d39154dc4e0a56151fdea30a09ed0301f62e2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "termcolor", +] + +[[package]] +name = "tungstenite" +version = "0.27.0" +source = "git+https://github.com/openai-oss-forks/tungstenite-rs?rev=4fffad30fe373adbdcffab9545e9e9bf4f2fc19f#4fffad30fe373adbdcffab9545e9e9bf4f2fc19f" +dependencies = [ + "bytes", + "data-encoding", + "flate2", + "headers", + "http", + "httparse", + "log", + "rand 0.9.5", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror 2.0.20", + "utf-8", +] + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-general-category" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f" + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce" +dependencies = [ + "getrandom 0.4.3", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ef4c5d3d2cdf5c54f4231181768f5510842e350db025faf1f7163b1030ed928" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 3.0.6", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbddc4a036f00ec4f18c83445bd3115cb306a91da554919a099d9222fe4a7f8" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "weezl" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" + +[[package]] +name = "which" +version = "8.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae2f2b2b816647a1cab1acc91f5bd20812d53cb344382635ec2181940c8034f" +dependencies = [ + "libc", +] + +[[package]] +name = "widestring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" + +[[package]] +name = "wildcard" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9b0540e91e49de3817c314da0dd3bc518093ceacc6ea5327cb0e1eb073e5189" +dependencies = [ + "thiserror 2.0.20", +] + +[[package]] +name = "wildmatch" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29333c3ea1ba8b17211763463ff24ee84e41c78224c16b001cd907e663a38c68" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core 0.62.2", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core 0.62.2", + "windows-link", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core 0.62.2", + "windows-link", +] + +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "winreg" +version = "0.55.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" +dependencies = [ + "cfg-if", + "windows-sys 0.59.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "writeable" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" + +[[package]] +name = "wxc_common" +version = "0.8.0" +source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4" +dependencies = [ + "base64 0.22.1", + "cidr", + "getrandom 0.2.17", + "libc", + "mxc_config_contract", + "mxc_telemetry", + "semver", + "serde", + "serde_json", + "serde_path_to_error", + "thiserror 2.0.20", + "unicode-general-category", + "url", + "widestring", + "windows 0.62.2", + "windows-core 0.62.2", + "winreg 0.55.0", +] + +[[package]] +name = "x509-parser" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" +dependencies = [ + "asn1-rs", + "aws-lc-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom 7.1.3", + "oid-registry", + "ring", + "rusticata-macros", + "thiserror 2.0.20", + "time", +] + +[[package]] +name = "yasna" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5f6765e852b9b4dc8e2a76843e4d64d1cea8e79bcde0b6901aea8e7c7f08282" +dependencies = [ + "bit-vec 0.9.1", + "time", +] + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", + "synstructure 0.14.0", +] + +[[package]] +name = "zerocopy" +version = "0.8.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", + "synstructure 0.14.0", +] + +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + +[[package]] +name = "zerotrie" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "zerovec" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" +dependencies = [ + "serde", + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + +[[package]] +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d80649ab6db9d9f6f9c80a40becd948eda4714a0a5ac8c4d157a32231c7882" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.1.0+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef0a8027ec3ee71300ab3bcbcd0393f434aa72b91ca6d635a39941deae8eea0" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "zune-core" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56377fd46368984a170bc5aac5567e52ca5da874caa60bea39fcbca78fb658b" + +[[package]] +name = "zune-jpeg" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" +dependencies = [ + "zune-core", +] diff --git a/crates/linux-sandbox/Cargo.toml b/crates/linux-sandbox/Cargo.toml new file mode 100644 index 0000000..52f3a91 --- /dev/null +++ b/crates/linux-sandbox/Cargo.toml @@ -0,0 +1,44 @@ +# Isolated workspace (excluded from the repo root workspace) so the pinned +# Codex crates keep their own workspace.dependencies. + +[package] +name = "codespace-linux-sandbox" +version = "0.6.0" +edition = "2021" +license = "Apache-2.0" +rust-version = "1.88" +publish = false +description = "Isolated Codex Linux sandbox adapter: helper argv without leaking Codex types" + +[workspace] +members = ["."] +resolver = "2" + +[dependencies] +codex-linux-sandbox = { path = "../../third_party/codex/codex-rs/linux-sandbox" } +codex-protocol = { path = "../../third_party/codex/codex-rs/protocol" } +codex-sandboxing = { path = "../../third_party/codex/codex-rs/sandboxing" } +codex-utils-path-uri = { path = "../../third_party/codex/codex-rs/utils/path-uri" } +# Resolver guards. Codex pin 6b9826e is validated against the Rama +# 0.3.0-alpha.4 train. Leaf crates use ^0.3.0-alpha.4, so a fresh +# resolve can pick stable 0.3.0 and break OpaqueError. These keys are +# not used in CodeSpace code; they pin the release train for both this +# workspace and the root workspace (path dep). +rama-error = "=0.3.0-alpha.4" +rama-macros = "=0.3.0-alpha.4" +rama-utils = "=0.3.0-alpha.4" + +[dev-dependencies] +serde_json = "1" +tempfile = "3" + +[[bin]] +name = "codespace-linux-sandbox" +path = "src/bin/codespace-linux-sandbox.rs" + +[patch.crates-io] +tokio-tungstenite = { git = "https://github.com/openai-oss-forks/tokio-tungstenite", rev = "0e5b2d73aa18dd9f0a50ee9ff199d5aef7594186" } +tungstenite = { git = "https://github.com/openai-oss-forks/tungstenite-rs", rev = "4fffad30fe373adbdcffab9545e9e9bf4f2fc19f" } + +[patch."ssh://git@github.com/openai-oss-forks/tungstenite-rs.git"] +tungstenite = { git = "https://github.com/openai-oss-forks/tungstenite-rs", rev = "4fffad30fe373adbdcffab9545e9e9bf4f2fc19f" } diff --git a/crates/linux-sandbox/src/bin/codespace-linux-sandbox.rs b/crates/linux-sandbox/src/bin/codespace-linux-sandbox.rs new file mode 100644 index 0000000..30cda5d --- /dev/null +++ b/crates/linux-sandbox/src/bin/codespace-linux-sandbox.rs @@ -0,0 +1,16 @@ +//! Isolated Codex Linux sandbox helper. The runner wraps user argv with +//! this process. It is not an MCP tool. `run_main` is Linux-only; other +//! targets compile the binary but must not invoke the upstream entry +//! (it panics). + +fn main() { + #[cfg(target_os = "linux")] + { + codex_linux_sandbox::run_main(); + } + #[cfg(not(target_os = "linux"))] + { + eprintln!("codespace-linux-sandbox is only supported on Linux"); + std::process::exit(1); + } +} diff --git a/crates/linux-sandbox/src/lib.rs b/crates/linux-sandbox/src/lib.rs new file mode 100644 index 0000000..e90b814 --- /dev/null +++ b/crates/linux-sandbox/src/lib.rs @@ -0,0 +1,507 @@ +//! Isolated Linux command-sandbox adapter. Wraps `codex-linux-sandbox` +//! and exposes only CodeSpace-owned types. Codex `PermissionProfile` +//! stays inside this crate. Not an MCP tool. + +use std::collections::BTreeMap; +use std::ffi::OsString; +use std::path::{Path, PathBuf}; +use std::process::{Command, Stdio}; +use std::sync::OnceLock; +use std::time::{Duration, Instant}; + +use codex_protocol::models::PermissionProfile; +use codex_protocol::protocol::{ + FileSystemAccessMode, FileSystemPath, FileSystemSandboxEntry, FileSystemSandboxPolicy, + FileSystemSpecialPath, NetworkSandboxPolicy, +}; +use codex_sandboxing::landlock::create_linux_sandbox_command_args_for_permission_profile; +use codex_utils_path_uri::PathUri; + +/// Env override for the helper, matching `CODESPACE_PATCH_BIN` / +/// `CODESPACE_RUNTIME_BIN`. +pub const HELPER_BIN_ENV: &str = "CODESPACE_LINUX_SANDBOX_BIN"; +pub const HELPER_BIN_NAME: &str = "codespace-linux-sandbox"; +/// Linux CI sets this to `1` so a failed helper probe is a test failure, +/// not a skip. +pub const REQUIRE_ENV: &str = "CODESPACE_REQUIRE_LINUX_SANDBOX"; + +/// PATH inside the sandbox. Host `HOME` / `~/.cargo/bin` are not mounted +/// for toolchain discovery. +pub const SANDBOX_PATH: &str = "/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"; + +const PROBE_TIMEOUT: Duration = Duration::from_secs(5); +const PROTECTED_METADATA_NAMES: &[&str] = &[".git", ".agents", ".codex"]; + +/// Filesystem / network inputs the runner already decided. Codex named +/// `workspace-write` is not reused: that profile remounts `.git` read-only. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct SandboxExecSpec { + pub workspace_root: PathBuf, + pub writable_workspace: bool, + pub network: SandboxNetwork, +} + +/// This work package only hard-denies network. `Enabled` / proxy is later. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum SandboxNetwork { + Restricted, +} + +/// Helper program + argv. Pipe and PTY spawn this, not the user argv. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct SandboxLaunch { + pub program: PathBuf, + pub args: Vec, +} + +/// Locate the helper: `CODESPACE_LINUX_SANDBOX_BIN`, else a binary named +/// [`HELPER_BIN_NAME`] next to the current executable. +pub fn helper_path() -> Option { + if let Some(path) = std::env::var_os(HELPER_BIN_ENV) { + let path = PathBuf::from(path); + if path.is_file() { + return Some(path); + } + return None; + } + let exe = std::env::current_exe().ok()?; + let candidate = exe.parent()?.join(HELPER_BIN_NAME); + candidate.is_file().then_some(candidate) +} + +/// True when tests must not skip a failed Linux helper probe. +pub fn require_linux_sandbox() -> bool { + std::env::var_os(REQUIRE_ENV).is_some_and(|value| value == "1") +} + +/// Cached Linux helper + bwrap/userns/pid/seccomp probe. Non-Linux is +/// always `false`. A failed probe does not wrap later spawns. A successful +/// probe never falls back to unsandboxed user argv. +pub fn probe() -> bool { + static OK: OnceLock = OnceLock::new(); + *OK.get_or_init(|| { + if !cfg!(target_os = "linux") { + return false; + } + let Some(helper) = helper_path() else { + return false; + }; + probe_helper(&helper) + }) +} + +/// Run `/usr/bin/true` (or `/bin/true`) once through the helper. Used by +/// [`probe`] and by Linux isolation tests that pass an explicit helper. +pub fn probe_helper(helper: &Path) -> bool { + if !cfg!(target_os = "linux") { + return false; + } + if !helper.is_file() { + return false; + } + let workspace = probe_workspace(); + let spec = SandboxExecSpec { + workspace_root: workspace.clone(), + writable_workspace: true, + network: SandboxNetwork::Restricted, + }; + let launch = match prepare_from_helper(helper, &spec, &[true_command()], &workspace) { + Ok(launch) => launch, + Err(err) => { + if require_linux_sandbox() { + eprintln!("linux sandbox probe prepare failed: {err}"); + } + return false; + } + }; + let mut child = Command::new(&launch.program); + child + .args(&launch.args) + .current_dir(&workspace) + .env_clear() + .envs(sandbox_exec_env(&workspace)) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(if require_linux_sandbox() { + Stdio::inherit() + } else { + Stdio::null() + }); + let child = match child.spawn() { + Ok(child) => child, + Err(err) => { + if require_linux_sandbox() { + eprintln!("linux sandbox probe spawn failed: {err}"); + } + return false; + } + }; + match wait_with_timeout(child, PROBE_TIMEOUT) { + Some(status) if status.success() => true, + Some(status) => { + if require_linux_sandbox() { + eprintln!("linux sandbox probe exited with {status}"); + } + false + } + None => { + if require_linux_sandbox() { + eprintln!("linux sandbox probe timed out after {PROBE_TIMEOUT:?}"); + } + false + } + } +} + +/// Build helper argv for `command` at `command_cwd`. Uses [`helper_path`]. +/// Does not spawn. Missing helper is an error (caller must not unsandbox). +pub fn prepare( + spec: &SandboxExecSpec, + command: &[String], + command_cwd: &Path, +) -> Result { + let helper = helper_path().ok_or_else(|| { + format!( + "{HELPER_BIN_ENV} is unset and {HELPER_BIN_NAME} was not found next to the executable" + ) + })?; + prepare_from_helper(&helper, spec, command, command_cwd) +} + +/// Same as [`prepare`] with an explicit helper path (tests and probe). +pub fn prepare_from_helper( + helper: &Path, + spec: &SandboxExecSpec, + command: &[String], + command_cwd: &Path, +) -> Result { + if command.is_empty() || command[0].is_empty() { + return Err("command must be a non-empty argv (no shell)".into()); + } + let profile = permission_profile(spec, helper)?; + let cwd = absolute_dir(command_cwd)?; + let policy_cwd = absolute_dir(&spec.workspace_root)?; + let args = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + create_linux_sandbox_command_args_for_permission_profile( + command.to_vec(), + &cwd, + &profile, + &policy_cwd, + /*use_legacy_landlock*/ false, + /*allow_network_for_proxy*/ false, + ) + })) + .map_err(|_| "failed to build linux sandbox argv".to_string())?; + if args.iter().any(|arg| { + arg == "--allow-network-for-proxy" + || arg == "--proxy-route-spec" + || arg == "--not-a-security-boundary" + || arg == "--use-legacy-landlock" + }) { + return Err("linux sandbox argv included a forbidden helper flag".into()); + } + Ok(SandboxLaunch { + program: helper.to_path_buf(), + args: args.into_iter().map(OsString::from).collect(), + }) +} + +/// Env applied after `env_clear` for a sandboxed spawn. `HOME` stays the +/// workspace root (same as unsandboxed runner defaults). +pub fn sandbox_exec_env(home: &Path) -> BTreeMap { + let mut env = BTreeMap::new(); + env.insert("PATH".into(), SANDBOX_PATH.into()); + env.insert("HOME".into(), home.display().to_string()); + env.insert("LANG".into(), "C".into()); + env.insert("TMPDIR".into(), "/tmp".into()); + env +} + +fn permission_profile(spec: &SandboxExecSpec, helper: &Path) -> Result { + let mut entries = vec![FileSystemSandboxEntry::new( + FileSystemPath::Special { + value: FileSystemSpecialPath::Minimal, + }, + FileSystemAccessMode::Read, + )]; + // The Codex Linux helper re-execs its own current executable inside + // bubblewrap before applying seccomp. `Minimal` does not expose arbitrary + // host paths, so make only this infrastructure binary readable there. + entries.push(FileSystemSandboxEntry::new( + path_uri(helper)?.into(), + FileSystemAccessMode::Read, + )); + let workspace = path_uri(&spec.workspace_root)?; + let access = if spec.writable_workspace { + FileSystemAccessMode::Write + } else { + FileSystemAccessMode::Read + }; + entries.push(FileSystemSandboxEntry::new( + workspace.clone().into(), + access, + )); + if spec.writable_workspace { + // Codex auto-protects `.git` / `.agents` / `.codex` on writable + // roots. CodeSpace `WorkspaceWrite` is `**` Write, so override. + for name in PROTECTED_METADATA_NAMES { + if let Ok(path) = workspace.join(name) { + entries.push(FileSystemSandboxEntry::new( + path.into(), + FileSystemAccessMode::Write, + )); + } + } + } + // Private `/tmp` comes from bubblewrap `--tmpfs /` under Minimal. + // Do not bind host `/tmp` (`SlashTmp`) or host `TMPDIR`. + let file_system = FileSystemSandboxPolicy::restricted(entries); + let network = match spec.network { + SandboxNetwork::Restricted => NetworkSandboxPolicy::Restricted, + }; + Ok(PermissionProfile::from_runtime_permissions( + &file_system, + network, + )) +} + +fn path_uri(path: &Path) -> Result { + let path = absolute_dir(path)?; + PathUri::from_host_native_path(&path).map_err(|err| err.to_string()) +} + +fn absolute_dir(path: &Path) -> Result { + let path = path.canonicalize().unwrap_or_else(|_| path.to_path_buf()); + if !path.is_absolute() { + return Err(format!("sandbox path must be absolute: {}", path.display())); + } + if path.to_str().is_none() { + return Err(format!( + "sandbox path must be valid UTF-8: {}", + path.display() + )); + } + Ok(path) +} + +fn true_command() -> String { + for candidate in ["/usr/bin/true", "/bin/true"] { + if Path::new(candidate).is_file() { + return candidate.to_string(); + } + } + "true".to_string() +} + +fn probe_workspace() -> PathBuf { + let dir = std::env::temp_dir().join("codespace-linux-sandbox-probe"); + let _ = std::fs::create_dir_all(&dir); + dir +} + +fn wait_with_timeout( + mut child: std::process::Child, + timeout: Duration, +) -> Option { + let start = Instant::now(); + loop { + match child.try_wait() { + Ok(Some(status)) => return Some(status), + Ok(None) => { + if start.elapsed() > timeout { + let _ = child.kill(); + let _ = child.wait(); + return None; + } + std::thread::sleep(Duration::from_millis(20)); + } + Err(_) => { + let _ = child.kill(); + return None; + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use serde_json::Value; + + fn dummy_helper() -> PathBuf { + PathBuf::from("/usr/bin/codespace-linux-sandbox") + } + + fn spec(root: &Path, writable: bool) -> SandboxExecSpec { + SandboxExecSpec { + workspace_root: root.to_path_buf(), + writable_workspace: writable, + network: SandboxNetwork::Restricted, + } + } + + fn launch_args(root: &Path, writable: bool) -> Vec { + let launch = prepare_from_helper( + &dummy_helper(), + &spec(root, writable), + &["/bin/echo".into(), "hi".into()], + root, + ) + .expect("prepare"); + assert_eq!(launch.program, dummy_helper()); + launch + .args + .iter() + .map(|arg| arg.to_string_lossy().into_owned()) + .collect() + } + + fn profile_json(args: &[String]) -> Value { + let idx = args + .iter() + .position(|arg| arg == "--permission-profile") + .expect("permission-profile flag"); + serde_json::from_str(&args[idx + 1]).expect("profile json") + } + + fn special_kinds(profile: &Value) -> Vec { + profile["file_system"]["entries"] + .as_array() + .expect("entries") + .iter() + .filter_map(|entry| { + let path = &entry["path"]; + (path["type"] == "special").then(|| { + path["value"]["kind"] + .as_str() + .unwrap_or_default() + .to_string() + }) + }) + .collect() + } + + #[test] + fn crate_is_isolated_adapter() { + assert_eq!(env!("CARGO_PKG_NAME"), "codespace-linux-sandbox"); + } + + #[test] + fn require_env_defaults_off() { + assert!(!require_linux_sandbox()); + } + + #[test] + fn probe_is_false_off_linux() { + if !cfg!(target_os = "linux") { + assert!(!probe()); + assert!(!probe_helper(Path::new("/usr/bin/true"))); + } + } + + #[test] + fn prepare_uses_minimal_workspace_and_restricted_network() { + let dir = tempfile::tempdir().unwrap(); + let args = launch_args(dir.path(), true); + assert!(!args.iter().any(|arg| arg == "--allow-network-for-proxy" + || arg == "--proxy-route-spec" + || arg == "--not-a-security-boundary" + || arg == "--use-legacy-landlock")); + assert!(args.contains(&"--sandbox-policy-cwd".to_string())); + assert!(args.contains(&"--command-cwd".to_string())); + assert_eq!(args[args.len() - 3], "--"); + assert_eq!(args[args.len() - 2], "/bin/echo"); + assert_eq!(args[args.len() - 1], "hi"); + + let profile = profile_json(&args); + assert_eq!(profile["type"], "managed"); + assert_eq!(profile["network"], "restricted"); + let kinds = special_kinds(&profile); + assert!(kinds.contains(&"minimal".to_string()), "{kinds:?}"); + assert!( + !kinds + .iter() + .any(|kind| kind == "slash_tmp" || kind == "tmpdir"), + "host /tmp must not be bound: {kinds:?}" + ); + assert!( + !kinds.iter().any(|kind| kind == "project_roots"), + "must not use Codex project_roots workspace-write: {kinds:?}" + ); + let dumped = profile.to_string(); + assert!( + !dumped.contains("\"subpath\":\".git\""), + "must not add Codex .git RO carveout: {dumped}" + ); + } + + #[test] + fn permission_profile_reads_helper_for_inner_reexec() { + let dir = tempfile::tempdir().unwrap(); + let profile = permission_profile(&spec(dir.path(), true), &dummy_helper()).unwrap(); + let (file_system, _) = profile.to_runtime_permissions(); + let expected = FileSystemPath::Path { + path: path_uri(&dummy_helper()).unwrap(), + }; + assert!( + file_system.entries.iter().any(|entry| { + entry.access == FileSystemAccessMode::Read && entry.path == expected + }), + "helper must stay readable for the inner sandbox re-exec: {:?}", + file_system.entries + ); + } + + #[test] + fn read_only_workspace_is_not_write() { + let dir = tempfile::tempdir().unwrap(); + let profile = profile_json(&launch_args(dir.path(), false)); + let writes = profile["file_system"]["entries"] + .as_array() + .unwrap() + .iter() + .filter(|entry| entry["access"] == "write") + .count(); + assert_eq!(writes, 0, "{profile}"); + } + + #[test] + fn writable_workspace_overrides_codex_metadata_ro() { + let dir = tempfile::tempdir().unwrap(); + let profile = profile_json(&launch_args(dir.path(), true)); + let writes = profile["file_system"]["entries"] + .as_array() + .unwrap() + .iter() + .filter(|entry| entry["access"] == "write") + .count(); + assert!( + writes >= 4, + "workspace + .git/.agents/.codex writes: {profile}" + ); + let dumped = profile.to_string(); + for name in PROTECTED_METADATA_NAMES { + assert!( + dumped.contains(name), + "missing {name} write override: {dumped}" + ); + } + } + + #[test] + fn prepare_rejects_empty_command() { + let dir = tempfile::tempdir().unwrap(); + let err = prepare_from_helper(&dummy_helper(), &spec(dir.path(), true), &[], dir.path()) + .unwrap_err(); + assert!(err.contains("non-empty argv"), "{err}"); + } + + #[test] + fn sandbox_env_uses_fixed_path_and_workspace_home() { + let env = sandbox_exec_env(Path::new("/workspace")); + assert_eq!(env.get("PATH").unwrap(), SANDBOX_PATH); + assert_eq!(env.get("HOME").unwrap(), "/workspace"); + assert_eq!(env.get("TMPDIR").unwrap(), "/tmp"); + assert!(!env.get("PATH").unwrap().contains(".cargo/bin")); + } +} diff --git a/crates/linux-sandbox/tests/isolation.rs b/crates/linux-sandbox/tests/isolation.rs new file mode 100644 index 0000000..82886c8 --- /dev/null +++ b/crates/linux-sandbox/tests/isolation.rs @@ -0,0 +1,340 @@ +//! Linux isolation checks against the helper binary. Non-Linux compiles +//! this file but skips the runtime assertions. + +use std::path::{Path, PathBuf}; +use std::process::{Command, Stdio}; +use std::time::{Duration, Instant}; + +use codespace_linux_sandbox::{ + prepare_from_helper, probe_helper, require_linux_sandbox, sandbox_exec_env, SandboxExecSpec, + SandboxLaunch, SandboxNetwork, REQUIRE_ENV, +}; + +fn helper_bin() -> PathBuf { + PathBuf::from(env!("CARGO_BIN_EXE_codespace-linux-sandbox")) +} + +fn spec(root: &Path) -> SandboxExecSpec { + SandboxExecSpec { + workspace_root: root.to_path_buf(), + writable_workspace: true, + network: SandboxNetwork::Restricted, + } +} + +fn launch(root: &Path, command: &[String]) -> SandboxLaunch { + prepare_from_helper(&helper_bin(), &spec(root), command, root).expect("prepare") +} + +fn run_ok(root: &Path, command: &[String]) -> String { + let launch = launch(root, command); + let output = Command::new(&launch.program) + .args(&launch.args) + .current_dir(root) + .env_clear() + .envs(sandbox_exec_env(root)) + .stdin(Stdio::null()) + .output() + .expect("spawn helper"); + assert!( + output.status.success(), + "status={} stderr={} stdout={}", + output.status, + String::from_utf8_lossy(&output.stderr), + String::from_utf8_lossy(&output.stdout) + ); + String::from_utf8_lossy(&output.stdout).into_owned() +} + +fn run_status(root: &Path, command: &[String]) -> std::process::ExitStatus { + let launch = launch(root, command); + Command::new(&launch.program) + .args(&launch.args) + .current_dir(root) + .env_clear() + .envs(sandbox_exec_env(root)) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status() + .expect("spawn helper") +} + +fn linux_ready() -> bool { + let ready = cfg!(target_os = "linux") && probe_helper(&helper_bin()); + if require_linux_sandbox() { + #[cfg(not(target_os = "linux"))] + panic!("{REQUIRE_ENV}=1 is Linux CI only"); + + #[cfg(target_os = "linux")] + assert!( + ready, + "{REQUIRE_ENV}=1 but linux sandbox helper probe failed" + ); + } + ready +} + +fn python3() -> Option<&'static Path> { + ["/usr/bin/python3", "/bin/python3"] + .into_iter() + .map(Path::new) + .find(|path| path.is_file()) +} + +/// Spawn the helper on a PTY (same argv as pipe). Used for isatty + stdin. +fn run_pty(root: &Path, command: &[String], stdin: Option<&str>) -> String { + let python = python3().expect("python3 for PTY checks"); + let launch = launch(root, command); + let env_json = serde_json::to_string(&sandbox_exec_env(root)).expect("env json"); + let script = r#" +import json, os, pty, select, sys, time +env = json.loads(os.environ["CODESPACE_SANDBOX_ENV"]) +stdin_data = os.environ.get("CODESPACE_PTY_STDIN") or "" +helper = sys.argv[1] +args = sys.argv[2:] +pid, fd = pty.fork() +if pid == 0: + os.environ.clear() + os.environ.update(env) + os.execv(helper, [helper] + args) +if stdin_data: + time.sleep(0.05) + os.write(fd, stdin_data.encode()) +data = b"" +deadline = time.time() + 8 +reaped = False +while time.time() < deadline: + ready, _, _ = select.select([fd], [], [], 0.2) + if fd in ready: + try: + chunk = os.read(fd, 4096) + except OSError: + break + if not chunk: + break + data += chunk + wpid, _ = os.waitpid(pid, os.WNOHANG) + if wpid != 0: + reaped = True + while True: + ready, _, _ = select.select([fd], [], [], 0.05) + if fd not in ready: + break + try: + chunk = os.read(fd, 4096) + except OSError: + break + if not chunk: + break + data += chunk + break +if not reaped: + os.kill(pid, 9) + os.waitpid(pid, 0) +sys.stdout.buffer.write(data) +"#; + let output = Command::new(python) + .arg("-c") + .arg(script) + .arg(&launch.program) + .args(&launch.args) + .current_dir(root) + .env("CODESPACE_SANDBOX_ENV", env_json) + .env("CODESPACE_PTY_STDIN", stdin.unwrap_or("")) + .output() + .expect("spawn python pty wrapper"); + assert!( + output.status.success(), + "pty wrapper status={} stderr={} stdout={}", + output.status, + String::from_utf8_lossy(&output.stderr), + String::from_utf8_lossy(&output.stdout) + ); + String::from_utf8_lossy(&output.stdout).into_owned() +} + +#[test] +fn helper_probe_matches_platform() { + if require_linux_sandbox() { + assert!(linux_ready()); + return; + } + if cfg!(target_os = "linux") { + if !probe_helper(&helper_bin()) { + eprintln!("skip: bubblewrap/userns/seccomp probe failed"); + } + } else { + assert!(!probe_helper(&helper_bin())); + } +} + +#[test] +fn workspace_write_and_outside_path_hidden() { + if !linux_ready() { + return; + } + let dir = tempfile::tempdir().unwrap(); + let ws = dir.path().join("ws"); + std::fs::create_dir(&ws).unwrap(); + let ssh_dir = dir.path().join("home").join(".ssh"); + std::fs::create_dir_all(&ssh_dir).unwrap(); + let secret = ssh_dir.join("id_ed25519"); + std::fs::write(&secret, "leak").unwrap(); + + run_ok( + &ws, + &[ + "/bin/sh".into(), + "-c".into(), + "echo inside > visible.txt && cat visible.txt".into(), + ], + ); + assert_eq!( + std::fs::read_to_string(ws.join("visible.txt")) + .unwrap() + .trim(), + "inside" + ); + + let status = run_status( + &ws, + &[ + "/bin/sh".into(), + "-c".into(), + format!("cat '{}'", secret.display()), + ], + ); + assert!( + !status.success(), + "host path outside workspace (~/.ssh) must not be readable" + ); +} + +#[test] +fn private_tmp_is_writable_and_does_not_bind_host_tmp() { + if !linux_ready() { + return; + } + let dir = tempfile::tempdir().unwrap(); + let host_marker = std::env::temp_dir().join("codespace-linux-sandbox-host-tmp-marker"); + std::fs::write(&host_marker, "host").unwrap(); + + let stdout = run_ok( + dir.path(), + &[ + "/bin/sh".into(), + "-c".into(), + "mkdir -p /tmp && echo sandboxed > /tmp/codespace-tmp && cat /tmp/codespace-tmp".into(), + ], + ); + assert!(stdout.contains("sandboxed"), "{stdout}"); + assert_eq!( + std::fs::read_to_string(&host_marker).unwrap().trim(), + "host" + ); + let _ = std::fs::remove_file(&host_marker); +} + +#[test] +fn inet_socket_denied_unix_socket_allowed() { + if !linux_ready() { + return; + } + let Some(python) = python3() else { + eprintln!("skip: python3 not present for socket checks"); + return; + }; + let dir = tempfile::tempdir().unwrap(); + let inet = run_status( + dir.path(), + &[ + python.display().to_string(), + "-c".into(), + "import socket; socket.socket(socket.AF_INET, socket.SOCK_STREAM)".into(), + ], + ); + assert!(!inet.success(), "AF_INET must be denied"); + + let unix = run_status( + dir.path(), + &[ + python.display().to_string(), + "-c".into(), + "import socket; socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)".into(), + ], + ); + assert!(unix.success(), "AF_UNIX must be allowed"); +} + +#[test] +fn terminate_kills_sandbox_tree() { + if !linux_ready() { + return; + } + let dir = tempfile::tempdir().unwrap(); + let launch = launch(dir.path(), &["/bin/sleep".into(), "30".into()]); + let mut child = Command::new(&launch.program) + .args(&launch.args) + .current_dir(dir.path()) + .env_clear() + .envs(sandbox_exec_env(dir.path())) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + .expect("spawn sleep"); + std::thread::sleep(Duration::from_millis(100)); + child.kill().expect("kill helper"); + let start = Instant::now(); + loop { + if child.try_wait().ok().flatten().is_some() { + break; + } + assert!( + start.elapsed() < Duration::from_secs(5), + "sandbox tree did not die with the helper" + ); + std::thread::sleep(Duration::from_millis(20)); + } +} + +#[test] +fn pty_isatty_and_stdin_roundtrip() { + if !linux_ready() { + return; + } + if python3().is_none() { + eprintln!("skip: python3 not present for PTY checks"); + return; + } + let dir = tempfile::tempdir().unwrap(); + let isatty = run_pty( + dir.path(), + &[ + "/bin/sh".into(), + "-c".into(), + "if [ -t 0 ]; then echo ISATTY; else echo NOTTY; fi".into(), + ], + None, + ); + assert!( + isatty.contains("ISATTY"), + "helper argv on a PTY must see a TTY, got {isatty:?}" + ); + assert!(!isatty.contains("NOTTY"), "chunk={isatty:?}"); + + let echo = run_pty( + dir.path(), + &[ + "/bin/sh".into(), + "-c".into(), + "IFS= read -r line; printf 'got:%s\\n' \"$line\"".into(), + ], + Some("hello\n"), + ); + assert!( + echo.contains("hello"), + "PTY stdin roundtrip through helper, got {echo:?}" + ); +} diff --git a/crates/runner/Cargo.toml b/crates/runner/Cargo.toml index 67e9d7f..2b044c6 100644 --- a/crates/runner/Cargo.toml +++ b/crates/runner/Cargo.toml @@ -12,6 +12,7 @@ codespace-domain = { path = "../domain" } codespace-policy = { path = "../policy" } codespace-pty = { path = "../pty" } codespace-fs = { path = "../file-system" } +codespace-linux-sandbox = { path = "../linux-sandbox" } serde = { workspace = true } serde_json = { workspace = true } sha2 = "0.10" diff --git a/crates/runner/src/lib.rs b/crates/runner/src/lib.rs index 2c58d3b..6e13e50 100644 --- a/crates/runner/src/lib.rs +++ b/crates/runner/src/lib.rs @@ -1,10 +1,12 @@ //! `Runner` trait, host `InProcessRunner`, and opt-in Unix-socket //! `UdsRunner`. Path sandbox, one patch transaction, host process //! supervisor, and isolation-fixture checks. Linux containers are the -//! **target** execution OS. macOS hosts may run the path sandbox for unit -//! tests; that does **not** verify Linux isolation. `exec_command` is not -//! dispatched into compose. Default backend remains in-process. Host + -//! `UdsRunner` is the same host over UDS, not a Linux isolation claim. +//! **target** execution OS. When the Linux helper probe succeeds, command +//! spawn is wrapped by `codespace-linux-sandbox`. macOS hosts may run the +//! path sandbox for unit tests; that does **not** verify Linux isolation. +//! `exec_command` is not dispatched into compose. Default backend remains +//! in-process. Host + `UdsRunner` is the same host over UDS, not a Linux +//! isolation claim. use std::fs; use std::os::unix::fs::FileTypeExt; @@ -119,6 +121,13 @@ pub use process::{ InProcessRunner, RetentionPolicy, ShellRelease, DEFAULT_COMPLETED_TTL, DEFAULT_MAX_COMPLETED, DEFAULT_MAX_PROCESSES, DEFAULT_TIMEOUT, }; + +/// True when this process probed a working Linux sandbox helper. +/// Advertisement and spawn must agree on this value. +pub fn linux_sandbox_available() -> bool { + codespace_linux_sandbox::probe() +} + pub use socket::{ allocate_private_runner_dir, is_forbidden_runner_dir, reclaim_leftover_socket, runner_socket_path, RUNNER_SOCKET_NAME, diff --git a/crates/runner/src/process.rs b/crates/runner/src/process.rs index eabe4be..e075930 100644 --- a/crates/runner/src/process.rs +++ b/crates/runner/src/process.rs @@ -1,15 +1,18 @@ //! Managed workspace processes. Request lifetime is not process lifetime. -//! Pipe spawn uses host `tokio::process::Command`. `tty: true` uses the -//! isolated `codespace-pty` adapter. UDS dispatch lives in `UdsRunner`. +//! Pipe spawn uses `tokio::process::Command`. `tty: true` uses the isolated +//! `codespace-pty` adapter. When the Linux helper probe succeeds, both wrap +//! the same helper argv. UDS dispatch lives in `UdsRunner`. use std::collections::HashMap; -use std::path::PathBuf; +use std::ffi::OsString; +use std::path::{Path, PathBuf}; use std::process::Stdio; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; -use codespace_domain::{ErrorBody, ErrorCode, ProcessId}; -use codespace_policy::Workspace; +use codespace_domain::{ErrorBody, ErrorCode, ProcessId, Profile}; +use codespace_linux_sandbox::{sandbox_exec_env, SandboxExecSpec, SandboxNetwork}; +use codespace_policy::{NetworkAxis, Workspace}; use codespace_pty::PtySession; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::process::{Child, ChildStdin, Command}; @@ -180,10 +183,9 @@ impl InProcessRunner { completed_at, process_id, } = ctx; - let mut child = Command::new(&req.argv[0]); - if req.argv.len() > 1 { - child.args(&req.argv[1..]); - } + let (program, args, sandboxed) = exec_launch(ws, &req)?; + let mut child = Command::new(&program); + child.args(&args); child .current_dir(&cwd) .env_clear() @@ -191,12 +193,7 @@ impl InProcessRunner { .stdout(Stdio::piped()) .stderr(Stdio::piped()) .kill_on_drop(true); - if req.env.use_runner_defaults { - for (key, value) in runner_local_exec_env(&cwd) { - child.env(key, value); - } - } - for (key, value) in &req.env.overrides { + for (key, value) in spawn_env(&cwd, &req, sandboxed) { child.env(key, value); } let mut spawned = child.spawn().map_err(|err| { @@ -289,22 +286,13 @@ impl InProcessRunner { completed_at, process_id, } = ctx; - let mut env = HashMap::new(); + let (program, args, sandboxed) = exec_launch(ws, &req)?; + let mut env = spawn_env(&cwd, &req, sandboxed); if req.env.use_runner_defaults { - for (key, value) in runner_local_exec_env(&cwd) { - env.insert(key, value); - } env.insert("TERM".into(), "xterm".into()); } - for (key, value) in &req.env.overrides { - env.insert(key.clone(), value.clone()); - } - let args = if req.argv.len() > 1 { - req.argv[1..].to_vec() - } else { - Vec::new() - }; - let mut session = codespace_pty::spawn(&req.argv[0], &args, &cwd, &env) + let (program, args) = utf8_launch(&program, &args)?; + let mut session = codespace_pty::spawn(&program, &args, &cwd, &env) .await .map_err(|err| { ErrorBody::new( @@ -569,6 +557,81 @@ fn missing(id: &str) -> ErrorBody { ) } +/// Wrap user argv with the Linux helper when [`probe`](codespace_linux_sandbox::probe) +/// succeeded. Probe failure keeps direct user argv. Probe success never +/// unsandboxes on a later setup/spawn error. +fn exec_launch( + ws: &Workspace, + req: &RunnerExecRequest, +) -> Result<(PathBuf, Vec, bool), ErrorBody> { + if !codespace_linux_sandbox::probe() { + return Ok(( + PathBuf::from(&req.argv[0]), + req.argv.iter().skip(1).map(OsString::from).collect(), + false, + )); + } + let spec = SandboxExecSpec { + workspace_root: ws.root.clone(), + writable_workspace: matches!(req.policy.workspace_profile, Profile::WorkspaceWrite), + network: sandbox_network(req.policy.network)?, + }; + let launch = codespace_linux_sandbox::prepare(&spec, &req.argv, &ws.root).map_err(|err| { + ErrorBody::new( + ErrorCode::ProcessSpawnFailed, + format!("linux sandbox setup failed: {err}"), + ) + })?; + Ok((launch.program, launch.args, true)) +} + +fn sandbox_network(network: NetworkAxis) -> Result { + match network { + NetworkAxis::Restricted => Ok(SandboxNetwork::Restricted), + NetworkAxis::Enabled => Err(ErrorBody::new( + ErrorCode::ProcessSpawnFailed, + "linux command sandbox does not support Enabled network yet", + )), + } +} + +fn spawn_env(cwd: &Path, req: &RunnerExecRequest, sandboxed: bool) -> HashMap { + let mut env = HashMap::new(); + if req.env.use_runner_defaults { + let defaults = if sandboxed { + sandbox_exec_env(cwd) + } else { + runner_local_exec_env(cwd) + }; + env.extend(defaults); + } + for (key, value) in &req.env.overrides { + env.insert(key.clone(), value.clone()); + } + env +} + +fn utf8_launch(program: &Path, args: &[OsString]) -> Result<(String, Vec), ErrorBody> { + let program = program.to_str().ok_or_else(|| { + ErrorBody::new( + ErrorCode::ProcessSpawnFailed, + "sandbox helper path is not UTF-8", + ) + })?; + let args = args + .iter() + .map(|arg| { + arg.to_str().map(str::to_string).ok_or_else(|| { + ErrorBody::new( + ErrorCode::ProcessSpawnFailed, + "sandbox helper argument is not UTF-8", + ) + }) + }) + .collect::, _>>()?; + Ok((program.to_string(), args)) +} + #[cfg(test)] mod tests { use super::*; @@ -613,6 +676,32 @@ mod tests { ) } + #[test] + fn enabled_network_is_not_silently_restricted() { + let err = sandbox_network(NetworkAxis::Enabled).unwrap_err(); + assert_eq!(err.code, ErrorCode::ProcessSpawnFailed); + assert_eq!( + sandbox_network(NetworkAxis::Restricted).unwrap(), + SandboxNetwork::Restricted + ); + } + + #[test] + fn linux_ci_requires_sandbox_probe() { + if !codespace_linux_sandbox::require_linux_sandbox() { + return; + } + + #[cfg(not(target_os = "linux"))] + panic!("CODESPACE_REQUIRE_LINUX_SANDBOX=1 is Linux CI only"); + + #[cfg(target_os = "linux")] + assert!( + crate::linux_sandbox_available(), + "CODESPACE_REQUIRE_LINUX_SANDBOX=1 but linux sandbox helper probe failed" + ); + } + #[tokio::test] async fn completed_handles_evict_after_ttl() { let dir = tempdir().unwrap(); @@ -801,21 +890,28 @@ mod tests { let dir = tempdir().unwrap(); let ws = workspace(dir.path()); let runner = InProcessRunner::new(Arc::new(|_| {})); - let err = runner + let process_id = ProcessId("proc-missing".into()); + let result = runner .exec( &ws, RunnerExecRequest::for_host( vec!["/no/such/codespace-exec".into()], - ProcessId("proc-missing".into()), + process_id.clone(), Profile::WorkspaceWrite, ), ) - .await - .unwrap_err(); - assert_eq!( - err.as_execution().map(|body| body.code), - Some(ErrorCode::ProcessSpawnFailed) - ); + .await; + if crate::linux_sandbox_available() { + // Helper spawn succeeded; the inner command failed inside bwrap. + result.expect("sandboxed helper spawn"); + let _ = wait_chunk(&runner, &process_id).await; + } else { + let err = result.unwrap_err(); + assert_eq!( + err.as_execution().map(|body| body.code), + Some(ErrorCode::ProcessSpawnFailed) + ); + } } #[tokio::test] @@ -823,17 +919,24 @@ mod tests { let dir = tempdir().unwrap(); let ws = workspace(dir.path()); let runner = InProcessRunner::new(Arc::new(|_| {})); + let process_id = ProcessId("proc-tty-missing".into()); let mut req = RunnerExecRequest::for_host( vec!["/no/such/codespace-exec".into()], - ProcessId("proc-tty-missing".into()), + process_id.clone(), Profile::WorkspaceWrite, ); req.tty = true; - let err = runner.exec(&ws, req).await.unwrap_err(); - assert_eq!( - err.as_execution().map(|body| body.code), - Some(ErrorCode::ProcessSpawnFailed) - ); + let result = runner.exec(&ws, req).await; + if crate::linux_sandbox_available() { + result.expect("sandboxed helper spawn"); + let _ = wait_chunk(&runner, &process_id).await; + } else { + let err = result.unwrap_err(); + assert_eq!( + err.as_execution().map(|body| body.code), + Some(ErrorCode::ProcessSpawnFailed) + ); + } } #[tokio::test] @@ -909,4 +1012,43 @@ mod tests { "PTY write_stdin/read_process roundtrip, got {chunk:?}" ); } + + #[tokio::test] + async fn terminate_reaps_sandboxed_sleep() { + if !crate::linux_sandbox_available() { + return; + } + let dir = tempdir().unwrap(); + let ws = workspace(dir.path()); + let runner = InProcessRunner::new(Arc::new(|_| {})); + let process_id = ProcessId("proc-sandbox-sleep".into()); + runner + .exec( + &ws, + RunnerExecRequest::for_host( + vec!["/bin/sleep".into(), "30".into()], + process_id.clone(), + Profile::WorkspaceWrite, + ), + ) + .await + .unwrap(); + runner.kill_host(&process_id).unwrap(); + let mut eof = false; + for _ in 0..50 { + let result = runner + .read_process(RunnerReadProcess { + process_id: process_id.clone(), + cursor: 0, + }) + .await + .unwrap(); + if result.eof { + eof = true; + break; + } + tokio::time::sleep(Duration::from_millis(20)).await; + } + assert!(eof, "SIGTERM on the helper must reap the sandbox tree"); + } } diff --git a/crates/runner/tests/uds_runner.rs b/crates/runner/tests/uds_runner.rs index 2c099a4..b3545cd 100644 --- a/crates/runner/tests/uds_runner.rs +++ b/crates/runner/tests/uds_runner.rs @@ -164,7 +164,7 @@ async fn uds_exec_lost_response_is_ambiguous() { } #[tokio::test] -async fn uds_spawn_failure_is_process_spawn_failed() { +async fn uds_missing_executable_respects_sandbox_spawn_boundary() { let (client, server) = UnixStream::pair().expect("unix pair"); let (worker, events) = host_worker(); tokio::spawn(async move { @@ -175,22 +175,42 @@ async fn uds_spawn_failure_is_process_spawn_failed() { let runner = UdsRunner::from_stream(client, Arc::new(|_| {})); let dir = tempdir().unwrap(); let ws = workspace(dir.path()); - let err = runner + let process_id = ProcessId("proc-uds-missing".into()); + let result = runner .exec( &ws, RunnerExecRequest::for_host( vec!["/no/such/codespace-exec".into()], - ProcessId("proc-uds-missing".into()), + process_id.clone(), Profile::WorkspaceWrite, ), ) - .await - .unwrap_err(); - match err { - RunnerError::Execution(body) => { - assert_eq!(body.code, ErrorCode::ProcessSpawnFailed, "{body:?}"); + .await; + + if codespace_runner::linux_sandbox_available() { + let spawned = result.expect("sandbox helper should spawn successfully"); + assert_eq!(spawned.process_id, process_id); + for _ in 0..50 { + let read = runner + .read_process(codespace_runner::RunnerReadProcess { + process_id: process_id.clone(), + cursor: 0, + }) + .await + .unwrap(); + if read.eof { + break; + } + tokio::time::sleep(std::time::Duration::from_millis(20)).await; + } + } else { + let err = result.unwrap_err(); + match err { + RunnerError::Execution(body) => { + assert_eq!(body.code, ErrorCode::ProcessSpawnFailed, "{body:?}"); + } + other => panic!("expected Execution(ProcessSpawnFailed), got {other:?}"), } - other => panic!("expected Execution(ProcessSpawnFailed), got {other:?}"), } } diff --git a/crates/server/src/mcp.rs b/crates/server/src/mcp.rs index a41a90f..582a911 100644 --- a/crates/server/src/mcp.rs +++ b/crates/server/src/mcp.rs @@ -16,8 +16,8 @@ use codespace_policy::{ Workspace, }; use codespace_runner::{ - Runner, RunnerApplyPatchRequest, RunnerError, RunnerExecRequest, RunnerReadProcess, - RunnerWriteStdin, RuntimeBackend, + linux_sandbox_available, Runner, RunnerApplyPatchRequest, RunnerError, RunnerExecRequest, + RunnerReadProcess, RunnerWriteStdin, RuntimeBackend, }; use codespace_store::{Begin, Store}; use rmcp::{ @@ -66,9 +66,12 @@ exec_command.tty is optional and defaults to false. tty=true attaches a \ fixed 24x80 PTY. PTY resize is not currently supported. Use tty=true only \ when the command requires terminal semantics or an interactive TUI. -Executable workspaces currently use host execution. Host execution is not an \ -OS command sandbox. Network policy is reported by workspace_info. OS network \ -enforcement is currently none; absence of enforcement is not permission. +Executable workspaces currently use host execution. When \ +workspace_info.execution.isolation.command_sandbox is linux-sandbox, \ +exec_command is wrapped by the Linux helper. When it is none, host \ +execution is not an OS command sandbox. Network policy is reported by \ +workspace_info. OS network enforcement follows \ +execution.network.enforcement; absence of enforcement is not permission. Treat apply_patch status=unknown as possibly executed. Do not blindly retry \ the mutation with a new operation_key. @@ -227,6 +230,7 @@ impl CodeSpace { .mark_shell_busy(¶ms.workspace_id.0, &process_id.0) .map_err(err_json)?; let mut req = RunnerExecRequest::for_host(params.command, process_id.clone(), ws.profile); + req.policy.network = PermissionProfile::from_workspace_profile(ws.profile).network; req.tty = params.tty; match self.runner.exec(ws, req).await { Ok(result) => Ok(Json(ExecCommandResult { @@ -506,11 +510,23 @@ fn workspace_execution_info(ws: &Workspace) -> WorkspaceExecutionInfo { file_read_supported: ws.environment_kind.file_read_supported(), file_write_supported: ws.environment_kind.file_write_supported(), }; - WorkspaceExecutionInfo::from_effective( + let info = WorkspaceExecutionInfo::from_effective( environment, permissions, client_network_policy(policy.network), - ) + ); + advertise_linux_sandbox(info, policy.network) +} + +fn advertise_linux_sandbox( + info: WorkspaceExecutionInfo, + network: NetworkAxis, +) -> WorkspaceExecutionInfo { + if linux_sandbox_available() { + info.with_linux_command_sandbox(matches!(network, NetworkAxis::Restricted)) + } else { + info + } } fn lookup(registry: &Registry, workspace_id: Option) -> Result { @@ -631,6 +647,18 @@ mod tests { exec.process.available, exec.permissions.exec && exec.environment.exec_supported ); + if linux_sandbox_available() { + assert_eq!( + exec.isolation.command_sandbox, + CommandSandboxState::LinuxSandbox + ); + if exec.network.policy == NetworkPolicyState::Restricted { + assert_eq!(exec.network.enforcement, NetworkEnforcementState::Enforced); + } + } else { + assert_eq!(exec.isolation.command_sandbox, CommandSandboxState::None); + assert_eq!(exec.network.enforcement, NetworkEnforcementState::None); + } } fn assert_instructions_cover_execution_contract(text: &str) { @@ -645,14 +673,16 @@ mod tests { "{text}" ); assert!(text.contains("WORKSPACE_BUSY"), "{text}"); + assert!(text.contains("command_sandbox is linux-sandbox"), "{text}"); assert!( - text.contains("Host execution is not an OS command sandbox"), + text.contains("host execution is not an OS command sandbox"), "{text}" ); assert!( text.contains("Network policy is reported by workspace_info"), "{text}" ); + assert!(text.contains("execution.network.enforcement"), "{text}"); assert!( text.contains("absence of enforcement is not permission"), "{text}" @@ -712,9 +742,7 @@ mod tests { .tty; assert!(tty.supported); assert!(!tty.resize_supported); - assert_eq!(exec.isolation.command_sandbox, CommandSandboxState::None); assert_eq!(exec.network.policy, NetworkPolicyState::Restricted); - assert_eq!(exec.network.enforcement, NetworkEnforcementState::None); let json = serde_json::to_value(&info).unwrap(); assert!(json.get("environment_id").is_none()); assert!(!json.to_string().contains("\"environment_id\"")); @@ -963,6 +991,33 @@ mod tests { .0 } + async fn assert_missing_exec_boundary_and_release(cs: &CodeSpace, store: &Store, tty: bool) { + let result = cs + .exec_command(Parameters(ExecCommandParams { + workspace_id: WorkspaceId("demo".into()), + command: vec!["/no/such/codespace-exec".into()], + work_id: None, + tty, + })) + .await; + + if linux_sandbox_available() { + let started = result.expect("sandbox helper should spawn successfully").0; + assert_eq!(started.dispatch_status, ExecDispatchStatus::Confirmed); + for _ in 0..50 { + if store.try_acquire_write("demo").is_ok() { + break; + } + tokio::time::sleep(std::time::Duration::from_millis(20)).await; + } + } else { + let err = parse_exec_err(result); + assert_eq!(err.code, ErrorCode::ProcessSpawnFailed); + } + + let _lease = store.try_acquire_write("demo").expect("lease released"); + } + #[tokio::test] async fn invalid_command_does_not_hold_lease() { let dir = tempfile::tempdir().unwrap(); @@ -984,47 +1039,27 @@ mod tests { } #[tokio::test] - async fn confirmed_spawn_failure_releases_lease() { + async fn missing_executable_releases_lease_across_spawn_boundaries() { let dir = tempfile::tempdir().unwrap(); let ws_root = dir.path().join("ws"); std::fs::create_dir(&ws_root).unwrap(); - let cs = CodeSpace::new(write_registry(ws_root)); - let err = parse_exec_err( - cs.exec_command(Parameters(ExecCommandParams { - workspace_id: WorkspaceId("demo".into()), - command: vec!["/no/such/codespace-exec".into()], - work_id: None, - tty: false, - })) - .await, - ); - assert_eq!(err.code, ErrorCode::ProcessSpawnFailed); - let started = exec_echo(&cs).await; - assert_eq!(started.dispatch_status, ExecDispatchStatus::Confirmed); + let store = Arc::new(Store::memory().unwrap()); + let cs = CodeSpace::with_store(write_registry(ws_root), store.clone()); + assert_missing_exec_boundary_and_release(&cs, &store, false).await; } #[tokio::test] - async fn tty_confirmed_spawn_failure_is_process_spawn_failed() { + async fn tty_missing_executable_releases_lease_across_spawn_boundaries() { let dir = tempfile::tempdir().unwrap(); let ws_root = dir.path().join("ws"); std::fs::create_dir(&ws_root).unwrap(); - let cs = CodeSpace::new(write_registry(ws_root)); - let err = parse_exec_err( - cs.exec_command(Parameters(ExecCommandParams { - workspace_id: WorkspaceId("demo".into()), - command: vec!["/no/such/codespace-exec".into()], - work_id: None, - tty: true, - })) - .await, - ); - assert_eq!(err.code, ErrorCode::ProcessSpawnFailed); - let started = exec_echo(&cs).await; - assert_eq!(started.dispatch_status, ExecDispatchStatus::Confirmed); + let store = Arc::new(Store::memory().unwrap()); + let cs = CodeSpace::with_store(write_registry(ws_root), store.clone()); + assert_missing_exec_boundary_and_release(&cs, &store, true).await; } #[tokio::test] - async fn uds_spawn_failure_releases_lease_and_propagates_code() { + async fn uds_missing_executable_releases_lease_across_spawn_boundaries() { let dir = tempfile::tempdir().unwrap(); let ws_root = dir.path().join("ws"); std::fs::create_dir(&ws_root).unwrap(); @@ -1044,17 +1079,7 @@ mod tests { }), )); let cs = CodeSpace::with_store_and_runner(write_registry(ws_root), store.clone(), runner); - let err = parse_exec_err( - cs.exec_command(Parameters(ExecCommandParams { - workspace_id: WorkspaceId("demo".into()), - command: vec!["/no/such/codespace-exec".into()], - work_id: None, - tty: false, - })) - .await, - ); - assert_eq!(err.code, ErrorCode::ProcessSpawnFailed); - let _lease = store.try_acquire_write("demo").expect("lease released"); + assert_missing_exec_boundary_and_release(&cs, &store, false).await; } #[tokio::test] diff --git a/crates/server/tests/process.rs b/crates/server/tests/process.rs index 289a698..98e5dee 100644 --- a/crates/server/tests/process.rs +++ b/crates/server/tests/process.rs @@ -725,9 +725,14 @@ async fn exec_command_schema_has_optional_tty_and_live_tools_unchanged() { exec["process"]["capabilities"]["tty"]["resize_supported"], false ); - assert_eq!(exec["isolation"]["command_sandbox"], "none"); + if codespace_runner::linux_sandbox_available() { + assert_eq!(exec["isolation"]["command_sandbox"], "linux-sandbox"); + assert_eq!(exec["network"]["enforcement"], "enforced"); + } else { + assert_eq!(exec["isolation"]["command_sandbox"], "none"); + assert_eq!(exec["network"]["enforcement"], "none"); + } assert_eq!(exec["network"]["policy"], "restricted"); - assert_eq!(exec["network"]["enforcement"], "none"); client.cancel().await.expect("cancel"); } diff --git a/docs/codex-reuse.md b/docs/codex-reuse.md index 7decb9b..392e7a4 100644 --- a/docs/codex-reuse.md +++ b/docs/codex-reuse.md @@ -53,6 +53,8 @@ CodeSpace Core ← only authorization authority │ interactive spawn; no Codex types on the runner API │ crates/file-system (codespace-fs) │ no-follow I/O + bounded walk; PathSandbox authorizes, adapter I/O is the safety boundary + │ crates/linux-sandbox (codespace-linux-sandbox) + │ helper wrap of user argv; Restricted net hard deny; no Codex types on Runner ▼ Codex execution subgraph (pinned) → OS ``` @@ -100,7 +102,7 @@ CodeSpace core isolated adapter (crates/patch today; crates/codex-runtime today; crates/pty today; -crates/file-system today) +crates/file-system today; crates/linux-sandbox today) ────────────────────────────────────────── approved execution subgraph allowed including transitive codex-protocol @@ -145,8 +147,9 @@ runtime adapter: - Pin stays [upstream-lock.md](upstream-lock.md) (`6b9826e3aa83b1a5947db50f4332cb9c65f1b340`). - Path dependency from an **isolated** Cargo workspace, not the repo root. Today: `crates/patch`, `crates/codex-runtime` - (`codespace-codex-runtime`), `crates/pty` (`codespace-pty`), and - `crates/file-system` (`codespace-fs`). + (`codespace-codex-runtime`), `crates/pty` (`codespace-pty`), + `crates/file-system` (`codespace-fs`), and `crates/linux-sandbox` + (`codespace-linux-sandbox`). - NOTICE + Apache-2.0 attribution. - Product policy stays in front of and behind the subgraph. - Do not file-copy a crate out of the Codex workspace. @@ -167,7 +170,7 @@ checkout and cargo, not this grep. | core manifests | root + `crates/{domain,policy,runner,store,server}/Cargo.toml` | tiny | crate in the update range | | core sources | those crates’ trees | low | same | | server tests | `tests/` | low | `crates/server` or `tests/` changed | -| adapter manifests | `crates/patch/Cargo.toml`; `crates/codex-runtime`; `crates/pty`; `crates/file-system` | tiny | adapter in the update range; allowlist only | +| adapter manifests | `crates/patch/Cargo.toml`; `crates/codex-runtime`; `crates/pty`; `crates/file-system`; `crates/linux-sandbox` | tiny | adapter in the update range; allowlist only | | upstream | `third_party/codex` | huge / false positives | never | Update range is `SCAN_BASE` (PR base / previous `main`). Unknown range @@ -181,11 +184,20 @@ allow only the approved subgraph (`crates/patch` today: graph, `codex-utils-path-uri`, `codex-process-hardening`; `crates/codex-runtime`: `codex-process-hardening`, `codex-uds`; `crates/pty`: `codex-utils-pty`; `crates/file-system`: -`codex-file-system`, `codex-exec-server`, `codex-utils-path-uri`). Sources keep the agent/model patterns +`codex-file-system`, `codex-exec-server`, `codex-utils-path-uri`; +`crates/linux-sandbox`: `codex-linux-sandbox`, `codex-sandboxing`, +`codex-protocol`, `codex-utils-path-uri`). Sources keep the agent/model patterns (`api.openai.com`, Responses, `codex-login`, `codex-core`, `codex-app-server`, `async-openai`). Comments that mention a crate name are not cargo deps. +The linux-sandbox adapter also pins the Rama **0.3.0-alpha.4** leaf +crates (`rama-error`, `rama-macros`, `rama-utils`) as resolver guards. +Codex pin `6b9826e` is validated against that train. A fresh resolve can +otherwise pick stable `0.3.0` for those leaves while `rama-core` stays +alpha.4. The guards apply to both the isolated helper lock and the root +lock (path dependency). CI `cargo clippy` / `cargo test` use `--locked`. + Do **not** wrap the standalone `apply_patch` binary as a security boundary. Do **not** wrap Codex App Server as an internal backend. @@ -204,9 +216,10 @@ rejected. ## Staged take (when those WPs exist) Documented order. **Taken in code this WP:** process-hardening, UDS, PTY -(`crates/pty` → `codex-utils-pty`), and filesystem (`crates/file-system` -→ `LOCAL_FS` / `ExecutorFileSystem`). **Not taken:** linux-sandbox, -network. +(`crates/pty` → `codex-utils-pty`), filesystem (`crates/file-system` +→ `LOCAL_FS` / `ExecutorFileSystem`), and linux-sandbox +(`crates/linux-sandbox` → helper wrap, Restricted hard deny). **Not +taken:** network (`Enabled` + proxy). ```text process-hardening → PTY → UDS / path → filesystem → linux-sandbox → network @@ -247,6 +260,23 @@ It is not the I/O safety boundary; live processes may race a pre-check. and typed errors (`SymlinkRejected`, `NotRegularFile`). MCP `read` / `find` stay workspace-relative. +**`codex-linux-sandbox`** via `crates/linux-sandbox` +(`codespace-linux-sandbox`). +([`codex-rs/linux-sandbox/Cargo.toml`](../third_party/codex/codex-rs/linux-sandbox/Cargo.toml)) + +Helper wrap of user argv (`spawn_pipe` / `spawn_pty`). Restricted +network is `--unshare-net` plus Restricted seccomp. Direct proxy flags +(`--allow-network-for-proxy`, `--proxy-route-spec`) are unused; that is +the next WP. Runtime deps do not include `codex-core`; **dev-dependencies +do** — adapter tests must not pull that graph into the product binary. +Public types stay CodeSpace (`SandboxExecSpec` / `SandboxLaunch`). +`codex_protocol::PermissionProfile` stays inside the crate. + +**Transitive (allowed in the adapter):** `codex-sandboxing`, +`codex-network-proxy`, `codex-protocol`. Direct use of the proxy is for +when a PermissionProfile **network** axis exists. Not an allow engine. +Not a root-workspace dep. + ### Prefer reuse (when that WP) **`codex-uds`** (already in `codespace-codex-runtime`) @@ -273,19 +303,6 @@ MCP still exposes workspace-relative paths only. Tree-sitter Bash/PowerShell, shlex, `which`. Parse / quoting / executable resolution only. Not the allow engine. -**`codex-linux-sandbox`** -([`codex-rs/linux-sandbox/Cargo.toml`](../third_party/codex/codex-rs/linux-sandbox/Cargo.toml)) - -Landlock, seccomp, process-hardening, network-proxy, protocol, -sandboxing. Width is a cohesive Linux sandbox. A **container** does not -replace it. Runtime deps do not include `codex-core`; **dev-dependencies -do** — adapter tests must not pull that graph into the product binary. - -**Transitive (allowed in the adapter when the subgraph is taken):** -`codex-sandboxing`, `codex-network-proxy`. Direct use of the proxy is -for when a PermissionProfile **network** axis exists. Not an allow -engine. Not a root-workspace dep. - ### Internal protocol candidate **`codex-exec-server-protocol`** @@ -349,12 +366,13 @@ second authorizer. - Container lifecycle and workspace bind-mount **policy**. - Isolated adapter workspaces (`crates/patch`, `crates/codex-runtime` / `codespace-codex-runtime`, `crates/pty` / - `codespace-pty`, `crates/file-system` / `codespace-fs`). + `codespace-pty`, `crates/file-system` / `codespace-fs`, + `crates/linux-sandbox` / `codespace-linux-sandbox`). ## Next implementation WP -The next **code** work packages are remaining execution subgraph crates -(linux-sandbox, network) behind the existing `Runner` +The next **code** work package is the remaining execution subgraph +(network: `Enabled` + proxy) behind the existing `Runner` trait. Do not split `apply_patch` into multiple gateway-driven RPCs. Do not default to a homegrown PTY / Landlock / seccomp stack. Take the diff --git a/docs/execution-substrate.md b/docs/execution-substrate.md index cbe16df..6949a62 100644 --- a/docs/execution-substrate.md +++ b/docs/execution-substrate.md @@ -42,7 +42,7 @@ CI: `policy-scan` job runs `scripts/check-no-model-deps.sh` **without** submodules, in parallel with `rust`. Core manifests may not declare `codex-*` deps. Core sources keep the agent/model grep. Isolated adapter manifests (`crates/patch`, `crates/codex-runtime`, `crates/pty`, -`crates/file-system`) use an +`crates/file-system`, `crates/linux-sandbox`) use an **allowlist**; `third_party/codex` sources are never scanned. `SCAN_BASE` limits the tree to the update range; unknown range scans all core crates and adapter manifests. Clippy/tests still always run. @@ -63,8 +63,10 @@ filesystem glob + network axes live in `crates/policy` as `PermissionProfile`, mapped from those profiles. `process_exec` is the Exec axis (`read-only` denies, `workspace-write` allows). Path globs are **domain only**; live enforcement stays coarse `allow(Write|Exec)` plus -PathSandbox. The network axis is recorded only; it does not grant. This -is not an import of Codex user config. +PathSandbox. Restricted network is OS-enforced when the Linux helper +probe succeeds (`workspace_info.execution.network.enforcement=enforced`). +`Enabled` / proxy is later. The axis never grants. This is not an +import of Codex user config. ## Four axes (target domain) @@ -192,9 +194,10 @@ request onto runner DTOs. Prefer `codex-process-hardening`, `codex-utils-pty`, `codex-uds` (transport primitive; RPC stays CodeSpace), and `codex-file-system` under PathSandbox scope (`crates/file-system` → `LOCAL_FS`, no-follow I/O and bounded walk). -Then `codex-linux-sandbox` (dev-dep includes `codex-core`; -keep that out of the product graph) plus `codex-network-proxy` when a -network axis exists. A container does not replace that subgraph. +`codex-linux-sandbox` is taken via `crates/linux-sandbox` (dev-dep +includes `codex-core`; keep that out of the product graph). Plus +`codex-network-proxy` when a network axis exists. A container does not +replace that subgraph. App Server streaming processes are connection-scoped and die when that connection closes. CodeSpace keeps **MCP request lifetime ≠ process @@ -297,7 +300,8 @@ P0 code for this substrate is in: Runner exec DTO **shape** resource serializer (request vs process owners), opt-in `UdsRunner` + `codespace-codex-runtime` (process-hardening + UDS), isolated `crates/pty` → `codex-utils-pty`, isolated `crates/file-system` → -`LOCAL_FS`. Live MCP tool **names** stay frozen; +`LOCAL_FS`, isolated `crates/linux-sandbox` → `codex-linux-sandbox`. +Live MCP tool **names** stay frozen; `exec_command` has optional `tty` (default false). **P0** — landed or next subgraph WPs: `codex-apply-patch` (done), exec @@ -305,8 +309,9 @@ runtime **shape** on Runner DTOs (done), PermissionProfile domain in `crates/policy` (done), Environment domain (operator-registered; not a tool arg) (done), resource serializer (done), transport (`UdsRunner`) with process-hardening + UDS (done, opt-in), PTY I/O -backend (done), filesystem mechanics under PathSandbox (done). Still -out: linux-sandbox → network. +backend (done), filesystem mechanics under PathSandbox (done), Linux +command sandbox (done: helper wrap, Restricted hard deny). Still +out: network (`Enabled` + proxy). **P1** — operation state machine / diff ledger, approval fallback tools, internal watch, richer process handles (resize, caps), @@ -319,5 +324,5 @@ MCP contract, deterministic hooks, skills as resources or prompts. The next **code** WPs are remaining execution subgraph crates behind the existing trait, without splitting `apply_patch` into gateway RPCs. -Start at linux-sandbox. Sandbox / network are not a default homegrown OS +Start at network. Sandbox / network are not a default homegrown OS stack ([codex-reuse.md](codex-reuse.md)). diff --git a/docs/ko/codex-reuse.md b/docs/ko/codex-reuse.md index 40b4439..20f9fae 100644 --- a/docs/ko/codex-reuse.md +++ b/docs/ko/codex-reuse.md @@ -51,6 +51,8 @@ CodeSpace Core ← only authorization authority │ interactive spawn; runner API에 Codex 타입 없음 │ crates/file-system (codespace-fs) │ no-follow I/O + 제한된 walk; PathSandbox가 인가, I/O 안전은 어댑터 + │ crates/linux-sandbox (codespace-linux-sandbox) + │ 사용자 argv 헬퍼 wrap; Restricted 네트워크 hard deny; Runner에 Codex 타입 없음 ▼ Codex execution subgraph (pinned) → OS ``` @@ -98,7 +100,7 @@ CodeSpace core isolated adapter (crates/patch today; crates/codex-runtime today; crates/pty today; -crates/file-system today) +crates/file-system today; crates/linux-sandbox today) ────────────────────────────────────────── approved execution subgraph allowed including transitive codex-protocol @@ -145,7 +147,8 @@ Runner helper - **격리된** Cargo 워크스페이스에서의 경로 의존성이며 저장소 루트가 아닙니다. 오늘: `crates/patch`, `crates/codex-runtime` (`codespace-codex-runtime`), `crates/pty` (`codespace-pty`), - `crates/file-system` (`codespace-fs`). + `crates/file-system` (`codespace-fs`), `crates/linux-sandbox` + (`codespace-linux-sandbox`). - NOTICE + Apache-2.0 귀속. - 제품 정책은 서브그래프 앞과 뒤에 남습니다. - Codex 워크스페이스에서 크레이트를 파일 복사하지 마세요. @@ -166,7 +169,7 @@ checkout과 cargo가 지배합니다. | core manifests | root + `crates/{domain,policy,runner,store,server}/Cargo.toml` | tiny | crate in the update range | | core sources | those crates’ trees | low | same | | server tests | `tests/` | low | `crates/server` or `tests/` changed | -| adapter manifests | `crates/patch/Cargo.toml`; `crates/codex-runtime`; `crates/pty`; `crates/file-system` | tiny | adapter in the update range; allowlist only | +| adapter manifests | `crates/patch/Cargo.toml`; `crates/codex-runtime`; `crates/pty`; `crates/file-system`; `crates/linux-sandbox` | tiny | adapter in the update range; allowlist only | | upstream | `third_party/codex` | huge / false positives | never | 갱신 범위는 `SCAN_BASE`(PR base / 이전 `main`)입니다. 범위를 모르면 @@ -180,11 +183,21 @@ checkout과 cargo가 지배합니다. `codex-exec-server`, `codex-utils-path-uri`, `codex-process-hardening`; `crates/codex-runtime`: `codex-process-hardening`, `codex-uds`; `crates/pty`: `codex-utils-pty`; `crates/file-system`: -`codex-file-system`, `codex-exec-server`, `codex-utils-path-uri`). 소스는 에이전트/모델 +`codex-file-system`, `codex-exec-server`, `codex-utils-path-uri`; +`crates/linux-sandbox`: `codex-linux-sandbox`, `codex-sandboxing`, +`codex-protocol`, `codex-utils-path-uri`). 소스는 에이전트/모델 패턴을 유지합니다(`api.openai.com`, Responses, `codex-login`, `codex-core`, `codex-app-server`, `async-openai`). 크레이트 이름을 언급하는 주석은 cargo 의존성이 아닙니다. +linux-sandbox 어댑터는 Rama **0.3.0-alpha.4** leaf +크레이트(`rama-error`, `rama-macros`, `rama-utils`)를 resolver +가드로도 고정합니다. Codex 핀 `6b9826e`는 그 train으로 검증되어 +있습니다. 새로 resolve하면 `rama-core`는 alpha.4인데 leaf만 +stable `0.3.0`이 될 수 있습니다. 가드는 격리 helper lock과 root lock +(path 의존) 모두에 적용됩니다. CI `cargo clippy` / `cargo test`는 +`--locked`입니다. + 독립 `apply_patch` 바이너리를 보안 경계로 감싸지 **마세요**. Codex App Server를 내부 백엔드로 감싸지 **마세요**. @@ -204,8 +217,9 @@ login, models, plugins, rollout도 따라옵니다. 그 폭발 반경은 여전 문서화된 순서입니다. **이 WP에서 코드로 가져옴:** process-hardening, UDS, PTY(`crates/pty` → `codex-utils-pty`), filesystem(`crates/file-system` -→ `LOCAL_FS` / `ExecutorFileSystem`). **아직 안 가져옴:** linux-sandbox, -network. +→ `LOCAL_FS` / `ExecutorFileSystem`), linux-sandbox +(`crates/linux-sandbox` → 헬퍼 wrap, Restricted hard deny). **아직 안 +가져옴:** network(`Enabled` + proxy). ```text process-hardening → PTY → UDS / path → filesystem → linux-sandbox → network @@ -246,6 +260,24 @@ open/read/write/remove/walk와 typed error(`SymlinkRejected`, `NotRegularFile`)를 소유합니다. MCP `read` / `find`는 워크스페이스 상대로 남습니다. +**`codex-linux-sandbox`** via `crates/linux-sandbox` +(`codespace-linux-sandbox`). +([`codex-rs/linux-sandbox/Cargo.toml`](../../third_party/codex/codex-rs/linux-sandbox/Cargo.toml)) + +사용자 argv를 `spawn_pipe` / `spawn_pty`에서 헬퍼로 감쌉니다. +Restricted 네트워크는 `--unshare-net`과 Restricted seccomp입니다. 직접 +프록시 플래그(`--allow-network-for-proxy`, `--proxy-route-spec`)는 +쓰지 않습니다. 그건 다음 WP입니다. 런타임 의존성에는 `codex-core`가 +없습니다. **dev-dependencies에는 있습니다** — 어댑터 시험이 그 +그래프를 제품 바이너리로 끌어오면 안 됩니다. 공개 타입은 +CodeSpace(`SandboxExecSpec` / `SandboxLaunch`)만. +`codex_protocol::PermissionProfile`은 이 크레이트 안에 남습니다. + +**전이(어댑터에서 허용):** `codex-sandboxing`, `codex-network-proxy`, +`codex-protocol`. 프록시의 직접 사용은 PermissionProfile **네트워크** +축이 있을 때입니다. 허용 엔진이 아닙니다. 루트 워크스페이스 의존성이 +아닙니다. + ### 재사용 선호 (그 WP가 올 때) **`codex-uds`** (이미 `codespace-codex-runtime`에 있음) @@ -272,20 +304,6 @@ Unix: Tokio `fs` / `net` / `rt`. 선택적 Runner Unix 소켓 워커의 소켓 Tree-sitter Bash/PowerShell, shlex, `which`. 파싱 / 인용 / 실행 파일 해석만. 허용 엔진이 아닙니다. -**`codex-linux-sandbox`** -([`codex-rs/linux-sandbox/Cargo.toml`](../../third_party/codex/codex-rs/linux-sandbox/Cargo.toml)) - -Landlock, seccomp, process-hardening, network-proxy, protocol, -sandboxing. 너비는 응집력 있는 Linux 샌드박스입니다. **컨테이너**가 -이를 대체하지 않습니다. 런타임 의존성에는 `codex-core`가 없습니다. -**dev-dependencies에는 있습니다** — 어댑터 시험이 그 그래프를 제품 -바이너리로 끌어오면 안 됩니다. - -**전이(서브그래프를 가져가면 어댑터에서 허용):** -`codex-sandboxing`, `codex-network-proxy`. 프록시의 직접 사용은 -PermissionProfile **네트워크** 축이 있을 때입니다. 허용 엔진이 -아닙니다. 루트 워크스페이스 의존성이 아닙니다. - ### 내부 프로토콜 후보 **`codex-exec-server-protocol`** @@ -349,12 +367,13 @@ rollout, history. 제품 exec 흐름이지 `spawn`이 아닙니다. - 컨테이너 수명주기와 워크스페이스 바인드 마운트 **정책**. - 격리된 어댑터 워크스페이스(`crates/patch`, `crates/codex-runtime` / `codespace-codex-runtime`, `crates/pty` / - `codespace-pty`, `crates/file-system` / `codespace-fs`). + `codespace-pty`, `crates/file-system` / `codespace-fs`, + `crates/linux-sandbox` / `codespace-linux-sandbox`). ## 다음 구현 WP 다음 **코드** 작업 패키지는 기존 `Runner` 트레이트 뒤의 남은 실행 -서브그래프(linux-sandbox, network)입니다. +서브그래프(network: `Enabled` + proxy)입니다. `apply_patch`를 게이트웨이가 구동하는 여러 RPC로 쪼개면 안 됩니다. 기본으로 자체 PTY / Landlock / seccomp 스택을 두지 마세요. diff --git a/docs/ko/execution-substrate.md b/docs/ko/execution-substrate.md index 9b9b296..6278277 100644 --- a/docs/ko/execution-substrate.md +++ b/docs/ko/execution-substrate.md @@ -42,7 +42,7 @@ CI: `policy-scan` job은 서브모듈 **없이** `scripts/check-no-model-deps.sh `rust`와 병렬로 실행합니다. 핵심 매니페스트는 `codex-*` 의존성을 선언하면 안 됩니다. 핵심 소스는 에이전트/모델 grep을 유지합니다. 격리된 어댑터 매니페스트(`crates/patch`, `crates/codex-runtime`, `crates/pty`, -`crates/file-system`)는 +`crates/file-system`, `crates/linux-sandbox`)는 **허용 목록**을 사용합니다. `third_party/codex` 소스는 절대 스캔하지 않습니다. `SCAN_BASE`는 트리를 갱신 범위로 제한합니다. 범위를 모르면 모든 핵심 크레이트와 어댑터 매니페스트를 스캔합니다. Clippy/시험은 @@ -64,7 +64,9 @@ CI: `policy-scan` job은 서브모듈 **없이** `scripts/check-no-model-deps.sh 있고 그 프로필에서 매핑됩니다. `process_exec`가 Exec 축입니다 (`read-only`는 거부, `workspace-write`는 허용). 경로 glob은 **표현만** 있고 live enforcement는 기존 coarse `allow(Write|Exec)` + PathSandbox입니다. -네트워크 축은 기록만 하며 허용을 올리지 않습니다. Codex 사용자 설정을 +Restricted 네트워크는 Linux 헬퍼 probe가 성공하면 OS에서 강제합니다 +(`workspace_info.execution.network.enforcement=enforced`). `Enabled` / +proxy는 이후입니다. 축이 허용을 올리지는 않습니다. Codex 사용자 설정을 가져오는 것이 아닙니다. ## 네 축 (목표 도메인) @@ -190,9 +192,10 @@ UDS 와이어를 클라이언트 계약에 넣지 마세요. 러너 DTO로 매핑합니다. `codex-process-hardening`, `codex-utils-pty`, `codex-uds`(전송 프리미티브, RPC는 CodeSpace)를 선호하세요. PathSandbox 범위 아래 `codex-file-system`(`crates/file-system` → `LOCAL_FS`, -no-follow I/O와 제한된 walk)을 가져왔습니다. 네트워크 축이 생기면 -`codex-linux-sandbox`(dev-dep에 `codex-core` 포함, 제품 그래프에서는 -빼 둘 것)와 `codex-network-proxy`를 보세요. 컨테이너가 그 서브그래프를 +no-follow I/O와 제한된 walk)을 가져왔습니다. +`codex-linux-sandbox`는 `crates/linux-sandbox`로 가져왔습니다(dev-dep에 +`codex-core` 포함, 제품 그래프에서는 빼 둘 것). 네트워크 축이 생기면 +`codex-network-proxy`를 보세요. 컨테이너가 그 서브그래프를 대체하지 않습니다. App Server 스트리밍 프로세스는 연결 범위이며 그 연결이 닫히면 죽습니다. @@ -290,7 +293,8 @@ Approval → policy + human, Attachment → artifact 리소스. 자원 직렬화기(요청 vs 프로세스 소유), 선택적 `UdsRunner` + `codespace-codex-runtime`(process-hardening + UDS), 격리된 `crates/pty` → `codex-utils-pty`, 격리된 `crates/file-system` → -`LOCAL_FS`. 실제 MCP 도구 **이름**은 그대로입니다. +`LOCAL_FS`, 격리된 `crates/linux-sandbox` → `codex-linux-sandbox`. +실제 MCP 도구 **이름**은 그대로입니다. `exec_command`에 선택적 `tty`(기본 false)가 있습니다. **P0** — 착수했거나 다음 서브그래프 WP: `codex-apply-patch`(완료), @@ -298,7 +302,8 @@ Runner DTO의 exec 런타임 **형태**(완료), `crates/policy`의 PermissionProfile 도메인(완료), Environment 도메인(운영자 등록, 도구 인자 아님)(완료), 자원 직렬화기(완료), process-hardening + UDS를 받는 전송(`UdsRunner`)(완료, 선택적), PTY I/O 백엔드(완료), PathSandbox 아래 -파일시스템 역학(완료). 아직 밖: linux-sandbox → network. +파일시스템 역학(완료), Linux command sandbox(완료: 헬퍼 wrap, Restricted +hard deny). 아직 밖: network(`Enabled` + proxy). **P1** — 작업 상태 기계 / diff 원장, 승인 폴백 도구, 내부 watch, 더 풍부한 프로세스 핸들(resize, caps), 연결 끊김 정책. @@ -309,6 +314,6 @@ PermissionProfile 도메인(완료), Environment 도메인(운영자 등록, 도 **P3** — 원격 환경, MCP 연합, 아티팩트 레지스트리. 다음 **코드** WP는 기존 트레이트 뒤의 남은 실행 서브그래프이며, -`apply_patch`를 게이트웨이 RPC로 쪼개지 않습니다. linux-sandbox부터 +`apply_patch`를 게이트웨이 RPC로 쪼개지 않습니다. network부터 시작합니다. Sandbox / network는 기본 자체 OS 스택이 아닙니다 ([codex-reuse.md](codex-reuse.md)). diff --git a/docs/ko/operations.md b/docs/ko/operations.md index 374efa5..5105d93 100644 --- a/docs/ko/operations.md +++ b/docs/ko/operations.md @@ -27,16 +27,19 @@ Codex 핀은 [upstream-lock.md](upstream-lock.md)의 커밋에 있는 [codex-reuse.md](codex-reuse.md)와 [execution-substrate.md](execution-substrate.md)를 보세요. -게이트웨이가 패치 헬퍼를 자기 옆에서 찾을 수 있도록 게이트웨이와 패치 -헬퍼를 **같은** 디렉터리에 빌드하세요(`CODESPACE_PATCH_BIN`을 설정해도 +게이트웨이가 패치 헬퍼와 Linux 샌드박스 헬퍼를 자기 옆에서 찾을 수 +있도록 게이트웨이와 헬퍼를 **같은** 디렉터리에 빌드하세요 +(`CODESPACE_PATCH_BIN` / `CODESPACE_LINUX_SANDBOX_BIN`을 설정해도 됩니다). UDS 워커는 선택입니다(`CODESPACE_RUNTIME_BIN`). ```bash cargo build -p codespace-server --bin codespace-mcp --release cargo build --manifest-path crates/patch/Cargo.toml --bin codespace-patch --release +cargo build --manifest-path crates/linux-sandbox/Cargo.toml --bin codespace-linux-sandbox --release mkdir -p dist cp target/release/codespace-mcp dist/ cp crates/patch/target/release/codespace-patch dist/ +cp crates/linux-sandbox/target/release/codespace-linux-sandbox dist/ # Optional Unix-socket worker (not the default exec path): cargo build --manifest-path crates/codex-runtime/Cargo.toml --bin codespace-codex-runtime --release cp crates/codex-runtime/target/release/codespace-codex-runtime dist/ @@ -49,7 +52,12 @@ cp crates/codex-runtime/target/release/codespace-codex-runtime dist/ `InProcessRunner`를 실행합니다. hardening은 워커/헬퍼 **프로세스** 강화입니다(`main` 첫 줄 `pre_main_hardening()`, `ctor` 없음). command sandbox가 아닙니다. 기본 `exec_command`는 여전히 프로세스 내부 호스트 -spawn입니다. `exec_command.tty` 기본값은 false(파이프)입니다. +spawn입니다. Linux에서 `CODESPACE_LINUX_SANDBOX_BIN`(또는 게이트웨이 옆 +`codespace-linux-sandbox`) probe가 성공하면 그 spawn을 헬퍼가 감쌉니다. +`workspace_info.execution.isolation.command_sandbox`는 그때만 +`linux-sandbox`이고, 아니면 `none`입니다. Restricted 네트워크는 그때 +OS에서 강제됩니다(`network.enforcement=enforced`). +`exec_command.tty` 기본값은 false(파이프)입니다. `tty: true`는 24x80 PTY를 붙입니다. Exec DTO cwd는 `WorkspaceRoot`이며 `PATH` / `HOME` / `LANG`은 러너 프로세스에서 적용합니다(PTY일 때 `TERM=xterm`). @@ -81,8 +89,9 @@ spawn입니다. `exec_command.tty` 기본값은 false(파이프)입니다. occupancy 아님 — `exec_command`나 `apply_patch`는 여전히 `WORKSPACE_BUSY`일 수 있음; 도구 존재는 `tools_exposed`), process가 가능할 때 resize 없는 고정 24x80 PTY, mutation lease / -`WORKSPACE_BUSY`, 워크스페이스 범위 파일 도구 대 command sandbox 없음, -OS 강제 없는 restricted 네트워크 정책입니다. +`WORKSPACE_BUSY`, 워크스페이스 범위 파일 도구 대 광고된 Linux command +sandbox, 헬퍼 probe가 성공하면 OS가 강제하는 restricted 네트워크 +정책입니다. `output_combined=true`는 `read_process`가 하나의 combined stream만 노출하고 stdout/stderr origin을 보존하지 않는다는 뜻입니다. `exec_command`는 `dispatch_status`(`confirmed` 또는 diff --git a/docs/ko/runner-isolation.md b/docs/ko/runner-isolation.md index 7bb5a8c..b333d07 100644 --- a/docs/ko/runner-isolation.md +++ b/docs/ko/runner-isolation.md @@ -3,8 +3,11 @@ [English](../runner-isolation.md) | [한국어](runner-isolation.md) **목표** 실행 격리 OS는 Linux 컨테이너입니다. **현재** `exec_command`는 -호스트 프로세스입니다(`tokio::process::Command`, 워크스페이스 cwd, -`env_clear`). 게이트웨이 단위 시험은 macOS에서 실행할 수 있습니다. 그것은 +호스트 프로세스입니다. Linux 헬퍼 probe가 성공하면 pipe와 PTY spawn이 +같은 `codespace-linux-sandbox` argv를 감쌉니다(bubblewrap + +`no_new_privs`/seccomp). probe가 실패하면(macOS, bwrap 없음) 샌드박스 +없이 실행하고 `workspace_info`는 `none`을 광고합니다. +게이트웨이 단위 시험은 macOS에서 실행할 수 있습니다. 그것은 개발 노트북에서 Linux 격리를 검증했다는 주장이 아닙니다. ## compose 픽스처가 하는 일 @@ -60,8 +63,8 @@ P0 UDS는 1:1입니다. 게이트웨이가 워커 자식을 소유합니다(`kil `process_id`는 살아남지 않으며 재연결은 없습니다. 러너 `Replay`는 같은 연결에서만 동작합니다. 그 **전송**은 구현되어 있으며 선택적입니다 (`CODESPACE_RUNNER=uds` / `CODESPACE_RUNTIME_BIN`). **같은 호스트**이며 -Linux 격리를 주장하지 않습니다. 다음 WP는 -linux-sandbox / network이며 두 번째 전송 재작성이 아닙니다. 소켓 +Linux 격리를 주장하지 않습니다. Linux command sandbox는 그 같은 +`InProcessRunner` spawn의 wrap이며 두 번째 전송 재작성이 아닙니다. 소켓 프리미티브로 `codex-uds`를 선호하세요. Runner RPC는 CodeSpace 계약으로 남습니다. @@ -70,9 +73,10 @@ Linux 격리는 여전히 목표 OS입니다. Landlock, seccomp, PTY 헬퍼, UDS 실행 서브그래프를 선호하세요 ([codex-reuse.md](codex-reuse.md)). 단계: process-hardening → PTY → UDS/path → filesystem → linux-sandbox → -network (filesystem은 `crates/file-system`으로 가져옴). -`codex-linux-sandbox`는 컨테이너 옆에 둘 수 있습니다. 그 -`codex-core` **dev-dep**는 제품 그래프에서 빼 두세요. `codex-exec`는 +network (filesystem은 `crates/file-system`, linux-sandbox는 +`crates/linux-sandbox`). `codex-linux-sandbox`는 컨테이너 옆에 둘 수 +있습니다. 그 `codex-core` **dev-dep**는 제품 그래프에서 빼 두세요. +다음 WP는 network(`Enabled` + proxy)입니다. `codex-exec`는 거절된 채로 남습니다. `codex-exec-server`는 참고 / 이후 백엔드이며 영구 거절은 아닙니다. 게이트웨이 정책이 유일한 허용 경로입니다. compose 픽스처에 호스트 Docker 소켓이나 이후 제어 소켓을 실수로 마운트하지 diff --git a/docs/operations.md b/docs/operations.md index 82603a1..dd03f2f 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -27,16 +27,19 @@ to Codex `main`. Product runtime stays out of the gateway; see [codex-reuse.md](codex-reuse.md) and [execution-substrate.md](execution-substrate.md). -Build the gateway and patch helper into the **same** directory so the -gateway can find the helper next to itself (or set `CODESPACE_PATCH_BIN`). +Build the gateway, patch helper, and Linux sandbox helper into the +**same** directory so the gateway can find them next to itself (or set +`CODESPACE_PATCH_BIN` / `CODESPACE_LINUX_SANDBOX_BIN`). The UDS worker is optional (`CODESPACE_RUNTIME_BIN`). ```bash cargo build -p codespace-server --bin codespace-mcp --release cargo build --manifest-path crates/patch/Cargo.toml --bin codespace-patch --release +cargo build --manifest-path crates/linux-sandbox/Cargo.toml --bin codespace-linux-sandbox --release mkdir -p dist cp target/release/codespace-mcp dist/ cp crates/patch/target/release/codespace-patch dist/ +cp crates/linux-sandbox/target/release/codespace-linux-sandbox dist/ # Optional Unix-socket worker (not the default exec path): cargo build --manifest-path crates/codex-runtime/Cargo.toml --bin codespace-codex-runtime --release cp crates/codex-runtime/target/release/codespace-codex-runtime dist/ @@ -49,7 +52,12 @@ binds a private Unix socket with `codex-process-hardening` and `codex-uds`, then runs `InProcessRunner`. Hardening is **worker/helper process** hardening (`pre_main_hardening()` as the first line of `main`; no `ctor`), not a command sandbox. Default `exec_command` still -uses in-process host spawn. `exec_command.tty` defaults to false (pipes). +uses in-process host spawn. On Linux, when +`CODESPACE_LINUX_SANDBOX_BIN` (or `codespace-linux-sandbox` next to the +gateway) probes successfully, that spawn is wrapped by the helper. +`workspace_info.execution.isolation.command_sandbox` is `linux-sandbox` +only then; otherwise `none`. Restricted network is OS-enforced in that +case (`network.enforcement=enforced`). `exec_command.tty` defaults to false (pipes). `tty: true` attaches a PTY at 24x80. Exec DTO cwd is `WorkspaceRoot`; `PATH` / `HOME` / `LANG` are applied inside the runner process (`TERM=xterm` for PTY). @@ -79,8 +87,9 @@ the effective execution contract (`execution`): policy vs backend support, support only; not occupancy — `exec_command` or `apply_patch` may still return `WORKSPACE_BUSY`; tool existence is `tools_exposed`), fixed 24x80 PTY without resize when a process is available, mutation lease / -`WORKSPACE_BUSY`, workspace-scoped file tools vs no command sandbox, and -restricted network policy without OS enforcement. `output_combined=true` means `read_process` exposes one +`WORKSPACE_BUSY`, workspace-scoped file tools vs Linux command sandbox +when advertised, and restricted network policy with OS enforcement when +the helper probe succeeds. `output_combined=true` means `read_process` exposes one combined stream; stdout/stderr identity is not preserved. `exec_command` returns `dispatch_status` (`confirmed` or `unknown`). Treat `unknown` patch/exec as possibly diff --git a/docs/runner-isolation.md b/docs/runner-isolation.md index cf62e03..70c9534 100644 --- a/docs/runner-isolation.md +++ b/docs/runner-isolation.md @@ -3,8 +3,11 @@ [English](runner-isolation.md) | [한국어](ko/runner-isolation.md) **Target** execution isolation OS is a Linux container. **Current** -`exec_command` is a host process (`tokio::process::Command`, workspace -cwd, `env_clear`). Gateway unit tests may run on macOS. That is not a +`exec_command` is a host process. When the Linux helper probe succeeds, +pipe and PTY spawn wrap the same `codespace-linux-sandbox` argv +(bubblewrap + `no_new_privs`/seccomp). When the probe fails (macOS, no +bwrap), spawn is unsandboxed and `workspace_info` advertises `none`. +Gateway unit tests may run on macOS. That is not a claim that Linux isolation was verified on the development laptop. ## What the compose fixture does @@ -61,8 +64,8 @@ disconnect or gateway shutdown kills the worker and host children; `process_id` does not survive; there is no reconnect. Runner `Replay` is same-connection only. That **transport** is implemented; it is opt-in (`CODESPACE_RUNNER=uds` / `CODESPACE_RUNTIME_BIN`) on the -**same host**. It does not claim Linux isolation. Next WPs are -linux-sandbox / network, not a second transport rewrite. +**same host**. Linux command sandbox is a wrap of that same +`InProcessRunner` spawn, not a second transport rewrite. Prefer `codex-uds` as the socket primitive; the Runner RPC stays a CodeSpace contract. @@ -71,9 +74,10 @@ UDS, filesystem mechanics, and network isolation are **not** a default homegrown stack. Prefer upstream execution subgraphs ([codex-reuse.md](codex-reuse.md)), staged process-hardening → PTY → UDS/path → filesystem → linux-sandbox → -network (filesystem is taken via `crates/file-system`). -`codex-linux-sandbox` can sit beside a container; keep its -`codex-core` **dev-dep** out of the product graph. `codex-exec` stays +network (filesystem is taken via `crates/file-system`; linux-sandbox +via `crates/linux-sandbox`). `codex-linux-sandbox` can sit beside a +container; keep its `codex-core` **dev-dep** out of the product graph. +The next WP is network (`Enabled` + proxy). `codex-exec` stays rejected. `codex-exec-server` is a reference / future backend, not a forever reject. Gateway policy remains the only allow path. Do not mount a host Docker socket or a future control socket on the compose diff --git a/docs/translations.json b/docs/translations.json index a759b30..23f632a 100644 --- a/docs/translations.json +++ b/docs/translations.json @@ -91,8 +91,8 @@ "워크스페이스-레지스트리", "이-문서가-검증하지-않는-것" ], - "source_sha256": "02e72a0edc2a1e1d929d2c0f1a78c3484e2d148b09ef3780b5f2f175dd41f53d", - "translation_sha256": "e94807a12e88b144571ed93bb34a1996ec34014da7862cdc8d615507c4e5fd5f" + "source_sha256": "9ad4c4694803215a80725d4c378bfe5b47e560e24423012a40cb04727aa1d555", + "translation_sha256": "c237539880cd54c7c935f209026391d723078fdab7bc252c347bbceb56b2997d" }, { "id": "chatgpt-connector", @@ -179,8 +179,8 @@ "실행-기반", "훅과-스킬" ], - "source_sha256": "58e66aca7d48f430fff8eaa039d218fe9cc83af6c6e5adf268d37f53b5655f93", - "translation_sha256": "0728cc5fc5ea4b0918d1266ac913e7b30761aaebd52003859abd094627b8f3cd" + "source_sha256": "0d9ad287e0278ffefa606404a16845f31fc7759d2a8a80f0db04873651cab54a", + "translation_sha256": "daab7c0bc7e025987e6bc5177eb11b028c28ac0f2b62c7aa579c561354a40fe4" }, { "id": "protocol-compatibility", @@ -274,8 +274,8 @@ "러너-격리", "이후-프로세스-분리" ], - "source_sha256": "0b2fb95715fead2bc3f7fcbb7c1a5658b9f38c24c4786680561a0118228b20a9", - "translation_sha256": "3548bf93890cdce23cf70aabf8854a1f147f2ac1046c4d7c470c97901a84c724" + "source_sha256": "12bc3c8860a7309d0f194e62d77d155192e3aa978d78e9d98bdc43d2eafc45b8", + "translation_sha256": "ebeae315a0231a98d904985a8f3987672274a273e958fc23e2ab774dd68011d7" }, { "id": "error-codes", @@ -342,8 +342,8 @@ "핀-6b9826e의-후보", "핵심-대-어댑터" ], - "source_sha256": "d00aac4e87035a01ababcb1cdf5284934ef2939f4ef0bf869f8b1842aa05ddb0", - "translation_sha256": "d04171321d200aa654a4a0392be7f62c7999f7beacf6109747896a4f7b287238" + "source_sha256": "297049584fa4f28463c61b3192c914ca6e521a293b2a4dc271a9dd6c92d78aa4", + "translation_sha256": "8c5c56114cf330ef5bf1da6ecb6ae89d0837c091b1c0b4e7263d2dcb279a5cbb" }, { "id": "upstream-lock", diff --git a/scripts/check-no-model-deps.sh b/scripts/check-no-model-deps.sh index 8680284..6040a69 100755 --- a/scripts/check-no-model-deps.sh +++ b/scripts/check-no-model-deps.sh @@ -71,6 +71,15 @@ fs_key_allowed() { esac } +# crates/linux-sandbox: helper argv + bwrap/seccomp. Direct keys only. +# Transitive: codex-network-proxy (no direct proxy API). +linux_sandbox_key_allowed() { + case "$1" in + codex-linux-sandbox|codex-sandboxing|codex-protocol|codex-utils-path-uri) return 0 ;; + *) return 1 ;; + esac +} + tmpdir="$(mktemp -d)" trap 'rm -rf "$tmpdir"' EXIT @@ -85,6 +94,7 @@ scan_patch=0 scan_runtime=0 scan_pty=0 scan_fs=0 +scan_linux_sandbox=0 scan_all=0 is_zero_sha() { @@ -110,6 +120,9 @@ want_all() { if [[ -d crates/file-system ]]; then scan_fs=1 fi + if [[ -d crates/linux-sandbox ]]; then + scan_linux_sandbox=1 + fi } base="${SCAN_BASE:-}" @@ -159,6 +172,11 @@ else scan_fs=1 fi ;; + crates/linux-sandbox|crates/linux-sandbox/*) + if [[ -d crates/linux-sandbox ]]; then + scan_linux_sandbox=1 + fi + ;; esac done < <(git diff --name-only "$merge_base"...HEAD) else @@ -177,7 +195,8 @@ if [[ "$scan_all" -eq 0 && "$scan_patch" -eq 0 && "$scan_runtime" -eq 0 && "$scan_pty" -eq 0 && - "$scan_fs" -eq 0 ]]; then + "$scan_fs" -eq 0 && + "$scan_linux_sandbox" -eq 0 ]]; then echo "policy-scan skipped (no core crate or adapter changes)" exit 0 fi @@ -189,7 +208,7 @@ selected=() [[ "$scan_store" -eq 1 ]] && selected+=("store") [[ "$scan_server" -eq 1 ]] && selected+=("server") -echo "policy-scan: crates=${selected[*]:-none} tests=$scan_tests root-manifest=$scan_root_manifest patch=$scan_patch runtime=$scan_runtime pty=$scan_pty fs=$scan_fs" +echo "policy-scan: crates=${selected[*]:-none} tests=$scan_tests root-manifest=$scan_root_manifest patch=$scan_patch runtime=$scan_runtime pty=$scan_pty fs=$scan_fs linux-sandbox=$scan_linux_sandbox" scan_manifest() { local file="$1" @@ -239,6 +258,11 @@ scan_adapter_manifest() { bad+="$line"$'\n' fi ;; + linux-sandbox) + if ! linux_sandbox_key_allowed "$key"; then + bad+="$line"$'\n' + fi + ;; esac done < <(grep -nE '^[[:space:]]*codex-[A-Za-z0-9_-]+[[:space:]]*=' "$file" || true) if [[ -n "$bad" ]]; then @@ -315,6 +339,10 @@ if [[ "$scan_fs" -eq 1 ]]; then launch scan_adapter_manifest crates/file-system/Cargo.toml fs fi +if [[ "$scan_linux_sandbox" -eq 1 ]]; then + launch scan_adapter_manifest crates/linux-sandbox/Cargo.toml linux-sandbox +fi + for pid in "${pids[@]+"${pids[@]}"}"; do wait "$pid" done diff --git a/tests/e2e/flow.rs b/tests/e2e/flow.rs index 7358ee7..3bc61b0 100644 --- a/tests/e2e/flow.rs +++ b/tests/e2e/flow.rs @@ -81,11 +81,19 @@ async fn info_read_patch_exec_flow() { info_body["execution"]["process"]["capabilities"]["tty"]["resize_supported"], false ); - assert_eq!( - info_body["execution"]["isolation"]["command_sandbox"], - "none" - ); - assert_eq!(info_body["execution"]["network"]["enforcement"], "none"); + if codespace_runner::linux_sandbox_available() { + assert_eq!( + info_body["execution"]["isolation"]["command_sandbox"], + "linux-sandbox" + ); + assert_eq!(info_body["execution"]["network"]["enforcement"], "enforced"); + } else { + assert_eq!( + info_body["execution"]["isolation"]["command_sandbox"], + "none" + ); + assert_eq!(info_body["execution"]["network"]["enforcement"], "none"); + } let read = client .call_tool(