docs: Runner Doctor 2026-07-28 scan — B15/B16 fixed, B13 log-aggregator update, A18 new XDG_CONFIG_HOME mode - #6706
Conversation
…or update, A18 new XDG_CONFIG_HOME mode
There was a problem hiding this comment.
Pull request overview
Synchronizes Runner Doctor knowledge for the 2026-07-28 scan.
Changes:
- Marks B15 and B16 fixed.
- Updates B13 firewall-report filtering guidance.
- Adds A18 for ARC/DinD XDG home failures.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/shared/self-hosted-failure-modes.md |
Updates the canonical failure catalog. |
.github/workflows/self-hosted-runner-doctor.md |
Updates the workflow diagnostic playbook. |
.github/agents/self-hosted-runner-doctor.md |
Synchronizes the portable agent copy. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (6)
.github/agents/self-hosted-runner-doctor.md:112
- A18 gives an ineffective workaround and omits the shipped fix. github/gh-aw#47802 says the later export overwrites an
engine.envXDG_CONFIG_HOME, so older versions must overrideHOMEinstead. github/gh-aw#48658 merged on 2026-07-28 and should be documented as the fix; the observed write was directly under/home/runner(/home/runner/tool_state), not necessarily.configor.local.
A18 / github/gh-aw-firewall#6684 — Under `runner.topology: arc-dind`, XDG-respecting tools (Flutter, etc.) fail with `EACCES` writing to `~/.config` or `~/.local` because `XDG_CONFIG_HOME` is set to the stale, root-owned `/home/runner` before `HOME` is updated to the writable `${RUNNER_TEMP}/gh-aw/home` path. **Fix in gh-aw engine:** move `export XDG_CONFIG_HOME="$HOME"` to after `HOME` is reassigned to the writable arc-dind path, or use `export XDG_CONFIG_HOME="${RUNNER_TEMP}/gh-aw/home/.config"` explicitly. **Workaround (unfixed gh-aw):** add `XDG_CONFIG_HOME=${RUNNER_TEMP}/gh-aw/home/.config` to `engine.env` in the AWF config.
.github/agents/self-hosted-runner-doctor.md:208
- A18 gives an ineffective workaround and stale fix status. github/gh-aw#47802 states that the later shell export overwrites an
engine.envXDG_CONFIG_HOMEvalue; the consumer workaround is to setHOMEto the writable literal instead. It also records writes directly under/home/runner(for example/home/runner/tool_state), not specifically.config/.local. github/gh-aw#48658 merged on 2026-07-28 and should be cited as the shipped fix.
| A18 | XDG-respecting tools (Flutter, etc.) fail with `EACCES` / permission errors writing to `~/.config` or `~/.local` under `runner.topology: arc-dind`; the actual write target is `/home/runner/.config` (root-owned) rather than the writable `${RUNNER_TEMP}/gh-aw/home` | The copilot engine entrypoint (`gh-aw` v0.79.8+) emits `export XDG_CONFIG_HOME="$HOME"` before reassigning `HOME` to the writable arc-dind path `${RUNNER_TEMP}/gh-aw/home`. Any XDG-respecting tool sees the stale, unwritable value. User-side `engine.env` overrides also run after this export, making them unreliable. | **Fix in gh-aw engine:** move `export XDG_CONFIG_HOME="$HOME"` to **after** `HOME` is set to `${RUNNER_TEMP}/gh-aw/home`, or use an explicit path `export XDG_CONFIG_HOME="${RUNNER_TEMP}/gh-aw/home/.config"`. Workaround (unfixed gh-aw): add `XDG_CONFIG_HOME=${RUNNER_TEMP}/gh-aw/home/.config` explicitly to `engine.env` in the AWF config. | Inside the arc-dind agent container: `echo "$XDG_CONFIG_HOME"` — if it shows `/home/runner` rather than a path under `$RUNNER_TEMP`, the ordering bug is present; `ls -la /home/runner` — root ownership confirms the mode | github/gh-aw-firewall#6684 |
.github/agents/self-hosted-runner-doctor.md:280
- This lookup does not match the reported symptom. Because
XDG_CONFIG_HOMEitself is/home/runner, github/gh-aw#47802 shows Flutter writing/home/runner/tool_state;.configis only the default when XDG_CONFIG_HOME is unset, and.localis unrelated to XDG_CONFIG_HOME. Match writes under/home/runnerand include the observedtool_stateexample.
| `EACCES` / write failures from XDG-respecting tools (Flutter, etc.) targeting `/home/runner/.config` or `/home/runner/.local` under `runner.topology: arc-dind` | A18 (`XDG_CONFIG_HOME` captured stale root-owned home before `HOME` updated to writable arc-dind path) |
.github/agents/self-hosted-runner-doctor.md:226
- The
Open sub-issuestatus is stale: #6658 merged on 2026-07-27 and added topology-peer rules to the policy manifest, fixing #6652's audit attribution gap. Mark that reporting path fixed (with an upgrade instruction) and keep #6689 as the separate Squid-log aggregation fix.
| B13 | In `--network-isolation` mode, MCP tool calls to topology-attached peers (e.g. `awmg-mcpg`) or to a `difcProxyHost` configured independently of `topologyAttach` return connection errors or are logged as `TCP_DENIED` in Squid's access log; the agent can reach the DIFC proxy host during startup (B5/B12) but individual in-session MCP/HTTP calls to those same hosts fail or produce Squid 403 noise | `buildProxyEnvironment()` assembled `NO_PROXY` from a static list of AWF-internal hosts but did not include (a) `config.topologyAttach` peer hostnames or (b) `config.difcProxyHost`. Proxy-aware clients (Node `undici`, curl) honoured `HTTPS_PROXY` for those hosts; Squid denied them because they are not in the domain allowlist. | **Fixed in AWF (PR github/gh-aw-firewall#6189, merged 2026-07-20):** `config.topologyAttach` peer hostnames are now added to `NO_PROXY`/`no_proxy`. **Fixed in AWF (PR github/gh-aw-firewall#6438, merged 2026-07-20):** `config.difcProxyHost` (stripped of any `:port` suffix) is also added to `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6473, merged 2026-07-21):** Topology peer hostnames and `difcProxyHost` are also auto-added to the Squid ACL allowlist (via `resolveAllowedDomains()`) so that proxy-aware clients that honour `HTTP(S)_PROXY` but ignore `NO_PROXY` are still permitted by Squid. The gating mirrors `buildProxyEnvironment()`: only active when `networkIsolation` is true and the runtime is compose-based (`runtimeUsesComposeAgent()`); microVM backends (sbx) are excluded. Upgrade AWF to the version including github/gh-aw-firewall#6473. **Open sub-issue (github/gh-aw-firewall#6652 / github/gh-aw-firewall#6658):** After github/gh-aw-firewall#6473, topology peer hostnames receive runtime Squid allow rules and traffic is permitted at the network level. However, the Firewall Issue Dispatcher **audit/block report** is generated from the policy manifest rather than the live Squid config; the manifest does not yet include topology-peer entries, so the block report incorrectly flags `awmg-mcpg` as denied. This is a **reporting false positive** — actual traffic is not blocked. The report also incorrectly suggests adding `awmgmcpg` to `network.allowed`, which fails schema validation. Tracked in github/gh-aw-firewall#6658. **Additional fix (PR github/gh-aw-firewall#6689):** `isInternalAwfDomain()` in `src/logs/internal-domain-filter.ts` filters `TCP_DENIED` log entries whose destination is a `172.30.0.0/24` IP or single-label hostname (Docker container names always single-label) from both the runtime `⚠️ Firewall blocked N domain(s)` warning and `awf logs stats/summary` output. Upgrade AWF to the version including github/gh-aw-firewall#6689. | Inspect Squid `access.log` for `TCP_DENIED` entries whose target host is a topology peer or the DIFC proxy host; inside the agent container check `echo $NO_PROXY` — the topology peer and DIFC proxy hostname should appear; inspect Squid `access.log` for `TCP_DENIED` entries for topology peer or DIFC proxy host even after upgrading to AWF with github/gh-aw-firewall#6189/#6438 — present on AWF missing github/gh-aw-firewall#6473; confirm topology hostname appears in generated `squid.conf` as `acl allowed_domains dstdomain .<topology-host>` after github/gh-aw-firewall#6473; if the Firewall Issue Dispatcher block report flags a topology peer after github/gh-aw-firewall#6473, treat it as a reporting false positive (manifest attribution gap; tracked in github/gh-aw-firewall#6658) | github/gh-aw-firewall#6189, github/gh-aw-firewall#6438, github/gh-aw-firewall#6473, github/gh-aw-firewall#6652, github/gh-aw-firewall#6658, github/gh-aw-firewall#6685, github/gh-aw-firewall#6689 |
.github/workflows/shared/self-hosted-failure-modes.md:58
- The probe still says this mount “reproduces the rejection,” but #6655 makes the same command expand the variable before validation. Qualify rejection as old-version behavior and state that patched AWF returns a resolved absolute mount (or the precise undefined-variable error).
| B16 | AWF rejects a `--mount` entry with a non-absolute host path error; the mount spec was defined as `${TERRAFORM_CLI_PATH}/terraform:...` (or similar env-var pattern) but the literal string `${TERRAFORM_CLI_PATH}` reaches AWF's volume validator | The gh-aw compiler wraps `sandbox.agent.mounts` specs containing `${}` references in single quotes in the generated shell invocation. Bash single quotes prevent variable substitution, so the literal variable reference string (e.g. `${TERRAFORM_CLI_PATH}`) reaches AWF's volume validation instead of the resolved absolute path. | **Fixed in AWF (PR github/gh-aw-firewall#6655, merged 2026-07-27):** `expandEnvVarsInMount()` in `src/parsers/volume-parsers.ts` now expands `${VAR_NAME}` and `$VAR_NAME` patterns from `process.env` before path validation. If the variable is undefined, AWF emits a precise error (`Environment variable is not set: ${VAR_NAME}`) rather than a misleading path-absoluteness failure. Upgrade AWF to the version including github/gh-aw-firewall#6655. | Inspect the generated `awf` invocation in the compiled lock file — if mount specs appear in single quotes containing `${...}`, the bug is present. Running `awf ... --mount '${VAR}/path:/dest'` reproduces the rejection. | github/gh-aw-firewall#6649, github/gh-aw-firewall#6655 |
.github/agents/self-hosted-runner-doctor.md:229
- The probe still says this mount “reproduces the rejection,” but #6655 makes the same command expand the variable before validation. Qualify rejection as old-version behavior and state that patched AWF returns a resolved absolute mount (or the precise undefined-variable error).
| B16 | AWF rejects a `--mount` entry with a non-absolute host path error; the mount spec was defined as `${TERRAFORM_CLI_PATH}/terraform:...` (or similar env-var pattern) but the literal string `${TERRAFORM_CLI_PATH}` reaches AWF's volume validator | The gh-aw compiler wraps `sandbox.agent.mounts` specs containing `${}` references in single quotes in the generated shell invocation. Bash single quotes prevent variable substitution, so the literal variable reference string (e.g. `${TERRAFORM_CLI_PATH}`) reaches AWF's volume validation instead of the resolved absolute path. | **Fixed in AWF (PR github/gh-aw-firewall#6655, merged 2026-07-27):** `expandEnvVarsInMount()` in `src/parsers/volume-parsers.ts` now expands `${VAR_NAME}` and `$VAR_NAME` patterns from `process.env` before path validation. If the variable is undefined, AWF emits a precise error (`Environment variable is not set: ${VAR_NAME}`) rather than a misleading path-absoluteness failure. Upgrade AWF to the version including github/gh-aw-firewall#6655. | Inspect the generated `awf` invocation in the compiled lock file — if mount specs appear in single quotes containing `${...}`, the bug is present. Running `awf ... --mount '${VAR}/path:/dest'` reproduces the rejection. | github/gh-aw-firewall#6649, github/gh-aw-firewall#6655 |
- Files reviewed: 3/3 changed files
- Comments generated: 11
- Review effort level: Medium
| | A15 | `[WARN] Rootless artifact permission repair failed for .../sandbox/firewall/logs (exit 1)`; squid log files unreadable after ARC/DinD run; `awf logs summary` returns `Failed to load logs: EACCES` | `fixArtifactPermissionsForRootless()` binds the log directory into a repair container but does not apply `dockerHostPathPrefix` translation to the bind mount source path; the DinD daemon cannot resolve the runner-local path, so `chmod` exits non-zero | **Fixed in PR github/gh-aw-firewall#5963**: `fixArtifactPermissionsForRootless()` now calls `applyHostPathPrefixToVolumes()` so the repair container bind mount is correctly translated for the DinD daemon. Upgrade AWF to the version that includes github/gh-aw-firewall#5963. Workaround (older AWF): run `chmod -R a+rX` inside the squid container before `docker compose down`. | `ls -la <proxy-logs-dir>` after run — files owned by uid 13 (squid) confirm the mode; check AWF logs for `[WARN] Rootless artifact permission repair failed` | github/gh-aw-firewall#5816, github/gh-aw-firewall#5817, github/gh-aw-firewall#5963 | | ||
| | A16 | ARC/DinD with `runner.topology: arc-dind`: custom `--mount` paths (e.g. `${RUNNER_TEMP}/gh-aw:...`) are silently dropped; agent command fails with `node: command not found` or other binary-not-found errors even when the tool is correctly installed and the mount was confirmed daemon-visible | AWF sysroot mount filter (`filterAgentVolumesForSysroot`) was too aggressive: it dropped any mount whose source or target fell under `effectiveHome` (`/home/runner`), incorrectly including daemon-visible workspace paths such as `${RUNNER_TEMP}/gh-aw` (`/home/runner/_work/_temp/...`) | **Fixed in AWF (PR github/gh-aw-firewall#5739)**: filter now only drops dot-directories and the home root; workspace paths under `_work/` now pass through. Upgrade AWF to the version including github/gh-aw-firewall#5739. | Inspect generated agent compose YAML for the expected `--mount` entry; `docker run --rm -v ${RUNNER_TEMP}:${RUNNER_TEMP}:ro alpine ls ${RUNNER_TEMP}` to confirm daemon-visibility | github/gh-aw-firewall#5739 | | ||
| | A17 | On ARC/DinD with `runner.topology: arc-dind`, `--image-tag build-tools=sha256:<digest>` throws `Error: invalid key 'build-tools'`; the sysroot-stage init container image cannot be digest-pinned | `IMAGE_DIGEST_KEYS` in `src/image-tag.ts` does not include `'build-tools'`; `buildSysrootStageService()` constructs the image ref as a template string, bypassing `buildRuntimeImageRef()` entirely | **Fixed in AWF (PR github/gh-aw-firewall#5986)**: `'build-tools'` is now in `IMAGE_DIGEST_KEYS`; `buildSysrootStageService()` accepts `ParsedImageTag` via `SysrootServiceParams` and calls `buildRuntimeImageRef()` instead of a hardcoded template string. Upgrade to the AWF version that includes github/gh-aw-firewall#5986. | `awf --image-tag build-tools=sha256:abc ...` — on a patched version the command succeeds and the sysroot-stage image ref includes the pinned digest (visible in generated compose YAML); on older AWF without the fix the command throws `Error: invalid key 'build-tools'` | github/gh-aw-firewall#5985, github/gh-aw-firewall#5986 | | ||
| | A18 | XDG-respecting tools (Flutter, etc.) fail with `EACCES` / permission errors writing to `~/.config` or `~/.local` under `runner.topology: arc-dind`; the actual write target is `/home/runner/.config` (root-owned) rather than the writable `${RUNNER_TEMP}/gh-aw/home` | The copilot engine entrypoint (`gh-aw` v0.79.8+) emits `export XDG_CONFIG_HOME="$HOME"` before reassigning `HOME` to the writable arc-dind path `${RUNNER_TEMP}/gh-aw/home`. Any XDG-respecting tool sees the stale, unwritable value. User-side `engine.env` overrides also run after this export, making them unreliable. | **Fix in gh-aw engine:** move `export XDG_CONFIG_HOME="$HOME"` to **after** `HOME` is set to `${RUNNER_TEMP}/gh-aw/home`, or use an explicit path `export XDG_CONFIG_HOME="${RUNNER_TEMP}/gh-aw/home/.config"`. Workaround (unfixed gh-aw): add `XDG_CONFIG_HOME=${RUNNER_TEMP}/gh-aw/home/.config` explicitly to `engine.env` in the AWF config. | Inside the arc-dind agent container: `echo "$XDG_CONFIG_HOME"` — if it shows `/home/runner` rather than a path under `$RUNNER_TEMP`, the ordering bug is present; `ls -la /home/runner` — root ownership confirms the mode | github/gh-aw-firewall#6684 | |
| | `EACCES: permission denied, mkdir` on a `/tmp/gh-aw/...` path before containers start (pre-flight) | B8 | | ||
| | `No CA certificates were loaded from the system` inside AWF chroot on RHEL/Fedora/Amazon Linux | B9 | | ||
| | `Error: invalid key 'build-tools'` with `--image-tag build-tools=sha256:...` | A17 | | ||
| | `EACCES` / write failures from XDG-respecting tools (Flutter, etc.) targeting `/home/runner/.config` or `/home/runner/.local` under `runner.topology: arc-dind` | A18 (`XDG_CONFIG_HOME` captured stale root-owned home before `HOME` updated to writable arc-dind path) | |
|
|
||
| A17 / github/gh-aw-firewall#5985, github/gh-aw-firewall#5986 — `build-tools` digest pinning is **fixed** in AWF version including github/gh-aw-firewall#5986. `'build-tools'` is now a valid key for `--image-tag build-tools=sha256:<digest>`. | ||
|
|
||
| A18 / github/gh-aw-firewall#6684 — Under `runner.topology: arc-dind`, XDG-respecting tools (Flutter, etc.) fail with `EACCES` writing to `~/.config` or `~/.local` because `XDG_CONFIG_HOME` is set to the stale, root-owned `/home/runner` before `HOME` is updated to the writable `${RUNNER_TEMP}/gh-aw/home` path. **Fix in gh-aw engine:** move `export XDG_CONFIG_HOME="$HOME"` to after `HOME` is reassigned to the writable arc-dind path, or use `export XDG_CONFIG_HOME="${RUNNER_TEMP}/gh-aw/home/.config"` explicitly. **Workaround (unfixed gh-aw):** add `XDG_CONFIG_HOME=${RUNNER_TEMP}/gh-aw/home/.config` to `engine.env` in the AWF config. |
| - `400 bad request: Authorization header is badly formatted` on `*.ghe.com` with `COPILOT_API_TARGET=api.business.githubcopilot.com` → C8 (platform-type guard short-circuits token-prefix catalog; also check for `COPILOT_PROVIDER_API_KEY=dummy-byok-key-for-offline-mode` sentinel suppressing GitHub-token auth path — fixed in github/gh-aw-firewall#6237) | ||
| - `diagnosis=unknown` (proxy reachable, no connection error) or `reachable-but-api-error` from DIFC probe with `GITHUB_SERVER_URL=*.ghe.com` → C7 (DIFC proxy not enterprise-host-aware) | ||
| - `Error: invalid key 'build-tools'` with `--image-tag build-tools=sha256:...` → A17 (build-tools not in IMAGE_DIGEST_KEYS) | ||
| - `EACCES` / write failures from XDG-respecting tools (Flutter, etc.) targeting `/home/runner/.config` or `/home/runner/.local` under `runner.topology: arc-dind` → A18 (`XDG_CONFIG_HOME` captured stale root-owned home before `HOME` updated to writable arc-dind path) |
| - `SIGSEGV` / `SIGABRT` crash with Claude Code (Bun runtime) under `--container-runtime gvisor`; retries all fail → D7 (JSC JIT incompatible with gVisor W^X restrictions; AWF ≥ github/gh-aw-firewall#6276 auto-injects `BUN_JSC_useJIT=0`; for older AWF pass `--env BUN_JSC_useJIT=0`) | ||
| - `diagnosis=unknown` (proxy reachable, no connection error) or `reachable-but-api-error` from DIFC probe with `GITHUB_SERVER_URL=*.ghe.com` → C7 (DIFC proxy not enterprise-host-aware) | ||
| - `Error: invalid key 'build-tools'` with `--image-tag build-tools=sha256:...` → A17 (build-tools not in IMAGE_DIGEST_KEYS) | ||
| - `EACCES` / write failures from XDG-respecting tools (Flutter, etc.) targeting `/home/runner/.config` or `/home/runner/.local` under `runner.topology: arc-dind` → A18 (`XDG_CONFIG_HOME` captured stale root-owned home before `HOME` updated to writable arc-dind path) |
| B12 / github/gh-aw-firewall#6326, github/gh-aw-firewall#6328 — On ARC/DinD, a topology-attached DIFC proxy addressed by Kubernetes Service name can remain unresolvable from DinD containers even after the ordering fix. `detectDnsResolutionFailure()` now augments the startup error with the unresolved host and recommends using the proxy IP or `dockerd --dns <cluster-dns-ip>`. | ||
|
|
||
| B13 / github/gh-aw-firewall#6189, github/gh-aw-firewall#6438, github/gh-aw-firewall#6473, github/gh-aw-firewall#6652, github/gh-aw-firewall#6658 — In `--network-isolation` mode, MCP tool calls to topology-attached peers or to a `difcProxyHost` were failing because those hosts were not included in `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6189, merged 2026-07-20):** topology peer hostnames are added to `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6438, merged 2026-07-20):** `config.difcProxyHost` (stripped of `:port`) is also added to `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6473, merged 2026-07-21):** topology peer hostnames and `difcProxyHost` are also auto-added to the Squid ACL allowlist. Upgrade to AWF including all three PRs. **Open sub-issue (github/gh-aw-firewall#6652 / github/gh-aw-firewall#6658):** After github/gh-aw-firewall#6473, topology peer hostnames receive runtime Squid allow rules and are not actually blocked; however, the Firewall Issue Dispatcher audit/block report is generated from the policy manifest (not the live Squid config) and does not include topology-peer entries — causing `awmg-mcpg` to appear as denied when traffic is permitted (**reporting false positive**). The report also incorrectly suggests adding `awmgmcpg` to `network.allowed`, which fails schema validation. Tracked in github/gh-aw-firewall#6658. | ||
| B13 / github/gh-aw-firewall#6189, github/gh-aw-firewall#6438, github/gh-aw-firewall#6473, github/gh-aw-firewall#6652, github/gh-aw-firewall#6658, github/gh-aw-firewall#6685, github/gh-aw-firewall#6689 — In `--network-isolation` mode, MCP tool calls to topology-attached peers or to a `difcProxyHost` were failing because those hosts were not included in `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6189, merged 2026-07-20):** topology peer hostnames are added to `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6438, merged 2026-07-20):** `config.difcProxyHost` (stripped of `:port`) is also added to `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6473, merged 2026-07-21):** topology peer hostnames and `difcProxyHost` are also auto-added to the Squid ACL allowlist. Upgrade to AWF including all three PRs. **Open sub-issue (github/gh-aw-firewall#6652 / github/gh-aw-firewall#6658):** After github/gh-aw-firewall#6473, topology peer hostnames receive runtime Squid allow rules and are not actually blocked; however, the Firewall Issue Dispatcher audit/block report is generated from the policy manifest (not the live Squid config) and does not include topology-peer entries — causing `awmg-mcpg` to appear as denied when traffic is permitted (**reporting false positive**). The report also incorrectly suggests adding `awmgmcpg` to `network.allowed`, which fails schema validation. Tracked in github/gh-aw-firewall#6658. **Additional fix (PR github/gh-aw-firewall#6689):** `isInternalAwfDomain()` in `src/logs/internal-domain-filter.ts` filters `TCP_DENIED` log entries whose destination is a `172.30.0.0/24` IP or single-label hostname (Docker container names always single-label) from both the runtime `⚠️ Firewall blocked N domain(s)` warning and `awf logs stats/summary` output. Upgrade AWF to the version including github/gh-aw-firewall#6689. |
| B12 / github/gh-aw-firewall#6326, github/gh-aw-firewall#6328 — On ARC/DinD, a topology-attached DIFC proxy addressed by Kubernetes Service name can remain unresolvable from DinD containers even after the ordering fix. `detectDnsResolutionFailure()` now augments the startup error with the unresolved host and recommends using the proxy IP or `dockerd --dns <cluster-dns-ip>`. | ||
|
|
||
| B13 / github/gh-aw-firewall#6189, github/gh-aw-firewall#6438, github/gh-aw-firewall#6473, github/gh-aw-firewall#6652, github/gh-aw-firewall#6658 — In `--network-isolation` mode, MCP tool calls to topology-attached peers or to a `difcProxyHost` were failing because those hosts were not included in `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6189, merged 2026-07-20):** topology peer hostnames are added to `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6438, merged 2026-07-20):** `config.difcProxyHost` (stripped of `:port`) is also added to `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6473, merged 2026-07-21):** topology peer hostnames and `difcProxyHost` are also auto-added to the Squid ACL allowlist. Upgrade to AWF including all three PRs. **Open sub-issue (github/gh-aw-firewall#6652 / github/gh-aw-firewall#6658):** After github/gh-aw-firewall#6473, topology peer hostnames receive runtime Squid allow rules and are not actually blocked; however, the Firewall Issue Dispatcher audit/block report is generated from the policy manifest (not the live Squid config) and does not include topology-peer entries — causing `awmg-mcpg` to appear as denied when traffic is permitted (**reporting false positive**). The report also incorrectly suggests adding `awmgmcpg` to `network.allowed`, which fails schema validation. Tracked in github/gh-aw-firewall#6658. | ||
| B13 / github/gh-aw-firewall#6189, github/gh-aw-firewall#6438, github/gh-aw-firewall#6473, github/gh-aw-firewall#6652, github/gh-aw-firewall#6658, github/gh-aw-firewall#6685, github/gh-aw-firewall#6689 — In `--network-isolation` mode, MCP tool calls to topology-attached peers or to a `difcProxyHost` were failing because those hosts were not included in `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6189, merged 2026-07-20):** topology peer hostnames are added to `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6438, merged 2026-07-20):** `config.difcProxyHost` (stripped of `:port`) is also added to `NO_PROXY`. **Fixed in AWF (PR github/gh-aw-firewall#6473, merged 2026-07-21):** topology peer hostnames and `difcProxyHost` are also auto-added to the Squid ACL allowlist. Upgrade to AWF including all three PRs. **Open sub-issue (github/gh-aw-firewall#6652 / github/gh-aw-firewall#6658):** After github/gh-aw-firewall#6473, topology peer hostnames receive runtime Squid allow rules and are not actually blocked; however, the Firewall Issue Dispatcher audit/block report is generated from the policy manifest (not the live Squid config) and does not include topology-peer entries — causing `awmg-mcpg` to appear as denied when traffic is permitted (**reporting false positive**). The report also incorrectly suggests adding `awmgmcpg` to `network.allowed`, which fails schema validation. Tracked in github/gh-aw-firewall#6658. **Additional fix (PR github/gh-aw-firewall#6689):** `isInternalAwfDomain()` in `src/logs/internal-domain-filter.ts` filters `TCP_DENIED` log entries whose destination is a `172.30.0.0/24` IP or single-label hostname (Docker container names always single-label) from both the runtime `⚠️ Firewall blocked N domain(s)` warning and `awf logs stats/summary` output. Upgrade AWF to the version including github/gh-aw-firewall#6689. |
| | B14 | After upgrading to AWF including the centralized mount-policy refactor (PR github/gh-aw-firewall#6339), the Copilot CLI agent exits immediately (exit code 1, ~0.5 s, zero stdout/stderr); no network calls are made; the issue appears on Docker and gVisor runtimes but not sbx (which moves files aside rather than overlay-masking them) | PR github/gh-aw-firewall#6339 added `~/.copilot/config.json` to the credential **deny list** with reason *"Copilot CLI persisted auth token"*. This is incorrect: `config.json` contains only experiment flags, first-launch timestamps, and plugin metadata — no token. AWF masks denied files with a **read-only** `/dev/null` bind-mount overlay. The Copilot CLI reads **and atomically rewrites** `config.json` via temp-file + rename at startup; a rename cannot target a bind-mounted path and the overlay is read-only, so the CLI crashes silently. | **Fixed in AWF (PR github/gh-aw-firewall#6374, merged 2026-07-18):** `~/.copilot/config.json` is removed from the credential deny list; the file is bind-mounted read-write as part of the `.copilot` tool subdir (pre-#6339 behaviour). Upgrade to the AWF version including github/gh-aw-firewall#6374. Workaround (older AWF): pass `--keep-containers` and inspect the agent container for `EROFS` or rename errors; downgrade AWF past github/gh-aw-firewall#6339 if unpatched. | `awf ... copilot agent --version` — if it exits 1 with no output in ~0.5 s, confirm AWF version includes github/gh-aw-firewall#6374; inspect agent container logs for `EROFS`/`rename` errors on `~/.copilot/config.json` | github/gh-aw-firewall#6339, github/gh-aw-firewall#6374 | | ||
| | B15 | AWF startup fails with `--network-isolation is not yet supported with --enable-host-access`; happens when `localhost` is in the domain allowlist because the gh-aw compiler auto-enables `--enable-host-access` and also emits `network.isolation: true` + `topologyAttach` | In `src/cli.ts`, `--network-isolation` and `--enable-host-access` are mutually exclusive with no overlap support. The gh-aw compiler (v0.82.x+) does not detect the conflict: it emits `isolation:true` + `topologyAttach` unconditionally while also auto-enabling `--enable-host-access` when `localhost` is in the allowlist. The compiled workflow always fails at runtime. | **Unresolved** (github/gh-aw-firewall#6651 open). Short-term workaround: remove `localhost` from the domain allowlist if topology/isolation is required; or set both `network.isolation: false` **and** `security.legacySecurity: true` in the AWF config if host-access is required — `network.isolation: false` alone is insufficient because `applySecurityMode()` forces isolation back on and clears `enableHostAccess` in default strict mode (`src/commands/validators/security-mode.ts:37-74`). | `awf --network-isolation --enable-host-access ...` — reproduces immediately with `not yet supported` error; check compiler output for both flags being emitted together when `localhost` is in allowlist | github/gh-aw-firewall#6651 | | ||
| | B16 | AWF rejects a `--mount` entry with a non-absolute host path error; the mount spec was defined as `${TERRAFORM_CLI_PATH}/terraform:...` (or similar env-var pattern) but the literal string `${TERRAFORM_CLI_PATH}` reaches AWF's volume validator | The gh-aw compiler wraps `sandbox.agent.mounts` specs containing `${}` references in single quotes in the generated shell invocation. Bash single quotes prevent variable substitution, so the literal variable reference string (e.g. `${TERRAFORM_CLI_PATH}`) reaches AWF's volume validation instead of the resolved absolute path. | **Unresolved** (github/gh-aw-firewall#6649 open). Workaround: replace `${VAR}` references with their literal values in `sandbox.agent.mounts`, or stage the path into a wrapper script that expands before calling AWF. | Inspect the generated `awf` invocation in the compiled lock file — if mount specs appear in single quotes containing `${...}`, the bug is present. Running `awf ... --mount '${VAR}/path:/dest'` reproduces the rejection. | github/gh-aw-firewall#6649 | | ||
| | B15 | AWF startup fails with `--network-isolation is not yet supported with --enable-host-access`; happens when `localhost` is in the domain allowlist because the gh-aw compiler auto-enables `--enable-host-access` and also emits `network.isolation: true` + `topologyAttach` | In `src/cli.ts`, `--network-isolation` and `--enable-host-access` are mutually exclusive with no overlap support. The gh-aw compiler (v0.82.x+) does not detect the conflict: it emits `isolation:true` + `topologyAttach` unconditionally while also auto-enabling `--enable-host-access` when `localhost` is in the allowlist. The compiled workflow always fails at runtime. | **Fixed in AWF (PR github/gh-aw-firewall#6657, merged 2026-07-28):** The mutual-exclusion guard is removed; `--enable-host-access` now coexists with `--network-isolation` in topology mode. In topology mode the agent is on an `internal` Docker network with no host route, so `--enable-host-access` only drives Squid port ACLs and the `host.docker.internal` hosts-file entry — no incompatible iptables changes. `allowHostServicePorts` (iptables-based GitHub Actions services) is still suppressed unconditionally. Upgrade AWF to version including github/gh-aw-firewall#6657. | `awf --network-isolation --enable-host-access ...` — reproduces immediately with `not yet supported` error; check compiler output for both flags being emitted together when `localhost` is in allowlist | github/gh-aw-firewall#6651, github/gh-aw-firewall#6657 | |
| | B14 | After upgrading to AWF including the centralized mount-policy refactor (PR github/gh-aw-firewall#6339), the Copilot CLI agent exits immediately (exit code 1, ~0.5 s, zero stdout/stderr); no network calls are made; the issue appears on Docker and gVisor runtimes but not sbx (which moves files aside rather than overlay-masking them) | PR github/gh-aw-firewall#6339 added `~/.copilot/config.json` to the credential **deny list** with reason *"Copilot CLI persisted auth token"*. This is incorrect: `config.json` contains only experiment flags, first-launch timestamps, and plugin metadata — no token. AWF masks denied files with a **read-only** `/dev/null` bind-mount overlay. The Copilot CLI reads **and atomically rewrites** `config.json` via temp-file + rename at startup; a rename cannot target a bind-mounted path and the overlay is read-only, so the CLI crashes silently. | **Fixed in AWF (PR github/gh-aw-firewall#6374, merged 2026-07-18):** `~/.copilot/config.json` is removed from the credential deny list; the file is bind-mounted read-write as part of the `.copilot` tool subdir (pre-#6339 behaviour). Upgrade to the AWF version including github/gh-aw-firewall#6374. Workaround (older AWF): pass `--keep-containers` and inspect the agent container for `EROFS` or rename errors; downgrade AWF past github/gh-aw-firewall#6339 if unpatched. | `awf ... copilot agent --version` — if it exits 1 with no output in ~0.5 s, confirm AWF version includes github/gh-aw-firewall#6374; inspect agent container logs for `EROFS`/`rename` errors on `~/.copilot/config.json` | github/gh-aw-firewall#6339, github/gh-aw-firewall#6374 | | ||
| | B15 | AWF startup fails with `--network-isolation is not yet supported with --enable-host-access`; happens when `localhost` is in the domain allowlist because the gh-aw compiler auto-enables `--enable-host-access` and also emits `network.isolation: true` + `topologyAttach` | In `src/cli.ts`, `--network-isolation` and `--enable-host-access` are mutually exclusive with no overlap support. The gh-aw compiler (v0.82.x+) does not detect the conflict: it emits `isolation:true` + `topologyAttach` unconditionally while also auto-enabling `--enable-host-access` when `localhost` is in the allowlist. The compiled workflow always fails at runtime. | **Unresolved** (github/gh-aw-firewall#6651 open). Short-term workaround: remove `localhost` from the domain allowlist if topology/isolation is required; or set both `network.isolation: false` **and** `security.legacySecurity: true` in the AWF config if host-access is required — `network.isolation: false` alone is insufficient because `applySecurityMode()` forces isolation back on and clears `enableHostAccess` in default strict mode (`src/commands/validators/security-mode.ts:37-74`). | `awf --network-isolation --enable-host-access ...` — reproduces immediately with `not yet supported` error; check compiler output for both flags being emitted together when `localhost` is in allowlist | github/gh-aw-firewall#6651 | | ||
| | B16 | AWF rejects a `--mount` entry with a non-absolute host path error; the mount spec was defined as `${TERRAFORM_CLI_PATH}/terraform:...` (or similar env-var pattern) but the literal string `${TERRAFORM_CLI_PATH}` reaches AWF's volume validator | The gh-aw compiler wraps `sandbox.agent.mounts` specs containing `${}` references in single quotes in the generated shell invocation. Bash single quotes prevent variable substitution, so the literal variable reference string (e.g. `${TERRAFORM_CLI_PATH}`) reaches AWF's volume validation instead of the resolved absolute path. | **Unresolved** (github/gh-aw-firewall#6649 open). Workaround: replace `${VAR}` references with their literal values in `sandbox.agent.mounts`, or stage the path into a wrapper script that expands before calling AWF. | Inspect the generated `awf` invocation in the compiled lock file — if mount specs appear in single quotes containing `${...}`, the bug is present. Running `awf ... --mount '${VAR}/path:/dest'` reproduces the rejection. | github/gh-aw-firewall#6649 | | ||
| | B15 | AWF startup fails with `--network-isolation is not yet supported with --enable-host-access`; happens when `localhost` is in the domain allowlist because the gh-aw compiler auto-enables `--enable-host-access` and also emits `network.isolation: true` + `topologyAttach` | In `src/cli.ts`, `--network-isolation` and `--enable-host-access` are mutually exclusive with no overlap support. The gh-aw compiler (v0.82.x+) does not detect the conflict: it emits `isolation:true` + `topologyAttach` unconditionally while also auto-enabling `--enable-host-access` when `localhost` is in the allowlist. The compiled workflow always fails at runtime. | **Fixed in AWF (PR github/gh-aw-firewall#6657, merged 2026-07-28):** The mutual-exclusion guard is removed; `--enable-host-access` now coexists with `--network-isolation` in topology mode. In topology mode the agent is on an `internal` Docker network with no host route, so `--enable-host-access` only drives Squid port ACLs and the `host.docker.internal` hosts-file entry — no incompatible iptables changes. `allowHostServicePorts` (iptables-based GitHub Actions services) is still suppressed unconditionally. Upgrade AWF to version including github/gh-aw-firewall#6657. | `awf --network-isolation --enable-host-access ...` — reproduces immediately with `not yet supported` error; check compiler output for both flags being emitted together when `localhost` is in allowlist | github/gh-aw-firewall#6651, github/gh-aw-firewall#6657 | |
| - `⚠️ Firewall blocked N domain(s)` warning lists `awmgmcpg` or `172.30.0.x` as a blocked domain on every run, even with no actual external blocks → B13 (internal MCP gateway traffic counted by log aggregator as denied; fixed in github/gh-aw-firewall#6689 with `isInternalAwfDomain()` filter) | ||
| - `--network-isolation is not yet supported with --enable-host-access` → B15 (compiler auto-emits both flags when `localhost` in allowlist + topology; fixed in github/gh-aw-firewall#6657) | ||
| - AWF rejects `--mount` with "host path must be absolute" and the path visibly contains `${VAR_NAME}` unexpanded → B16 (single-quote wrapping by compiler prevents shell expansion of `${}` in mount specs; fixed in github/gh-aw-firewall#6655) |
|
@copilot Fix the code for all comments in this review thread. When a review comment includes a suggested change, apply the suggestion exactly. Do not make changes beyond what is described in the linked review thread. |
…obe qualification, lock regen
All review comments addressed in commit A18 (in all 3 catalog files + 2 lookup tables each):
B13 (in all 3 files, both paragraph and table-row formats):
B15 + B16 probes (shared file and agents file):
Lock file: |
|
✅ Copilot review passed with no inline comments. @copilot Add the |
|
📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅ |
|
✅ Smoke Gemini completed. All facets verified. 💎 Smoke test check |
|
✅ Contribution Check completed successfully! PR #6706 follows the contribution guidelines in CONTRIBUTING.md based on the pre-fetched context: it is a documentation/catalog sync, the description is clear and references related issues/PRs, and no code or new-file placement concerns are evident. No review comment needed. |
|
✅ Build Test Suite completed successfully! |
|
📰 VERDICT: Smoke Docker Sbx has concluded. All systems operational. This is a developing story. 🎤 |
|
🛡️ Smoke Copilot Network Isolation confirmed the egress allowlist is enforced. ✅ |
|
✅ Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓 |
|
✅ Smoke Claude passed |
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
|
❌ Smoke Copilot BYOK AOAI (Entra) reports failed. AOAI BYOK (Entra) mode investigation needed... |
|
❌ Smoke Copilot BYOK AOAI (api-key) reports failed. AOAI BYOK (api-key) mode investigation needed... |
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded. |
|
✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟 |
|
🚀 Security Guard has started processing this pull request |
✅ Coverage Check PassedOverall Coverage
📁 Per-file Coverage Changes (1 files)
Coverage comparison generated by |
Smoke Test: Claude Engine Validation
Overall result: PASS ✅
|
🔥 Smoke Test Results
Overall: PASS cc
|
🔥 Smoke Test: Copilot Network Isolation
Overall: PASS Thanks Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "example.com"See Network Configuration for more information.
|
Smoke Test: Copilot BYOK (Direct) Mode
Note: Running in direct BYOK mode ( Overall: PARTIAL — BYOK inference path confirmed working; smoke-data step outputs were not resolved (raw template variables in prompt).
|
Smoke Test: Services Connectivity
Overall: FAIL —
|
Gemini Smoke Test Results
Overall status: PASS Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "localhost"See Network Configuration for more information.
|
🔍 Smoke Test: API Proxy OpenTelemetry Tracing
Result: All 5 scenarios passed. OTEL tracing integration is fully implemented with proper span creation, GenAI semantic conventions, parent context propagation via
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — ✅ PASS
|
Chroot Version Comparison Results
Overall: ❌ FAILED — Node.js version mismatch (host
|
🔥 Smoke Test Results — Docker Sbx
Overall: PASS (2/2 functional tests passed)
|
|
Knowledge-base sync for the 2026-07-28 Runner Doctor scan window. Updates the three mirrored catalog files (
shared/self-hosted-failure-modes.md,self-hosted-runner-doctor.md,.github/agents/self-hosted-runner-doctor.md) in lockstep.B15 → Fixed (PR #6657, merged 2026-07-28)
--network-isolation+--enable-host-accessmutual-exclusion guard removed. In topology mode the agent sits on aninternalnetwork with no host route, so--enable-host-accessonly drives Squid port ACLs and thehost.docker.internalhosts-file entry — no iptables conflict.allowHostServicePortsstill suppressed unconditionally. Removed from Known Unresolved list.B16 → Fixed (PR #6655, merged 2026-07-27)
expandEnvVarsInMount()insrc/parsers/volume-parsers.tsnow expands${VAR_NAME}/$VAR_NAMEfromprocess.envbefore path validation. Undefined vars produce a precise error instead of a misleading path-absoluteness failure. Removed from Known Unresolved list.B13 — log-aggregator additional fix (issues #6685, #6670; PR #6689)
Appended
isInternalAwfDomain()fix detail to all B13 entries: filtersTCP_DENIEDentries whose destination is a172.30.0.0/24IP or single-label hostname from both the⚠️ Firewall blocked N domain(s)runtime warning andawf logs stats/summary. Added quick-lookup entry:⚠️ Firewall blocked N domain(s)listsawmgmcpgor172.30.0.xon every runA18 — new failure mode: XDG_CONFIG_HOME stale under arc-dind (issue #6684)
Added new catalog row after A17. The gh-aw engine entrypoint exports
XDG_CONFIG_HOME="$HOME"before reassigningHOMEto${RUNNER_TEMP}/gh-aw/home, leaving XDG-respecting tools (Flutter, etc.) writing to root-owned/home/runner/.config. Workaround: setXDG_CONFIG_HOME=${RUNNER_TEMP}/gh-aw/home/.configinengine.env. Added to error-string quick-lookup table.