Skip to content
Closed
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
10 changes: 10 additions & 0 deletions .github/workflows/trusted-uv-materializer-quality-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,30 @@ on:
paths:
- ".github/workflows/trusted-uv-materializer-quality-ci.yml"
- "scripts/ci/materialize_base_python_requirements.py"
- "scripts/ci/ensure_opencode_asyncio_toolchain.sh"
- "tests/conftest.py"
- "tests/test_materialize*.py"
- "tests/test_trusted_uv*.py"
- "tests/test_uv*.py"
- "tests/test_repository_branch_coverage_*.py"
- "tests/test_opencode_asyncio_toolchain_contract.py"
- "requirements-opencode-review-ci-hashes.txt"
- "requirements-opencode-review-ci.txt"
- "pyproject.toml"
push:
branches: [main]
paths:
- ".github/workflows/trusted-uv-materializer-quality-ci.yml"
- "scripts/ci/materialize_base_python_requirements.py"
- "scripts/ci/ensure_opencode_asyncio_toolchain.sh"
- "tests/conftest.py"
- "tests/test_materialize*.py"
- "tests/test_trusted_uv*.py"
- "tests/test_uv*.py"
- "tests/test_repository_branch_coverage_*.py"
- "tests/test_opencode_asyncio_toolchain_contract.py"
- "requirements-opencode-review-ci-hashes.txt"
- "requirements-opencode-review-ci.txt"
- "pyproject.toml"

concurrency:
Expand Down Expand Up @@ -109,6 +115,9 @@ jobs:
- 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: Verify asyncio coverage toolchain imports
run: bash scripts/ci/ensure_opencode_asyncio_toolchain.sh

- name: Run trusted uv tests with complete branch coverage
run: |
cat >"${RUNNER_TEMP}/trusted-uv-coveragerc" <<'EOF'
Expand Down Expand Up @@ -159,6 +168,7 @@ jobs:
tests/test_uv_redirect_boundary.py \
tests/test_uv_workspace_fail_closed.py \
tests/test_trusted_uv_materializer_quality_workflow_contract.py \
tests/test_opencode_asyncio_toolchain_contract.py \
tests/test_repository_branch_coverage_javascript_and_noema.py \
tests/test_repository_branch_coverage_review_schedulers.py \
tests/test_repository_branch_coverage_execution_sandboxes.py \
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@

Materialize accepts only exact SHA-256 pins or a bounded relative `-r` include (no `.`/`..`); a lone `--require-hashes` directive is not trust evidence. See [`docs/doctoring/hourly-nvidia-nim-autofix.md`](docs/doctoring/hourly-nvidia-nim-autofix.md).
Conflict-scope roots fail closed when the immediate parent directory is a symbolic link.
Coverage sandbox asyncio execution is pinned through `requirements-opencode-review-ci.txt` and `scripts/ci/ensure_opencode_asyncio_toolchain.sh`; quality CI must run that helper after the hash-lock install. Do not rewrite hashed `opencode-review-dispatch.yml` for that import.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop this root ADR edit. #896 already owns AGENTS.md. Record the asyncio boundary in docs/doctoring/opencode-asyncio-test-runtime.md only, as #1060 does.

21 changes: 21 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@ flowchart LR
Products -->|"standalone or as module"| Buyer
```

## Coverage asyncio toolchain

The hash-pinned OpenCode review lock includes `pytest-asyncio==1.4.0`.
`scripts/ci/ensure_opencode_asyncio_toolchain.sh` fail-closed imports that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This root architecture hunk collides with #896. Keep the mermaid and helper-after-lock-install path in doctoring. Prefer #1060, which has the quality-CI execution without this ADR overlap.

plugin after the quality job installs the lock. The independent
review-dispatch workflow remains the hashed review-agent key blob.

```mermaid
flowchart LR
Lock["requirements-opencode-review-ci-hashes.txt"]
Quality["trusted-uv-materializer-quality-ci"]
Helper["ensure_opencode_asyncio_toolchain.sh"]
Image["Coverage image on merge"]
Buyer["Downstream marked asyncio suite"]

Lock --> Quality
Quality --> Helper
Lock --> Image
Image --> Buyer
```

## Hourly NVIDIA NIM repair gate

```mermaid
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Semantic Versioning where the repository publishes a release.

### Added

- Added hash-pinned `pytest-asyncio==1.4.0` and `typing-extensions==4.16.0` plus `scripts/ci/ensure_opencode_asyncio_toolchain.sh` so the coverage sandbox can execute marked asyncio tests without rewriting the hashed review-dispatch workflow.
- Execute that asyncio helper on the hash-locked quality job and collect a marked coroutine the same way a downstream buyer suite does, so an unread helper cannot claim the runtime is present.
- Added a trusted pull-request comment router for `@cwl-noema-review` and review-only `@opencode-agent` dispatches, with an organization sweep, exact-head receipts, repository allowlisting, fixed runners, immutable checkout pins, and a permanent 100% statement/branch/docstring quality gate.
- Added exact-base `uv.lock` materialization that reconstructs standalone nested projects with a checksum-pinned official `uv` exporter, isolated frozen/offline execution, strict exact-pin and SHA-256 output validation, and complete Python 3.10/3.14 quality evidence.
- Added a permanent exact-head contract workflow for the hourly review-repair scheduler, immutable reusable-workflow source, NVIDIA NIM model boundary, credential isolation, and fail-closed unattended-agent permissions.
Expand Down
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ repeatable compile command.
without running the test suite will break CI.
- **100% coverage and 100% docstrings on `scripts/ci/`** are hard gates, not aspirations. New helper
code needs matching tests and docstrings.
- **Asyncio coverage plugin** is pinned in `requirements-opencode-review-ci.txt` and checked by
`scripts/ci/ensure_opencode_asyncio_toolchain.sh` after the quality job installs the
hash lock. Do not edit `opencode-review-dispatch.yml` to carry that import.
- **`pull_request_target` trust boundary.** The required review workflows run the *base branch's*
trusted scripts. A PR that edits the trusted review workflows can fail its own checks until the
base branch catches up; a same-head manual `workflow_dispatch` Strix run may supply review evidence
Expand Down
69 changes: 69 additions & 0 deletions docs/doctoring/opencode-asyncio-test-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# OpenCode coverage sandbox asyncio test runtime

## Decision

Materialize accepts only exact SHA-256 pins or a bounded relative `-r` include; a lone `--require-hashes` line is not lock evidence.

The trusted OpenCode coverage image must execute repository tests that use
`pytest.mark.asyncio`. The pinned review toolchain therefore includes
`pytest-asyncio==1.4.0` and the Python 3.12 audit runtime's
`typing-extensions==4.16.0`. `scripts/ci/ensure_opencode_asyncio_toolchain.sh`
imports `pytest_asyncio` alongside `coverage`, `interrogate`, `pytest`, and
`pytest_cov`. The hashed `opencode-review-dispatch.yml` review-agent blob is
not rewritten to carry that import.

A missing plugin is a coverage-evidence failure. It is not permission to skip
async tests and still claim 100% execution of the repository suite.

The helper is not documentation. After the quality job installs the hash lock,
`trusted-uv-materializer-quality-ci.yml` executes the helper and the contract
suite collects a marked coroutine the same way a downstream buyer suite does.
pytest-asyncio registers through setuptools entry points, so installing the
pin is what makes `pytest.mark.asyncio` collect (Krekel et al., 2026;
Tvrtković, 2026). Keep that execution on the quality path instead of editing
the independent review-agent dispatch blob.

## Why the pin is required

PEP 492 defines native coroutines as first-class Python syntax (Selivanov,
2015). pytest does not run those tests unless an asyncio plugin is installed
in the same isolated image that records coverage. NIST SP 800-218 PW.4.1
requires third-party software to come from expected, trusted sources with
integrity verification (Souppaya et al., 2022). ISO/IEC 25010 treats
functional completeness and testability as product quality characteristics;
an unread helper does not satisfy either (International Organization for
Standardization, 2023). The hash-pinned lock is that source; an untrusted
head cannot replace or omit the plugin.

## Rollback

Rollback requires an independently reviewed change that still executes marked
asyncio tests inside the same isolated coverage image. Removing
`pytest-asyncio` without a replacement plugin reintroduces silent skips.

## Next action

After this lands on protected `main`, rerun coverage on an affected async
consumer such as `ContextualWisdomLab/pg-erd-cloud` and keep the issue open
until that consumer's marked coroutine suite collects under the merged lock.

## References

International Organization for Standardization. (2023). *Systems and software
engineering — Systems and software Quality Requirements and Evaluation
(SQuaRE) — Product quality model* (ISO/IEC 25010:2023).
https://www.iso.org/standard/78176.html

Krekel, H., & pytest-dev team. (2026). *pytest documentation*. pytest-dev.
https://docs.pytest.org/en/stable/

Selivanov, Y. (2015). *Coroutines with async and await syntax* (PEP 492).
Python Software Foundation. https://peps.python.org/pep-0492/

Souppaya, M., Scarfone, K., & Dodson, D. (2022). *Secure Software Development
Framework (SSDF) version 1.1: Recommendations for mitigating the risk of
software vulnerabilities* (NIST Special Publication 800-218). National
Institute of Standards and Technology. https://doi.org/10.6028/NIST.SP.800-218

Tvrtković, T. (2026). *pytest-asyncio 1.4.0*. pytest-dev.
https://pypi.org/project/pytest-asyncio/1.4.0/
Loading
Loading