From 1160f59cc6e372940df1833f355b9a851a05294c Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Tue, 19 May 2026 09:43:52 +0200 Subject: [PATCH 1/2] fix(ci): drop musl target from fuzz.yml, bust cache key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #168 root cause per smithy's analysis on the issue thread: The "sanitizer is incompatible with statically linked libc" error on fuzz_parse_component / fuzz_resolver_terminates jobs was NOT runner config drift. All 7 rust-cpu runners have identical toolchains and configs. The actual problem: `dtolnay/rust-toolchain@nightly with: targets: x86_64-unknown-linux-musl` installed the musl toolchain target. cargo-fuzz's `--release` reuse path can pick up a musl-built artifact on cache restore, and musl statically links libc which is incompatible with the AddressSanitizer cargo-fuzz injects via `-Z sanitizer=address`. The failure mode then propagates from any runner that happened to receive a musl-contaminated cache key. Fix: - Drop `targets: x86_64-unknown-linux-musl` from the toolchain install step. cargo-fuzz uses the host gnu target by default, which is sanitizer-compatible. - Version-bump the actions/cache key from `${{ runner.os }}-fuzz-` to `${{ runner.os }}-fuzz-v2-` to invalidate ALL existing cache snapshots once, including any that captured musl artifacts. - Document the rationale inline so a future change doesn't reintroduce the targets line without checking. The musl target isn't referenced anywhere else in the repo — verified with `grep -r musl meld-core/ fuzz/` (no matches outside this workflow). Dropping it is a strict simplification. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/fuzz.yml | 24 ++++++++++++++++++++---- CHANGELOG.md | 14 ++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 669d765..7ace677 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -48,10 +48,22 @@ jobs: steps: - uses: actions/checkout@v4 + # Do NOT install the `x86_64-unknown-linux-musl` toolchain target. + # musl statically links libc, which is incompatible with the + # AddressSanitizer that `cargo-fuzz` injects via + # `-Z sanitizer=address`. The build then fails with + # error: sanitizer is incompatible with statically linked libc, + # disable it using `-C target-feature=-crt-static` + # cargo-fuzz's `--release` reuse path can pick up a musl target if + # a stale `fuzz/target/` is restored from cache. We default to the + # host gnu target (no `targets:` line, no `--target` flag on + # `cargo fuzz run`) so the sanitizer stays compatible. + # Inputs here are workflow-static (no untrusted event payloads): + # `matrix.target` is hardcoded in the strategy matrix and + # `runner.os` is GitHub-provided runner metadata. + # See pulseengine/meld#168 for the recurring failure pattern. - name: Install nightly Rust uses: dtolnay/rust-toolchain@nightly - with: - targets: x86_64-unknown-linux-musl - name: Install cargo-fuzz run: cargo install cargo-fuzz --locked @@ -64,8 +76,12 @@ jobs: ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ - key: ${{ runner.os }}-fuzz-${{ matrix.target }}-${{ hashFiles('fuzz/Cargo.toml', 'meld-core/Cargo.toml') }} - restore-keys: ${{ runner.os }}-fuzz-${{ matrix.target }}- + # Cache key version-bumped to `v2-` once to bust any snapshots + # taken while the toolchain still had musl as an extra target + # (#168). Bump again if a future change should invalidate all + # existing caches in lock-step. + key: ${{ runner.os }}-fuzz-v2-${{ matrix.target }}-${{ hashFiles('fuzz/Cargo.toml', 'meld-core/Cargo.toml') }} + restore-keys: ${{ runner.os }}-fuzz-v2-${{ matrix.target }}- - name: Run target for 60 s run: cargo +nightly fuzz run --release "$FUZZ_TARGET" -- -max_total_time=60 diff --git a/CHANGELOG.md b/CHANGELOG.md index e9e0d2e..26c6206 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,20 @@ All notable changes to this project will be documented in this file. 18/19 verified to **19/19 — full coverage**. The advisory missing-bucket is now empty. +- **Fuzz smoke `sanitizer is incompatible with statically linked + libc` recurrence** (`.github/workflows/fuzz.yml`, #168). The + toolchain install was requesting `x86_64-unknown-linux-musl` as + an extra target. cargo-fuzz's `--release` reuse path can pick up + that musl target on cache restore, and musl statically links libc + which is incompatible with the AddressSanitizer cargo-fuzz + injects. The fuzz_parse_component / fuzz_resolver_terminates + failures attributed to runner config-drift (#139 §3) were + actually workflow-side: same failure on the "good" runner-7 once + the musl cache hit. Drops the `targets: x86_64-unknown-linux-musl` + line and version-bumps the `actions/cache` key to `v2-` to + invalidate any contaminated snapshots. Root-cause analysis + contributed by smithy team on the #168 thread. + - **LS-A-9 regression coverage** (`meld-core/src/adapter/fact.rs`). PR fixed the callback-mode `if code == WAIT` branch that silently treated `POLL (3)` as a YIELD fall-through (dropping host-ready From d31880d6751fcc057952863a9337abb3e71902ce Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Tue, 19 May 2026 14:06:12 +0200 Subject: [PATCH 2/2] fix(ci): mythos-auto needs `id-token: write` for OIDC token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the unzip block on rust-cpu runners cleared (#167), PR #169's mythos-auto matrix scan ran far enough to expose a third plumbing issue: ``` error: Error message: Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable at (.../@actions/core/lib/oidc-utils.js:71:27) ... Attempt 3 failed: Could not fetch an OIDC token. Did you remember to add `id-token: write` to your workflow permissions? ``` claude-code-action calls `core.getIDToken()` early in `setupGitHubToken` (entry point: `src/github/token.ts:15`). The OIDC issuer URL is injected as the `ACTIONS_ID_TOKEN_REQUEST_URL` environment variable, but only when the workflow has `permissions.id-token: write`. mythos-auto.yml's permissions block had `contents: read` and `pull-requests: write` but not `id-token: write`. The action retries 3× via its `retryWithBackoff` helper and then aborts before running its prompt. The sticky-comment + label flow then short-circuits and the placeholder-FINDING fallback fires. Adds the permission with an inline comment explaining the requirement. The token is workflow-scoped and signed by GitHub; it does not grant access to anything beyond what the workflow already has. Bundled with the fuzz.yml musl drop on this PR — both are CI workflow plumbing fixes uncovered by the same Tier-5 PR (#169). --- .github/workflows/mythos-auto.yml | 9 +++++++++ CHANGELOG.md | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/.github/workflows/mythos-auto.yml b/.github/workflows/mythos-auto.yml index 87b83ae..423e388 100644 --- a/.github/workflows/mythos-auto.yml +++ b/.github/workflows/mythos-auto.yml @@ -60,6 +60,15 @@ concurrency: permissions: contents: read pull-requests: write + # `id-token: write` lets the action mint an OIDC token from the + # GitHub Actions OIDC issuer. claude-code-action calls + # `core.getIDToken()` (`@actions/core/lib/oidc-utils.js:71`) early in + # `setupGitHubToken`; without this permission the call throws + # "Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable" and the + # action aborts before running its prompt. The token is workflow- + # scoped and signed by GitHub; it does not grant access to anything + # beyond what the workflow already has. + id-token: write jobs: detect: diff --git a/CHANGELOG.md b/CHANGELOG.md index 26c6206..36ffa9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,18 @@ All notable changes to this project will be documented in this file. invalidate any contaminated snapshots. Root-cause analysis contributed by smithy team on the #168 thread. +- **mythos-auto.yml missing `id-token: write` permission** + (`.github/workflows/mythos-auto.yml`). After the unzip block on + rust-cpu runners cleared (#167), the next mythos-auto run + surfaced a third plumbing issue: claude-code-action calls + `core.getIDToken()` early in `setupGitHubToken`, which requires + the OIDC token issuer URL. Without `id-token: write` in + `permissions:`, the action gets "Unable to get + ACTIONS_ID_TOKEN_REQUEST_URL env variable" and aborts before + running its prompt. Adds the permission with an inline comment + explaining the requirement. Discovered by PR #169's matrix scan + on the now-unzip-fixed runner image. + - **LS-A-9 regression coverage** (`meld-core/src/adapter/fact.rs`). PR fixed the callback-mode `if code == WAIT` branch that silently treated `POLL (3)` as a YIELD fall-through (dropping host-ready