Skip to content

Mount the configured container working directory when no other mount exposes it - #8021

Merged
lpcox merged 5 commits into
mainfrom
copilot/awf-fix-codex-engine-circuit-breaker
Sep 2, 2026
Merged

Mount the configured container working directory when no other mount exposes it#8021
lpcox merged 5 commits into
mainfrom
copilot/awf-fix-codex-engine-circuit-breaker

Conversation

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

A codex-engine run under AWF aborted after the agent could not cd into /home/runner/work/gh-aw/gh-aw, then re-discovered its context until the context-rebuild circuit breaker tripped. AWF sets the agent CWD from --container-workdir, but nothing guarantees that path exists inside the chroot: if it isn't covered by the workspace mount (derived from GITHUB_WORKSPACE/cwd at AWF launch, which can differ from the requested workdir), /tmp, a system mount, a $HOME tool mount, or an explicit --mount, entrypoint.sh silently falls back to /.

Changes

  • src/services/agent-volumes/workspace-mounts.ts — new buildContainerWorkDirMounts(), called from buildWorkspaceMounts():
    • Emits <workdir>:<workdir>:rw and <workdir>:/host<workdir>:rw when the configured workdir is not already reachable inside the chroot, so the in-container path matches the host path the engine was told to use.
    • No-op when covered by the workspace mount, /tmp, systemDirectories(), a HOME_TOOL_PATHS mount, a custom --mount target, $HOME itself, or /.
    • Refuses to auto-mount (with a warning) paths inside deliberately hidden roots — mount-policy credential paths (~/.ssh, ~/.aws, …) plus /etc, /root, /proc, /run, /boot, /var/run — so --container-workdir ~/.ssh cannot be used to defeat credential hiding. Checked before coverage so a broad tool mount can't shadow the rule.
    • Warns when the directory simply doesn't exist on the host, replacing the silent / fallback with an actionable log line.
  • Tests — unit coverage for mount / skip-when-covered / custom-mount coverage / missing-dir warning / hidden-path refusal; an integration case in tests/integration/container-workdir.test.ts that runs with a workdir outside every default mount (verified failing without the change).
  • docs/usage.md — new "Working Directory" section describing the guarantee and the two warn-only cases.

Sandbox mount surface is unchanged unless a caller explicitly asks for a workdir that AWF was previously unable to provide.

Copilot AI changed the title [WIP] Fix codex engine context-rebuild circuit breaker in AWF sandbox Mount the configured container working directory when no other mount exposes it Sep 2, 2026
Copilot AI requested a review from lpcox September 2, 2026 17:26
@lpcox
lpcox marked this pull request as ready for review September 2, 2026 19:50
Copilot AI balanced review requested due to automatic review settings September 2, 2026 19:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Hidden paths can be exposed through parent-directory mounts or symlink aliases.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds automatic mounting for configured working directories not otherwise visible inside the sandbox.

Changes:

  • Adds workdir mount and safety checks.
  • Adds unit and integration coverage.
  • Documents working-directory behavior.
File summaries
File Description
src/services/agent-volumes/workspace-mounts.ts Builds fallback workdir mounts.
src/services/agent-volumes/workspace-mounts.test.ts Tests mount and refusal behavior.
tests/integration/container-workdir.test.ts Verifies external workdirs end-to-end.
docs/usage.md Documents workdir guarantees and exceptions.
Review details

Suppressed comments (2)

src/services/agent-volumes/workspace-mounts.ts:150

  • This warning is inaccurate when an explicit --mount already exposes the hidden target: the helper declines only the automatic mount, while buildCustomVolumeMounts() still adds the caller's mount and the agent can start there as documented. Avoid claiming that the path will not be mounted or that startup will fall back to /.
      `Container working directory ${workDir} is inside a host path that AWF deliberately hides from ` +
      'the sandbox; it will not be mounted and the agent will start in / instead'

src/services/agent-volumes/workspace-mounts.ts:159

  • statSync follows symlinks, but the hidden-root check only examines the lexical path. A workdir such as /srv/checkout -> /home/runner/.ssh therefore passes validation and the bind source can expose the hidden directory. Resolve the source with realpathSync, apply the hidden-root overlap check to the canonical path, and mount that canonical source so the alias cannot be retargeted between validation and mount construction.
  if (!isExistingDirectory(workDir)) {
  • Files reviewed: 4/4 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/services/agent-volumes/workspace-mounts.ts Outdated
Comment thread src/services/agent-volumes/workspace-mounts.ts Outdated
Comment thread tests/integration/container-workdir.test.ts Outdated
lpcox and others added 2 commits September 2, 2026 14:09
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

✅ Copilot review passed with no inline comments.

@copilot Add the ready-for-aw label to this PR to trigger agentic CI smoke tests.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Documentation Preview

Documentation build failed for this PR. View logs.

Built from commit 2a86b30

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

📰 BREAKING: Report filed by Smoke Copilot

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (Entra) completed. Copilot AOAI BYOK (Entra) mode operational. 🔓

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Docker Sbx has concluded. All systems operational. This is a developing story. 🎤

📰 BREAKING: Report filed by Smoke Docker Sbx

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (api-key) completed. Copilot AOAI BYOK (api-key) mode operational. 🔓

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Gemini reports failed. Facets need polishing...

💎 Faceted by Smoke Gemini

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🛡️ Smoke Copilot Network Isolation confirmed the egress allowlist is enforced. ✅

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • example.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "example.com"

See Network Configuration for more information.

🛡️ Egress verdict from Smoke Copilot Network Isolation

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.

Tested by Smoke Chroot

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅

📡 OTel tracing validated by Smoke OTel Tracing

@lpcox
lpcox deployed to aoai-model September 2, 2026 21:57 — with GitHub Actions Active
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Contribution Check failed. Please review the logs for details.

Generated by Contribution Check for #8021

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Build Test Suite completed successfully!

Generated by Build Test Suite for #8021

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Claude passed

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • api.anthropic.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.anthropic.com"

See Network Configuration for more information.

Generated by Smoke Claude for #8021

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot Engine@lpcox

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Test Results: Copilot BYOK (Direct Mode)

✅ MCP Connectivity — PRs fetched successfully
✅ GitHub.com Connectivity — HTTP 200
✅ File Write/Read — smoke test file readable
✅ BYOK Inference — Running direct BYOK mode (COPILOT_PROVIDER_API_KEY via api-proxy → api.githubcopilot.com)

Overall Status: PASS

Recent merged PRs: #8026, #8004

🔑 BYOK report filed by Smoke Copilot BYOK
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Claude Engine Validation

Check Status
API ✅ PASS
gh CLI ✅ PASS
File ✅ PASS

Overall result: PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • api.anthropic.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.anthropic.com"

See Network Configuration for more information.

Generated by Smoke Claude for #8021 · claude · haiku45 · 58.4 AIC · ⊞ 4.5K ·
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Services Connectivity

  • Redis PING: ❌ (Temporary failure in name resolution)
  • Postgres pg_isready: ❌ (no response)
  • Postgres SELECT 1: ❌ (could not translate host name)

Overall: FAILhost.docker.internal could not be resolved from the sandbox.

🔌 Service connectivity validated by Smoke Services
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Docker Sbx@Copilot @lpcox

Overall: PASS

📰 BREAKING: Report filed by Smoke Docker Sbx
Add label ready-for-aw to run again

@lpcox
lpcox deployed to aoai-model September 2, 2026 22:02 — with GitHub Actions Active
@github-actions github-actions Bot added the smoke-copilot-network-isolation Copilot network-isolation egress smoke test label Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

EGRESS_RESULT allow=pass deny=pass

✅ Allowed domain (github.com) reachable: allowed=200
✅ Non-allowed domain (example.com) blocked: denied=000 (CONNECT tunnel failed, 403)

Overall status: PASS

@lpcox

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • example.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "example.com"

See Network Configuration for more information.

🛡️ Egress verdict from Smoke Copilot Network Isolation
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

@Copilot @lpcox
PR #8026: test: validate shared-gateway enclave smoke
PR #8004: chore: upgrade gh-aw workflows to v0.88.0

GitHub MCP connectivity: ❌
GitHub.com connectivity: ✅
File write/read: ✅
BYOK inference: ✅

Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw)
Status: FAIL

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.14 Python 3.12.14 ✅ YES
Node.js v24.20.0 v2.98.0 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Overall: FAILED — Node.js version mismatch between host and chroot environment. smoke-chroot label not added since not all tests passed.

Tested by Smoke Chroot
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke test: FAIL

Merged PR titles: safeinputs-gh unavailable; local fallback title: chore: upgrade gh-aw workflows to v0.88.0 (#8004)
GitHub MCP review: ❌
safeinputs-gh PR query: ❌
Playwright GitHub title: ✅
Temp file + cat: ✅
Discussion query/comment: ❌ skipped
Build (npm ci && npm run build): ✅
Overall: FAIL

Warning

Firewall blocked 7 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • msfeed25.pkgs.visualstudio.com
  • www.google.com
  • www.gstatic.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "msfeed25.pkgs.visualstudio.com"
    - "www.google.com"
    - "www.gstatic.com"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

@lpcox

test: validate shared-gateway enclave smoke, chore: upgrade gh-aw workflows to v0.88.0 — ❌
GitHub.com Connectivity — ✅
File Write/Read Test — ✅
BYOK Inference Test — ✅

Running in direct BYOK mode (AWF_AUTH_TYPE=github-oidc + AWF_AUTH_AZURE_* + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) authenticated via Microsoft Entra
Overall status: FAIL

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: API Proxy OpenTelemetry Tracing — Results

  • Scenario 1 (Module Loading): otel.js loads successfully. isEnabled()true. Exports: startRequestSpan, setTokenAttributes, setBudgetAttributes, endSpan, endSpanError, shutdown, isEnabled, _provider, _ProxyAwareOtlpExporter, _FileSpanExporter, _FanOutSpanExporter, _parseEndpoints, _parseOtlpHeaders, _buildResourceSpans, _createOtlpWorkloadIdentity.
  • Scenario 2 (Test Suite): npx jest --testPathPatterns=otel → 3 test suites, 68/68 tests passed (0 failed).
  • Scenario 3 (Env Var Forwarding): env-passthrough.ts forwards GITHUB_AW_OTEL_TRACE_ID and GITHUB_AW_OTEL_PARENT_SPAN_ID; api-proxy-env-config.ts forwards GH_AW_OTLP_ENDPOINTS, OTEL_EXPORTER_OTLP_ENDPOINT, plus the trace/parent-span IDs.
  • Scenario 4 (Token Tracker Integration): token-tracker-http.js contains the onUsage callback (OTEL hook point).
  • ⚠️ Scenario 5 (OTEL Diagnostics): Workflow-level trace export to /tmp/gh-aw/otel.jsonl is present (root gh-aw.agent.setup span found). However, no otel.jsonl was found under /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/ — expected, since no LLM API calls were routed through the api-proxy sidecar during this run (no spans to export from that component).

Overall: 4/5 scenarios pass; Scenario 5 is expected-pending (no api-proxy traffic occurred in this run).

📡 OTel tracing validated by Smoke OTel Tracing
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color pass ✅ PASS
Go env pass ✅ PASS
Go uuid pass ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx pass ✅ PASS
Node.js execa pass ✅ PASS
Node.js p-limit pass ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — PASS

Notes:

  • Java: default ~/.m2 was root-owned and not writable, so builds used -Dmaven.repo.local=<tmp path> as a local override; both gson and caffeine compiled and tested successfully via the Squid HTTP/HTTPS proxy.
  • All other ecosystems (Bun, C++, Deno, .NET, Go, Node.js, Rust) built/tested successfully with no network or proxy issues.

Generated by Build Test Suite for #8021 · copilot · auto · 75.6 AIC · ⊞ 12K ·
Add label ready-for-aw to run again

@lpcox
lpcox merged commit fda7a1c into main Sep 2, 2026
180 of 184 checks passed
@lpcox
lpcox deleted the copilot/awf-fix-codex-engine-circuit-breaker branch September 2, 2026 23:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[awf] codex engine: context-rebuild circuit breaker trips under AWF sandbox, aborting task as incomplete

3 participants