Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: OpenCode Coverage Artifact Rerun Quality CI

on:
pull_request:
branches: [main]
paths:
- ".github/workflows/opencode-review-dispatch.yml"
- ".github/workflows/opencode-coverage-artifact-rerun-quality-ci.yml"
- "tests/test_opencode_coverage_artifact_rerun_contract.py"
- "docs/doctoring/opencode-coverage-artifact-reruns.md"
- "CHANGELOG.md"
- "requirements-opencode-review-ci-hashes.txt"
- "pyproject.toml"
push:
branches: [main]
paths:
- ".github/workflows/opencode-review-dispatch.yml"
- ".github/workflows/opencode-coverage-artifact-rerun-quality-ci.yml"
- "tests/test_opencode_coverage_artifact_rerun_contract.py"
- "docs/doctoring/opencode-coverage-artifact-reruns.md"
- "CHANGELOG.md"
- "requirements-opencode-review-ci-hashes.txt"
- "pyproject.toml"

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

permissions:
contents: read

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
exact-head-contract:
name: Python 3.14 attempt-scoped artifact contract
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

- name: Checkout exact source
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 quality tooling
run: python -m pip install --disable-pip-version-check --require-hashes -r requirements-opencode-review-ci-hashes.txt

- name: Run attempt-scoped artifact regression
run: python -m pytest tests/test_opencode_coverage_artifact_rerun_contract.py -q

- name: Enforce complete central test and branch coverage
run: |
set -euo pipefail
python -m coverage erase
python -m coverage run -m pytest tests -q
python -m coverage report --show-missing

- name: Enforce production docstring coverage
run: python -m interrogate scripts/ci

- name: Compile permanent contracts
run: python -m compileall -q scripts tests

- name: Reject uncommitted generated state
run: git diff --exit-code --check && test -z "$(git status --porcelain)"
64 changes: 60 additions & 4 deletions .github/workflows/opencode-review-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@ jobs:
permissions:
contents: read
id-token: write
outputs:
coverage_source_artifact_id: ${{ steps.coverage_source_upload.outputs.artifact-id }}
coverage_source_run_attempt: ${{ steps.coverage_source_attempt.outputs.run_attempt }}
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
steps:
Expand Down Expand Up @@ -349,10 +352,23 @@ jobs:
git -C "$COVERAGE_SOURCE_WORKDIR" status --short
tar -cf "$COVERAGE_SOURCE_ARCHIVE" -C "$COVERAGE_SOURCE_WORKDIR" .

- name: Record coverage source workflow attempt
id: coverage_source_attempt
env:
GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }}
shell: bash --noprofile --norc -e -o pipefail {0}
run: |
if ! [[ "$GITHUB_RUN_ATTEMPT" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::Coverage producer workflow attempt is not a positive integer."
exit 1
fi
printf 'run_attempt=%s\n' "$GITHUB_RUN_ATTEMPT" >>"$GITHUB_OUTPUT"

- name: Upload materialized pull request merge tree
id: coverage_source_upload
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: opencode-coverage-source
name: opencode-coverage-source-${{ github.run_attempt }}
path: ${{ runner.temp }}/opencode-coverage-source.tar
if-no-files-found: error
retention-days: 1
Expand Down Expand Up @@ -431,14 +447,54 @@ jobs:
if: needs.coverage-source-tree.result != 'success'
run: |
echo "::error::Coverage source tree could not be materialized; see the coverage-source-tree job log for the exact target repository, base SHA, head SHA, and fetch or merge failure."
exit 1
# Continue to the unified current-attempt recovery gate for bounded fail-closed guidance.

- name: Verify coverage source identity for current workflow attempt
if: always()
id: coverage_source_identity
continue-on-error: true
env:
COVERAGE_SOURCE_ARTIFACT_ID: ${{ needs.coverage-source-tree.outputs.coverage_source_artifact_id }}
COVERAGE_SOURCE_RUN_ATTEMPT: ${{ needs.coverage-source-tree.outputs.coverage_source_run_attempt }}
CURRENT_RUN_ATTEMPT: ${{ github.run_attempt }}
shell: bash --noprofile --norc -e -o pipefail {0}
run: |
if ! [[ "$CURRENT_RUN_ATTEMPT" =~ ^[1-9][0-9]*$ ]] || \
[ "$COVERAGE_SOURCE_RUN_ATTEMPT" != "$CURRENT_RUN_ATTEMPT" ]; then
echo "::error::Coverage source was not produced in current workflow attempt ${CURRENT_RUN_ATTEMPT:-missing}; producer attempt=${COVERAGE_SOURCE_RUN_ATTEMPT:-missing}."
echo "::error::Use a full rerun or a fresh repository dispatch; failed-jobs-only reruns cannot reuse prior-attempt source evidence."
exit 1
fi
if ! [[ "$COVERAGE_SOURCE_ARTIFACT_ID" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::Coverage source artifact ID is missing or malformed for current workflow attempt."
echo "::error::Use a full rerun or a fresh repository dispatch so the producer publishes current-attempt evidence."
exit 1
fi
artifact_id=$COVERAGE_SOURCE_ARTIFACT_ID
printf 'artifact_id=%s\n' "$artifact_id" >>"$GITHUB_OUTPUT"

- name: Download materialized pull request merge tree
- name: Download current-attempt materialized pull request merge tree
if: >-
always()
&& needs.coverage-source-tree.result == 'success'
&& steps.coverage_source_identity.outcome == 'success'
id: coverage_source_download
continue-on-error: true
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: opencode-coverage-source
artifact-ids: ${{ steps.coverage_source_identity.outputs.artifact_id }}
path: ${{ runner.temp }}/opencode-coverage-artifact

- name: Report missing current-attempt coverage source
if: always() && (needs.coverage-source-tree.result != 'success' || steps.coverage_source_identity.outcome != 'success' || steps.coverage_source_download.outcome != 'success')
env:
GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }}
run: |
set -euo pipefail
echo "::error::Coverage source evidence is unavailable for workflow run attempt ${GITHUB_RUN_ATTEMPT}; a failed-jobs-only rerun cannot safely reconstruct or reuse source evidence from another attempt."
echo "::error::Use a full rerun or a fresh repository dispatch so coverage-source-tree uploads exact current-attempt evidence."
exit 1

- name: Prepare pull request merge tree for coverage measurement
env:
COVERAGE_SOURCE_ARCHIVE: ${{ runner.temp }}/opencode-coverage-artifact/opencode-coverage-source.tar
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pr-review-autofix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ jobs:
conflicted_paths_file="${RUNNER_TEMP}/opencode-conflicted-files.zlist"
conflict_scope_snapshot="${RUNNER_TEMP}/opencode-conflict-workspace-before.json"
git diff --name-only -z --diff-filter=U >"$conflicted_paths_file"
sha256sum "$conflicted_paths_file" | awk '{print $1}' >"${conflicted_paths_file}.sha256"
python3 "$GITHUB_WORKSPACE/trusted-autofix-source/scripts/ci/pr_review_conflict_scope.py" snapshot \
--root "$TARGET_WORKSPACE" \
--output "$conflict_scope_snapshot"
Expand Down
27 changes: 19 additions & 8 deletions .github/workflows/strix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -867,16 +867,27 @@ jobs:

# Recognized signals that the LLM backend was unavailable / starved.
backend_unavailable_signal='RateLimitError|Too many requests\. For more on scraping GitHub|exceeded your current quota|insufficient_quota|billing details|"status"[[:space:]]*:[[:space:]]*"RESOURCE_EXHAUSTED"|tokens_limit_reached|Request body too large|Max size:[[:space:]]*[0-9]+[[:space:]]+tokens|Error code:[[:space:]]*413|LLM CONNECTION FAILED|Could not establish connection to the language model|LLM warm-up failed|Configured model and fallback models were unavailable|Configured Vertex model and fallback models were unavailable|emitted provider infrastructure or failure-signal output|before provider infrastructure failure|litellm(\.exceptions)?\.NotFoundError[^[:cntrl:]]*Nvidia_nimException[^[:cntrl:]]*Error code:[[:space:]]*404'
# Any evidence that a vulnerability was actually reported. Its presence
# forces a hard failure so real findings are NEVER downgraded. Keep the
# severity branch anchored away from identifiers so environment lines
# such as STRIX_FAIL_ON_MIN_SEVERITY do not look like findings.
reported_vulnerability_signal='Vulnerabilities[[:space:]]+[1-9]|(^|[^A-Za-z0-9_])severity[[:space:]]*:'
# Only medium-or-higher findings are blocking evidence. Low and INFO
# reports are retained as artifacts but do not block merge progress;
# the configured Strix threshold is MEDIUM. Keep the severity branch
# anchored away from identifiers such as STRIX_FAIL_ON_MIN_SEVERITY.
reported_vulnerability_signal='(^|[^A-Za-z0-9_])severity[[:space:]]*:[[:space:]]*(critical|high|medium)([^A-Za-z0-9_]|$)'

# Workflow-only callers can legitimately produce an informational
# "no assessable application code" report. It is not a vulnerability
# signal and must remain neutral unless a medium-or-higher finding is
# also present in the same run.
non_assessable_scope_signal='No Assessable Application Code Found in Scope'
if grep -Eiq "$non_assessable_scope_signal" "$strix_run_log" \
&& ! grep -Eiq "$reported_vulnerability_signal" "$strix_run_log"; then
echo "::warning title=Strix scope not assessable::Strix received workflow-only scope and produced no medium-or-higher vulnerability evidence; treating the informational scope result as neutral."
exit 0
fi

# Neutral skip only when ALL hold: a backend-unavailability signal is
# present and no vulnerability was reported anywhere. This preserves
# real security gating while keeping uncontrollable provider outages
# from blocking current-head merge progress.
# present and no medium-or-higher vulnerability was reported. This
# preserves real security gating while keeping uncontrollable provider
# outages from blocking current-head merge progress.
if grep -Eiq "$backend_unavailable_signal" "$strix_run_log" \
&& ! grep -Eiq "$reported_vulnerability_signal" "$strix_run_log"; then
echo "::warning title=Strix backend unavailable::Strix could not complete because its LLM backend was unavailable (rate limit / token cap / connection or warm-up failure) before producing a vulnerability report. Treating as a neutral skip so an infrastructure outage does not block merges; genuine findings still fail the check. See the strix-reports artifact and the run log."
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ Semantic Versioning where the repository publishes a release.

### Fixed

- Added a direct regression contract for Vertex custom-model resource paths and a filterable Strix harness case, so model normalization can be reproduced independently of the full scenario order.
- Documented GitHubClient initialization so the attempt-scoped artifact quality workflow reaches the repository-wide 100% docstring contract on every current head.
- Bound OpenCode coverage source evidence to a validated immutable artifact ID and producer-attested workflow attempt, retained one-day source evidence, and made selective reruns fail closed before download on missing, malformed, or prior-attempt identity with full-rerun or fresh-dispatch guidance.
- Materialized base Python locks only when every package line is an exact SHA-256 pin or a bounded relative `-r`/`--requirement` include. A lone `--require-hashes` directive, a dotted include such as `./lock.txt`, or `-r other-hashes.txt` no longer enters the trusted build context.
- Parsed `opencode.jsonc` as JSONC (stripping `//` and `/* */` comments outside string literals) in the reasoning-effort guard and its contract tests, instead of raw `json.loads`, which rejected the file the moment it carried its first explanatory comment (added for the `contextual-orchestrator` provider block) with `Expecting property name enclosed in double quotes`. Comment markers inside string values, such as the `$schema` URL, are left untouched.
- Download the pinned `uv` 0.12.1 exporter from the official GitHub Releases URL instead of `releases.astral.sh`, which now returns HTTP 403 and blocks org-wide OpenCode `coverage-evidence`. The SHA-256 pin is unchanged. The opener may follow one hop onto `release-assets.githubusercontent.com` or `objects.githubusercontent.com` and still rejects every other host, userinfo, non-HTTPS scheme, and nondefault port (ContextualWisdomLab/.github#1109).
- Compared the trusted `uv` executable's post-install `--version` output against the real GitHub Releases build's full string, `uv 0.12.1 (x86_64-unknown-linux-gnu)`, instead of the bare `uv 0.12.1` the prior check required; the genuine release binary always prints the target triple, so every installation was failing the pin check immediately after the archive download itself was fixed (ContextualWisdomLab/.github#1109).
Expand Down
Loading
Loading