diff --git a/README.md b/README.md index 532d329..3358582 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,11 @@ exist only in the service-owned clone/push subprocess and are not inherited by Codex turns. The image and Compose capability/security settings let the non-root service create Codex's nested `bwrap` sandbox. They follow Codex's secure devcontainer pattern instead of making the service container privileged. Do not -remove Codex's configured filesystem and network restrictions. +remove Codex's configured filesystem and network restrictions. In particular, +`systempaths=unconfined` removes Docker's outer masked `/proc` subpaths so the +nested user/PID namespace can mount its own procfs. Runtimes such as CoreCLR +require `/proc/self/maps`; Codex still controls visibility through the fresh +procfs and its filesystem policy. ## State and recovery diff --git a/compose.yaml b/compose.yaml index f3b8436..6906c21 100644 --- a/compose.yaml +++ b/compose.yaml @@ -19,6 +19,8 @@ services: security_opt: - seccomp=unconfined - apparmor=unconfined + # Docker's masked /proc paths prevent Codex's user namespace from mounting fresh procfs. + - systempaths=unconfined environment: AGENTCI_GITEA_URL: ${AGENTCI_GITEA_URL:-http://gitea:3000} AGENTCI_BOT_USERNAME: ${AGENTCI_BOT_USERNAME:-agentci} diff --git a/install-scripts/dotnet b/install-scripts/dotnet index 2db526a..0a1e6e6 100644 --- a/install-scripts/dotnet +++ b/install-scripts/dotnet @@ -27,11 +27,13 @@ printf '%s\n' \ "export DOTNET_ROOT='$install_dir'" \ 'export DOTNET_CLI_HOME="${DOTNET_CLI_HOME:-/tmp/agentci-dotnet}"' \ 'export NUGET_PACKAGES="${NUGET_PACKAGES:-/tmp/agentci-nuget/packages}"' \ + 'export NUGET_HTTP_CACHE_PATH="${NUGET_HTTP_CACHE_PATH:-/tmp/agentci-nuget/http-cache}"' \ + 'export HOME="$DOTNET_CLI_HOME"' \ 'export DOTNET_CLI_TELEMETRY_OPTOUT=1' \ 'export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1' \ 'export DOTNET_NOLOGO=1' \ 'export DOTNET_CLI_WORKLOAD_UPDATE_NOTIFY_DISABLE=1' \ - 'mkdir -p "$DOTNET_CLI_HOME" "$NUGET_PACKAGES"' \ + 'mkdir -p "$DOTNET_CLI_HOME" "$NUGET_PACKAGES" "$NUGET_HTTP_CACHE_PATH"' \ "exec '$install_dir/dotnet' \"\$@\"" \ > "$bin_dir/dotnet" chmod 0755 "$bin_dir/dotnet" diff --git a/tests/test_codex.py b/tests/test_codex.py index 4088c91..82b241e 100644 --- a/tests/test_codex.py +++ b/tests/test_codex.py @@ -16,6 +16,14 @@ def test_enables_codegraph_in_shared_codex_config() -> None: assert codegraph["env"]["CODEGRAPH_TELEMETRY"] == "0" +def test_compose_allows_nested_codex_procfs() -> None: + root = Path(__file__).parents[1] + + compose = (root / "compose.yaml").read_text() + + assert "systempaths=unconfined" in compose + + def test_extracts_thread_id_from_jsonl() -> None: output = '\n'.join( [ diff --git a/tests/test_install_scripts.py b/tests/test_install_scripts.py index b1de10d..e7c53be 100644 --- a/tests/test_install_scripts.py +++ b/tests/test_install_scripts.py @@ -7,4 +7,6 @@ def test_dotnet_wrapper_uses_sandbox_writable_runtime_directories() -> None: assert 'DOTNET_CLI_HOME="${DOTNET_CLI_HOME:-/tmp/agentci-dotnet}"' in script assert 'NUGET_PACKAGES="${NUGET_PACKAGES:-/tmp/agentci-nuget/packages}"' in script - assert 'mkdir -p "$DOTNET_CLI_HOME" "$NUGET_PACKAGES"' in script + http_cache = 'NUGET_HTTP_CACHE_PATH="${NUGET_HTTP_CACHE_PATH:-/tmp/agentci-nuget/http-cache}"' + assert http_cache in script + assert 'export HOME="$DOTNET_CLI_HOME"' in script