-
Notifications
You must be signed in to change notification settings - Fork 0
fix(coverage): replace stale LLVM runtime-boundary repair #827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
71c8a19
12f6bf5
368269a
41ea872
a6e3dfd
207cf36
2594c2c
2657580
93aaa61
247582a
077781c
16bd128
08ef6f9
112c8d9
eadd4ab
48603e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| name: OpenCode Rust Coverage Toolchain Quality CI | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - ".github/workflows/opencode-rust-coverage-toolchain-quality-ci.yml" | ||
| - "scripts/ci/ensure_rust_llvm19.sh" | ||
| - "tests/test_opencode_rust_coverage_toolchain_contract.py" | ||
| - "docs/doctoring/opencode-rust-coverage-runtime-boundary.md" | ||
| - "CHANGELOG.md" | ||
|
Comment on lines
+5
to
+10
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This watch list no longer includes Add the dispatch workflow back to |
||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: opencode-rust-coverage-toolchain-quality-${{ github.event.pull_request.number || github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| quality: | ||
| name: quality | ||
| runs-on: ubuntu-24.04 | ||
| timeout-minutes: 15 | ||
| env: | ||
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | ||
| steps: | ||
| - name: Harden runner | ||
| uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 | ||
| with: | ||
| egress-policy: audit | ||
|
|
||
| - name: Checkout exact pull request head | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| ref: ${{ github.event.pull_request.head.sha }} | ||
| fetch-depth: 0 | ||
| persist-credentials: false | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | ||
| with: | ||
| python-version: "3.14" | ||
| cache: pip | ||
| cache-dependency-path: requirements-opencode-review-ci-hashes.txt | ||
|
|
||
| - name: Install exact hash-locked test tooling | ||
| run: >- | ||
| python -m pip install --disable-pip-version-check --require-hashes | ||
| -r requirements-opencode-review-ci-hashes.txt | ||
|
|
||
| - name: Run permanent LLVM runtime-boundary contract | ||
| run: | | ||
| set -euo pipefail | ||
| python -m pytest -q tests/test_opencode_rust_coverage_toolchain_contract.py | ||
| python -m compileall -q tests/test_opencode_rust_coverage_toolchain_contract.py | ||
| git diff --check "${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }}" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| # OpenCode Rust coverage LLVM runtime boundary | ||
|
|
||
| ## Decision | ||
|
|
||
| The trusted OpenCode coverage sandbox binds Rust coverage to the reviewed LLVM | ||
| 19 executables shipped by Debian's `llvm-19` package: | ||
|
|
||
| - `LLVM_COV=/usr/bin/llvm-cov-19` | ||
| - `LLVM_PROFDATA=/usr/bin/llvm-profdata-19` | ||
|
|
||
| These are compatibility and trust-boundary constants, not caller-selectable | ||
| configuration. The reviewed helper `scripts/ci/ensure_rust_llvm19.sh` binds both | ||
| exact paths and fails closed unless the live `LLVM_COV` / `LLVM_PROFDATA` | ||
| values match and are executable before Rust coverage evidence is admitted. The | ||
| independent OpenCode review-dispatch workflow stays byte-for-byte so the | ||
| review-agent key system is not rewritten to carry this runtime check. | ||
|
Comment on lines
+12
to
+16
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This record tells operators the helper is the binding and that Rewrite this as producer-selection (path pin + |
||
|
|
||
| The runtime MUST NOT fall back to unversioned `llvm-cov` or `llvm-profdata`, a | ||
| host-runner tool, a pull-request-selected path, or a dynamically downloaded LLVM | ||
| binary. Missing, changed, or non-executable reviewed paths are coverage-evidence | ||
| failures rather than reasons to measure a different toolchain. | ||
|
|
||
| ## Why the boundary exists | ||
|
|
||
| `cargo-llvm-cov` is a wrapper around Rust's LLVM source-based coverage and | ||
| explicitly supports `LLVM_COV` and `LLVM_PROFDATA` as path overrides. Its | ||
| current project documentation states that the LLVM tools must be compatible | ||
| with the LLVM version used by `rustc`. Allowing ambient `PATH` discovery would | ||
| therefore make a runner-image change capable of silently changing the coverage | ||
| producer. | ||
|
|
||
| Debian bookworm currently publishes the versioned `llvm-19` package from | ||
| `llvm-toolchain-19`; Debian package file inventories expose versioned LLVM 19 | ||
| tool entry points including `llvm-cov-19`. Pinning the reviewed executable names | ||
| inside the image converts that mutable ambient dependency into an explicit | ||
| contract that can be checked before source execution. | ||
|
|
||
| ## Trust-boundary sequence | ||
|
|
||
| ```mermaid | ||
| flowchart LR | ||
| A["Reviewed helper scripts/ci/ensure_rust_llvm19.sh"] --> B["Default LLVM_COV_PATH / LLVM_PROFDATA_PATH"] | ||
| B --> C["Require live LLVM_COV and LLVM_PROFDATA equality"] | ||
| C --> D["Require both paths executable"] | ||
| D --> E["Fail closed before cargo llvm-cov"] | ||
| F["Hashed opencode-review-dispatch.yml"] --> G["Unchanged review-agent key blob"] | ||
| ``` | ||
|
|
||
| Each arrow is fail-closed. A later stage does not repair or broaden an earlier | ||
| stage's failed trust decision. | ||
|
|
||
| ## Security and supply-chain implications | ||
|
|
||
| The reviewed paths are fixed in trusted central workflow source. Pull-request | ||
| content cannot choose an LLVM package, executable path, download origin, or | ||
| runtime environment value. The existing coverage sandbox retains | ||
| `--network=none`, credential/Git isolation, exact-head/base materialization, | ||
| and the separately checksum-pinned `cargo-llvm-cov` archive. | ||
|
|
||
| This binding narrows reproducibility risk but does not by itself attest Debian's | ||
| whole package supply chain or prove a future Rust toolchain is compatible with | ||
| LLVM 19. A future rustc or base-image upgrade must revalidate compatibility and | ||
| update this contract, its tests, and CHANGELOG in one reviewed change rather | ||
| than silently selecting a different binary. | ||
|
|
||
| ## Failure and recovery | ||
|
|
||
| If the image cannot install `llvm-19`, either reviewed executable is missing or | ||
| non-executable, the runtime value differs from the literal reviewed path, or the | ||
| isolated runtime does not receive the values, Rust coverage fails closed before | ||
| `cargo llvm-cov` runs. The operator should identify whether the failure comes | ||
| from Debian package availability, the pinned image/base generation, a central | ||
| workflow regression, or an intentional Rust/LLVM compatibility change. | ||
|
|
||
| Do not work around the failure by removing the exact-value check, using an | ||
| unversioned executable, adding network access to the PR runtime, or accepting a | ||
| host-provided path. A deliberate toolchain migration requires fresh authoritative | ||
| compatibility evidence and the same RED→GREEN exact-head verification sequence. | ||
|
|
||
| ## Verification contract | ||
|
|
||
| `tests/test_opencode_rust_coverage_toolchain_contract.py` proves that: | ||
|
|
||
| 1. the helper defaults both reviewed LLVM 19 executable paths; | ||
| 2. the helper requires live `LLVM_COV` / `LLVM_PROFDATA` equality with those | ||
| paths; | ||
| 3. the helper requires both paths to be executable and exits `1` on mismatch; | ||
| 4. the helper does not mention unversioned `llvm-cov` / `llvm-profdata`; and | ||
| 5. every exact path named by the permanent quality workflow's | ||
| `pull_request.paths` filter resolves to a repository file, including the | ||
| helper, preventing a dangling documentation trigger from becoming | ||
| invisible debt. | ||
|
|
||
| The permanent quality workflow runs on Python 3.14, checks out the exact PR head, | ||
| executes the focused contract, compiles the test, and applies `git diff --check`. | ||
| Repository security and supply-chain workflows remain separate authorities. | ||
|
|
||
| ## References | ||
|
|
||
| Debian Project. (2026). *Package: llvm-19 (1:19.1.7-3~deb12u1), bookworm*. | ||
| Debian Packages. Retrieved August 10, 2026, from | ||
| https://packages.debian.org/bookworm/llvm-19 | ||
|
|
||
| Debian Project. (2026). *File list of package llvm-19*. Debian Packages. | ||
| Retrieved August 10, 2026, from | ||
| https://packages.debian.org/bookworm/amd64/llvm-19/filelist | ||
|
|
||
| Taiki Endo. (2026). *cargo-llvm-cov: Cargo subcommand to use LLVM source-based | ||
| code coverage*. GitHub. Retrieved August 10, 2026, from | ||
| https://github.com/taiki-e/cargo-llvm-cov | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,15 @@ | ||||||||||
| #!/usr/bin/env bash | ||||||||||
| # Fail closed unless the reviewed LLVM 19 coverage tools are bound. | ||||||||||
| set -euo pipefail | ||||||||||
|
|
||||||||||
| LLVM_COV_PATH="${LLVM_COV_PATH:-/usr/bin/llvm-cov-19}" | ||||||||||
| LLVM_PROFDATA_PATH="${LLVM_PROFDATA_PATH:-/usr/bin/llvm-profdata-19}" | ||||||||||
|
Comment on lines
+5
to
+6
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These defaults are caller-selectable. A pull-request or sandbox environment can set The helper is also current-head source, so even a hardcoded version is not the trust boundary. Restore the
Comment on lines
+5
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win LLVM 19 기준 경로를 외부 환경에서 재정의할 수 없게 하세요.
두 경로를 리터럴 상수로 고정하세요. 현재 제안 수정-LLVM_COV_PATH="${LLVM_COV_PATH:-/usr/bin/llvm-cov-19}"
-LLVM_PROFDATA_PATH="${LLVM_PROFDATA_PATH:-/usr/bin/llvm-profdata-19}"
+readonly LLVM_COV_PATH="/usr/bin/llvm-cov-19"
+readonly LLVM_PROFDATA_PATH="/usr/bin/llvm-profdata-19"As per path instructions: 이 helper는 Rust 커버리지의 LLVM 19 경계를 고정해야 합니다. 이 판단은 PR 목표와 제공된 계약 테스트 스니펫을 기준으로 합니다. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI AgentsSource: Path instructions |
||||||||||
|
|
||||||||||
| if [ "${LLVM_COV:-}" != "$LLVM_COV_PATH" ] || | ||||||||||
| [ "${LLVM_PROFDATA:-}" != "$LLVM_PROFDATA_PATH" ] || | ||||||||||
| ! test -x "${LLVM_COV:-}" || | ||||||||||
| ! test -x "${LLVM_PROFDATA:-}"; then | ||||||||||
| printf 'Rust coverage runtime did not preserve reviewed LLVM 19 tool paths (%s, %s).\n' \ | ||||||||||
| "$LLVM_COV_PATH" "$LLVM_PROFDATA_PATH" >&2 | ||||||||||
| exit 1 | ||||||||||
| fi | ||||||||||
Uh oh!
There was an error while loading. Please reload this page.