Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
4e4b99a
ci: stage fail-closed LLVM coverage repair
seonghobae Aug 4, 2026
c28a16f
ci: use bounded app token for workflow repair
seonghobae Aug 4, 2026
2cd3e13
ci(opencode-review): provision LLVM coverage tools
opencode-agent[bot] Aug 4, 2026
08e038d
chore: bootstrap coverage failure diagnostics repair
seonghobae Aug 4, 2026
657e8fe
chore: remove coverage diagnostics bootstrap workflow
seonghobae Aug 4, 2026
1c02958
fix(opencode-review): publish JavaScript lock failure evidence
seonghobae Aug 4, 2026
cb1ed50
fix(opencode-review): publish Python lock failure evidence
seonghobae Aug 4, 2026
b59d2bb
test(opencode-review): cover exact coverage setup diagnostics
seonghobae Aug 4, 2026
94bfa75
ci(opencode-review): verify coverage failure diagnostics
seonghobae Aug 4, 2026
2defa39
test(opencode-review): cover materializer branch contracts
seonghobae Aug 4, 2026
cad711b
ci(opencode-review): separate minimum-runtime and full-quality gates
seonghobae Aug 4, 2026
1fcb790
test(opencode-review): cover absent workspace manifest branch
seonghobae Aug 4, 2026
5bf0fdb
chore: bootstrap Strix security lock refresh
seonghobae Aug 4, 2026
16e438c
ci: run Strix lock refresh from same-repository PR
seonghobae Aug 4, 2026
9b273e0
fix(security): refresh vulnerable Strix dependencies
opencode-agent[bot] Aug 4, 2026
988e10f
ci: verify Strix security lock contract with diagnostics
seonghobae Aug 4, 2026
0165ed7
fix(strix): preserve complete support and Rust scopes (#753)
seonghobae Aug 5, 2026
575aa55
docs(doctoring): trace LLVM coverage toolchain decision
seonghobae Aug 5, 2026
3a31af0
fix(security): apply remediated Strix dependency floors
seonghobae Aug 5, 2026
6610317
ci: refresh PR 755 Strix lock from validated blob
seonghobae Aug 5, 2026
5495d08
fix(security): refresh remediated Strix hash lock
github-actions[bot] Aug 5, 2026
dc81bb8
ci(opencode-review): provision LLVM coverage tools (#755)
seonghobae Aug 5, 2026
c59dd43
fix(ci): align scheduled CodeQL action revision
seonghobae Aug 5, 2026
99ba682
ci: verify and repair early diagnostic redaction
seonghobae Aug 5, 2026
b1720b5
ci: repair early coverage diagnostic redaction
seonghobae Aug 5, 2026
30a40e3
ci: make PR759 redaction repair deterministic
seonghobae Aug 5, 2026
a2efb90
test(ci): reproduce mixed coverage credential leakage
seonghobae Aug 5, 2026
402743e
ci: run PR759 repair on inspectable exact-head event
seonghobae Aug 5, 2026
68f6ad0
test(ci): require mixed credential redaction in materializers
seonghobae Aug 5, 2026
ee42b1f
fix(ci): redact mixed credentials before key truncation
seonghobae Aug 5, 2026
8078137
ci: validate shared coverage sanitizer on exact heads
seonghobae Aug 5, 2026
79e109e
feat(ci): centralize redacted coverage failure envelopes
seonghobae Aug 5, 2026
badbb9a
chore(ci): remove completed PR 759 one-shot workflow
seonghobae Aug 5, 2026
3b61229
chore(ci): remove completed PR 759 repair workflow
seonghobae Aug 5, 2026
df5e5ea
ci: canonicalize PR 759 source repair
seonghobae Aug 5, 2026
8e4adcb
ci: verify shared redaction before diagnostic output
seonghobae Aug 5, 2026
f808953
chore(ci): remove completed PR 759 repair workflow
seonghobae Aug 5, 2026
2315fc0
chore(ci): remove obsolete PR 759 repair workflow
seonghobae Aug 5, 2026
67526be
ci: finalize PR 759 bounded diagnostics
seonghobae Aug 5, 2026
225c14e
test(opencode-review): repair shared diagnostics contract
seonghobae Aug 5, 2026
168b160
chore(ci): remove superseded PR 759 repair workflow
seonghobae Aug 5, 2026
6ae0932
chore(ci): remove obsolete PR 759 repair workflow
seonghobae Aug 5, 2026
66c1094
ci: run bounded PR 759 coverage summary repair
seonghobae Aug 5, 2026
c98fd59
ci: run canonical PR 759 repair
seonghobae Aug 5, 2026
6e4c2d4
fix(opencode-review): centralize redacted diagnostics
github-actions[bot] Aug 5, 2026
21420a9
chore(ci): remove completed PR 759 one-shot workflow
seonghobae Aug 5, 2026
206ab44
test(opencode-review): stage canonical diagnostics repair
seonghobae Aug 5, 2026
c60811f
chore(ci): remove completed PR 759 patch helper
seonghobae Aug 5, 2026
6120297
test(coverage): expose username-only URL userinfo leak
seonghobae Aug 5, 2026
b5a8597
fix(coverage): redact username-only URL userinfo
seonghobae Aug 5, 2026
e1d6e01
fix(strix): freeze source-directory scan boundary
seonghobae Aug 5, 2026
c9ecbe1
test(strix): reject source-directory traversal inputs
seonghobae Aug 5, 2026
c500762
docs(strix): record source-directory trust boundary
seonghobae Aug 5, 2026
76ac1cd
test(strix): reproduce standalone parent traversal
seonghobae Aug 5, 2026
4d076f6
fix(strix): reject standalone parent traversal
seonghobae Aug 5, 2026
050cb25
fix(coverage): keep native fuzz locks out of generic images
seonghobae Aug 5, 2026
5459118
fix(coverage): preserve exact failure diagnostics
seonghobae Aug 5, 2026
66d5a26
docs(coverage): align the integration plan with surviving PRs
seonghobae Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/codeql-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}

- name: Initialize CodeQL
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/init@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/analyze@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
category: "/language:${{ matrix.language }}"
upload: false
Expand Down Expand Up @@ -197,13 +197,13 @@ jobs:
ref: ${{ format('refs/pull/{0}/merge', github.event.pull_request.number) }}

- name: Initialize CodeQL
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/init@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/analyze@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
category: "/language:${{ matrix.language }}-merge"
upload: false
Expand Down
176 changes: 176 additions & 0 deletions .github/workflows/opencode-coverage-diagnostics-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
name: OpenCode Coverage Diagnostics CI

on:
pull_request:
branches: [main]
paths:
- "scripts/ci/coverage_failure_summary.py"
- "scripts/ci/materialize_base_javascript_packages.py"
- "scripts/ci/materialize_base_python_requirements.py"
- "scripts/ci/sanitize_github_output_summary.py"
- "tests/test_materialize_base_javascript_packages.py"
- "tests/test_materialize_base_python_requirements.py"
- "tests/test_coverage_materializer_failure_diagnostics.py"
- "tests/test_coverage_native_fuzz_lock_boundary.py"
- "tests/test_sanitize_github_output_summary.py"
- "tests/test_strix_dependency_security_floor.py"
- "requirements-opencode-review-ci-hashes.txt"
- "requirements-strix-ci.txt"
- "requirements-strix-ci-hashes.txt"
- "pyproject.toml"
- ".github/workflows/opencode-coverage-diagnostics-ci.yml"
push:
branches: [main]
paths:
- "scripts/ci/coverage_failure_summary.py"
- "scripts/ci/materialize_base_javascript_packages.py"
- "scripts/ci/materialize_base_python_requirements.py"
- "scripts/ci/sanitize_github_output_summary.py"
- "tests/test_materialize_base_javascript_packages.py"
- "tests/test_materialize_base_python_requirements.py"
- "tests/test_coverage_materializer_failure_diagnostics.py"
- "tests/test_coverage_native_fuzz_lock_boundary.py"
- "tests/test_sanitize_github_output_summary.py"
- "tests/test_strix_dependency_security_floor.py"
- "requirements-opencode-review-ci-hashes.txt"
- "requirements-strix-ci.txt"
- "requirements-strix-ci-hashes.txt"
- "pyproject.toml"
- ".github/workflows/opencode-coverage-diagnostics-ci.yml"

concurrency:
group: opencode-coverage-diagnostics-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
minimum-python-contract:
name: Python 3.10 runtime contract
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

- name: Checkout exact revision
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Set up minimum supported Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.10"

- name: Compile production modules on Python 3.10
run: |
python -m compileall -q \
scripts/ci/coverage_failure_summary.py \
scripts/ci/materialize_base_javascript_packages.py \
scripts/ci/materialize_base_python_requirements.py \
scripts/ci/sanitize_github_output_summary.py

- name: Exercise exact failure evidence on Python 3.10
run: |
python - <<'PY'
import os
import pathlib
import tempfile

from scripts.ci import materialize_base_javascript_packages as javascript_materializer
from scripts.ci import materialize_base_python_requirements as python_materializer

with tempfile.TemporaryDirectory() as directory:
output = pathlib.Path(directory) / "github-output"
os.environ["GITHUB_OUTPUT"] = str(output)
exact_reason = (
"current-head npm lock package-lock.json package "
"apps/desktop/node_modules/@types/react-dom must pin a registry "
"tarball and SHA-512 integrity"
)
javascript_materializer._publish_coverage_failure_summary(
"Base JavaScript package lock materialization",
ValueError(exact_reason),
"Repair the lock and rerun coverage-evidence.",
)
python_materializer._publish_coverage_failure_summary(
"Base Python lock materialization",
OSError("fixture <unsafe>\nCWL_COVERAGE_SUMMARY_EOF"),
"Repair the trusted lock and rerun coverage-evidence.",
)
published = output.read_text(encoding="utf-8")
assert f"ValueError: {exact_reason}" in published
assert "OSError: fixture &lt;unsafe&gt; CWL_COVERAGE_SUMMARY_END" in published
assert published.count("coverage_summary<<CWL_COVERAGE_SUMMARY_EOF") == 2
PY

full-quality-gate:
name: Python 3.14 full quality gate
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

- name: Checkout exact revision
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Set up current stable 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 hash-locked test tooling
run: >-
python -m pip install --disable-pip-version-check --require-hashes
-r requirements-opencode-review-ci-hashes.txt

- name: Run diagnostics and lock contracts with full branch coverage
run: |
python -m pytest \
tests/test_materialize_base_javascript_packages.py \
tests/test_materialize_base_python_requirements.py \
tests/test_coverage_materializer_failure_diagnostics.py \
tests/test_coverage_native_fuzz_lock_boundary.py \
tests/test_sanitize_github_output_summary.py \
tests/test_strix_dependency_security_floor.py \
--cov=scripts.ci.coverage_failure_summary \
--cov=scripts.ci.materialize_base_javascript_packages \
--cov=scripts.ci.materialize_base_python_requirements \
--cov=scripts.ci.sanitize_github_output_summary \
--cov-branch \
--cov-fail-under=100 \
-q

- name: Enforce complete production docstrings
run: |
python -m interrogate \
--fail-under 100 \
scripts/ci/coverage_failure_summary.py \
scripts/ci/materialize_base_javascript_packages.py \
scripts/ci/materialize_base_python_requirements.py \
scripts/ci/sanitize_github_output_summary.py

- name: Compile changed Python surfaces
run: |
python -m compileall -q \
scripts/ci/coverage_failure_summary.py \
scripts/ci/materialize_base_javascript_packages.py \
scripts/ci/materialize_base_python_requirements.py \
scripts/ci/sanitize_github_output_summary.py \
tests/test_coverage_materializer_failure_diagnostics.py \
tests/test_coverage_native_fuzz_lock_boundary.py \
tests/test_sanitize_github_output_summary.py \
tests/test_strix_dependency_security_floor.py
4 changes: 4 additions & 0 deletions .github/workflows/opencode-review-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -652,11 +652,15 @@ jobs:
r-base \
r-cran-covr \
r-cran-testthat \
llvm-19 \
rustc \
util-linux \
vulkan-tools \
xz-utils \
&& rm -rf /var/lib/apt/lists/*
ENV LLVM_COV=/usr/bin/llvm-cov-19
ENV LLVM_PROFDATA=/usr/bin/llvm-profdata-19
RUN test -x "$LLVM_COV" && test -x "$LLVM_PROFDATA"
RUN curl --proto '=https' --tlsv1.2 -fsSLo /tmp/node-linux-x64.tar.xz \
https://nodejs.org/dist/v24.18.0/node-v24.18.0-linux-x64.tar.xz \
&& echo '55aa7153f9d88f28d765fcdad5ae6945b5c0f98a36881703817e4c450fa76742 /tmp/node-linux-x64.tar.xz' | sha256sum -c - \
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/scheduled-security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ jobs:
with:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/init@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- name: Perform CodeQL Analysis
continue-on-error: true
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/analyze@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
category: "/language:${{ matrix.language }}-scheduled"

Expand Down Expand Up @@ -131,7 +131,7 @@ jobs:
- name: Upload Trivy SARIF to code scanning
if: always() && hashFiles('trivy-results.sarif') != ''
continue-on-error: true
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
uses: github/codeql-action/upload-sarif@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
sarif_file: trivy-results.sarif
category: trivy-fs-scheduled
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Changelog

All notable changes to the ContextualWisdomLab central GitHub control plane are documented in this file.

The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versioned releases follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- Keep the native Atheris fuzz-engine lock in dedicated repository fuzz workflows instead of installing it in the generic OpenCode coverage image; immutable hash-pinned property and regression test locks remain eligible for central coverage materialization.

### Documentation

- Add an APA 7 doctoring record for the generic coverage/native fuzz-engine dependency boundary, exact-base trust model, verification fixture, limitations, and rollback requirements.
27 changes: 27 additions & 0 deletions docs/doctoring/coverage-failure-diagnostics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Credential-redacted coverage failure diagnostics

## Decision

Coverage setup failures are security-relevant review evidence, but exception text is untrusted and may contain registry URL userinfo, authorization headers, API tokens, database connection strings, passwords, or encryption keys. JavaScript and Python trusted-lock materializers therefore delegate multiline `GITHUB_OUTPUT` publication to one shared helper. The helper normalizes whitespace, applies the central credential sanitizer, bounds each field, HTML-escapes Markdown-embedded evidence, and replaces the fixed multiline delimiter before publication.

The sanitizer applies URL-userinfo and authorization-header redaction before key-value truncation so mixed single-line failures cannot preserve an earlier credential. The final output retains the failure class, stage, bounded non-secret context, and remediation without exposing raw credentials. Local CLI status remains nonzero when publication is unavailable.

## Verification contract

The exact-head gate requires Python 3.10 compilation, Python 3.14 tests, 100% production statement and branch coverage, 100% production docstrings, and direct execution of the shared sanitizer CLI contract. Regression cases cover mixed URL, bearer, and token secrets; delimiter injection; oversized errors; missing `GITHUB_OUTPUT`; and both materializer call paths. Temporary write-capable repair workflows are removed from the final tree.

## Standards and guidance

GitHub environment files define delimiter-based multiline outputs and warn that a delimiter must not occur alone within arbitrary values. This implementation delimiter-proofs bounded fields before writing `GITHUB_OUTPUT`. OWASP logging guidance recommends removing, masking, sanitizing, hashing, or encrypting access tokens, passwords, database connection strings, encryption keys, session identifiers, and sensitive personal data rather than recording them directly. RFC 3986 deprecates secret passwords in URI userinfo because URIs are commonly displayed, stored, and logged.

## Limitations

Pattern-based redaction is a defense-in-depth boundary, not a general secret classifier. Callers must not intentionally place secrets in exception messages. GitHub log masking and least-privilege workflow permissions remain required. The diagnostic helper does not make untrusted test output safe for shell evaluation or workflow-command execution.

## References

Berners-Lee, T., Fielding, R., & Masinter, L. (2005). *Uniform resource identifier (URI): Generic syntax* (RFC 3986). Internet Engineering Task Force. https://doi.org/10.17487/RFC3986

GitHub. (2026). *Workflow commands for GitHub Actions*. GitHub Docs. Retrieved August 5, 2026, from https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands

OWASP Foundation. (n.d.). *Logging cheat sheet*. OWASP Cheat Sheet Series. Retrieved August 5, 2026, from https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html
56 changes: 56 additions & 0 deletions docs/doctoring/coverage-native-fuzz-lock-boundary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Generic coverage versus native fuzz-engine lock boundary

## Decision

The central OpenCode coverage image materializes immutable, hash-pinned dependencies needed to import selected production modules and run their ordinary tests. It does not install native coverage-guided fuzz engines that are executed only by dedicated repository fuzz workflows.

`requirements-atheris.txt` is therefore classified as a native fuzz-engine lock and excluded from generic coverage materialization. The classification is exact-name based and path-independent. Hash-pinned property and regression locks such as `requirements-property.txt` and `requirements-fuzz-regression.txt` remain eligible.

## Technical rationale

Atheris is a coverage-guided native Python fuzzer built on libFuzzer. Its runtime role is to instrument and repeatedly execute fuzz targets, not to provide application imports required by an ordinary coverage.py test run. Installing an interpreter- and platform-specific native fuzz runtime in every generic coverage image adds an unrelated native artifact compatibility gate before application coverage begins.

Coverage.py measures execution of Python programs and can report statement and branch coverage for the selected test process without Atheris. The central reviewer therefore preserves two independent verification layers:

1. repository Fuzz workflows install and execute the native fuzz engine against real fuzz targets;
2. central OpenCode coverage evidence installs ordinary import/test dependencies and measures the selected production surface.

Separating these layers avoids converting a native fuzz toolchain mismatch into a source-coverage review failure while retaining both gates.

## Trust boundary

The materializer still reads every candidate only from the exact validated pull-request base commit. Pull-request-mutated dependency files never enter the networked image-build stage. Every included lock must remain hash-pinned, and malformed Git metadata, unsafe paths, non-blob entries, unpinned requirements, and unsafe output destinations remain fail-closed.

The exclusion reduces trusted inputs. It does not introduce an unhashed fallback, download a replacement package, or suppress an application/test import failure. Dedicated Fuzz required workflows continue to install `requirements-atheris.txt` directly.

## Verification evidence

A real temporary Git repository fixture contains:

- `fuzz/requirements-atheris.txt`;
- `fuzz/requirements-property.txt`;
- `services/example_service/requirements-fuzz-regression.txt`.

The test commits these files as the immutable base, materializes that exact revision, and proves that only the property and regression locks appear in the generated manifest. A second contract proves exact-name classification so a substring or directory name cannot broaden the exclusion.

The changed helper and integration path are subject to the central 100% statement, branch, and docstring gates.

## Operational limits

The exact-name set initially contains only `requirements-atheris.txt`. Another native engine must not be added through a wildcard or informal comment. It requires separate artifact-role evidence, a regression fixture, review, and changelog entry.

This boundary does not claim that Atheris is optional for fuzzing. It is optional only for the generic OpenCode import/coverage image. Repositories remain responsible for realistic dedicated fuzz execution and crash-regression evidence.

## Rollback

Rollback removes the exact-name classifier and its fixture. Before rollback, operators must confirm that every supported central coverage interpreter can install every repository's Atheris lock and that doing so provides coverage evidence not already supplied by the dedicated Fuzz workflow. Otherwise rollback recreates the false-negative review condition documented here.

## APA 7 references

Batchelder, N. (2026). *Coverage.py documentation*. https://coverage.readthedocs.io/

Google. (2026). *Atheris: A coverage-guided, native Python fuzzer* [Computer software]. GitHub. https://github.com/google/atheris

Python Packaging Authority. (2026). *Dependency specifiers*. Python Packaging User Guide. https://packaging.python.org/en/latest/specifications/dependency-specifiers/

Semgrep, Inc. (2026). *Sample continuous integration configurations*. https://semgrep.dev/docs/semgrep-ci/sample-ci-configs
Loading
Loading