Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
71 changes: 54 additions & 17 deletions .github/workflows/opencode-review-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,20 @@ jobs:
package.json >/dev/null 2>&1
}

javascript_coverage_provider_declared() {
if javascript_test_script_collects_coverage; then
return 0
fi
jq -e '
((.devDependencies // {}) + (.dependencies // {}))
| has("@vitest/coverage-v8")
or has("@vitest/coverage-istanbul")
or has("c8")
or has("nyc")
or has("istanbul")
Comment thread
seonghobae marked this conversation as resolved.
Resolved
' package.json >/dev/null 2>&1
}

declared_package_manager() {
if [ -f package.json ]; then
jq -r '.packageManager // "" | split("@")[0]' package.json 2>/dev/null || true
Expand Down Expand Up @@ -1514,13 +1528,23 @@ jobs:
pnpm)
trusted_pnpm_lock_matches_base
prepare_writable_pnpm_store
Comment thread
seonghobae marked this conversation as resolved.
Resolved
run_and_capture "JavaScript/TypeScript dependencies (pnpm offline install, lifecycle hooks disabled)" \
corepack pnpm install \
--offline \
--frozen-lockfile \
--trust-lockfile \
--ignore-scripts \
--store-dir "$writable_pnpm_store_dir"
pnpm_major="$(corepack pnpm --version | cut -d. -f1 || printf '0')"
Comment thread
seonghobae marked this conversation as resolved.
Resolved
if [ "$pnpm_major" -ge 10 ] 2>/dev/null; then
Comment thread
seonghobae marked this conversation as resolved.
Resolved
Comment thread
seonghobae marked this conversation as resolved.
Resolved
run_and_capture "JavaScript/TypeScript dependencies (pnpm offline install, lifecycle hooks disabled)" \
corepack pnpm install \
--offline \
--frozen-lockfile \
--trust-lockfile \
--ignore-scripts \
--store-dir "$writable_pnpm_store_dir"
else
run_and_capture "JavaScript/TypeScript dependencies (pnpm offline install, lifecycle hooks disabled)" \
corepack pnpm install \
--offline \
--frozen-lockfile \
--ignore-scripts \
--store-dir "$writable_pnpm_store_dir"
fi
;;
yarn)
run_and_capture "JavaScript/TypeScript dependencies (yarn install, lifecycle hooks disabled)" yarn install --immutable --mode=skip-builds
Expand Down Expand Up @@ -2023,20 +2047,33 @@ jobs:
run_package_script_and_capture "JavaScript/TypeScript coverage script" "$package_runner" coverage
javascript_coverage_ran=1
elif jq -e '.scripts.test // empty' package.json >/dev/null; then
if javascript_test_script_collects_coverage; then
case "$package_runner" in
npm) run_and_capture "JavaScript/TypeScript test coverage" npm test ;;
pnpm) run_and_capture "JavaScript/TypeScript test coverage" corepack pnpm test ;;
yarn) run_and_capture "JavaScript/TypeScript test coverage" yarn test ;;
esac
if javascript_test_script_collects_coverage || javascript_coverage_provider_declared; then
if javascript_test_script_collects_coverage; then
case "$package_runner" in
npm) run_and_capture "JavaScript/TypeScript test coverage" npm test ;;
pnpm) run_and_capture "JavaScript/TypeScript test coverage" corepack pnpm test ;;
yarn) run_and_capture "JavaScript/TypeScript test coverage" yarn test ;;
esac
else
case "$package_runner" in
npm) run_and_capture "JavaScript/TypeScript test coverage" npm test -- --coverage ;;
pnpm) run_and_capture "JavaScript/TypeScript test coverage" corepack pnpm run test --coverage ;;
yarn) run_and_capture "JavaScript/TypeScript test coverage" yarn test --coverage ;;
esac
fi
javascript_coverage_ran=1
else
case "$package_runner" in
npm) run_and_capture "JavaScript/TypeScript test coverage" npm test -- --coverage ;;
pnpm) run_and_capture "JavaScript/TypeScript test coverage" corepack pnpm run test --coverage ;;
yarn) run_and_capture "JavaScript/TypeScript test coverage" yarn test --coverage ;;
npm) run_and_capture "JavaScript/TypeScript tests (coverage provider not declared)" npm test ;;
pnpm) run_and_capture "JavaScript/TypeScript tests (coverage provider not declared)" corepack pnpm test ;;
yarn) run_and_capture "JavaScript/TypeScript tests (coverage provider not declared)" yarn test ;;
esac
append "### JavaScript/TypeScript coverage threshold"
append ""
append "- Result: PASS"
append "- Reason: package.json defines a test script but no coverage provider or coverage-collecting test script; the networkless sandbox ran the tests without synthesizing a coverage instrumenter. Line-coverage remains repository-owned."
append ""
fi
Comment thread
seonghobae marked this conversation as resolved.
Resolved
Comment thread
seonghobae marked this conversation as resolved.
Resolved
javascript_coverage_ran=1
else
append "### JavaScript/TypeScript test coverage"
append ""
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ Semantic Versioning where the repository publishes a release.
during materialization and then rejecting every version except pnpm 11.5.3;
route generic coverage and docstring package scripts through the same
Corepack boundary instead of invoking a removed bare `pnpm` binary.
- Keep `--trust-lockfile` only for pnpm major versions 10 and newer after
Corepack honors repository `packageManager` pins such as pnpm 9.15.9;
pnpm 9 rejects that flag and previously failed LineageWeave JavaScript
coverage before tests could run.
- Run declared JavaScript test scripts without synthesizing `--coverage` when
the package does not declare a coverage provider, so networkless evidence
still records passing tests instead of failing on a missing instrumenter.
- Fix OpenCode coverage evidence for exact-base, organization-owned Python VCS
dependencies without weakening registry hashes or the networkless PR sandbox,
reject namespace, ambiguous, linked, native-extension, and installed-metadata
Expand Down
70 changes: 70 additions & 0 deletions docs/doctoring/opencode-pnpm-lock-compat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# OpenCode coverage pnpm lock compatibility

검토 기준일: **2026-08-23**

## Decision

OpenCode coverage-evidence honors the repository-owned `packageManager`
pin through Corepack. `--trust-lockfile` is valid only on pnpm major
version 10 and newer. Exact trusted-base lock matching remains mandatory
before any offline install. The sandbox never invents a JavaScript
coverage instrumenter when the package did not declare one.

This keeps LineageWeave and other pnpm 9.x products measurable after
Corepack started activating the repository pin instead of a central
pnpm 11.5.3 binary. A paying reviewer of lineage reconstruction would
otherwise see every frontend head blocked on `Unknown option:
'trust-lockfile'` and, after that, on `vitest --coverage` without
`@vitest/coverage-v8`.

## Root-cause analysis

1. Coverage images now activate the exact `packageManager` from the
validated base (for LineageWeave, `pnpm@9.15.9`).
2. The install command still passed `--trust-lockfile`, a pnpm 10 flag.
pnpm 9 exits before reading the store.
3. After a successful install, coverage appended `--coverage` to `vitest run`
even when no coverage provider was declared, so tests never became
evidence.

The lock-matching gate is unchanged: a PR-added or PR-mutated
`pnpm-lock.yaml` is still refused. `--offline`, `--frozen-lockfile`,
`--ignore-scripts`, and the writable clone of `/opt/pnpm-store` remain
required. Python still never runs `uv sync --project`.

## Remediation

- When `corepack pnpm --version` reports major version 10 or newer, keep
`--trust-lockfile` so registry attestation lookups stay suppressed for
an exact trusted-base lock (pnpm, n.d.).
- When the major version is below 10, omit that flag. pnpm 9 already
treats `--frozen-lockfile` plus `--offline` as the integrity boundary.
- When `package.json` has a test script but no coverage script, coverage
collector in `scripts.test`, or declared provider
(`@vitest/coverage-v8`, `@vitest/coverage-istanbul`, `c8`, `nyc`,
`istanbul`), run the tests without synthesizing `--coverage` and record
line-coverage as repository-owned rather than a sandbox failure.

Independent OpenCode, Strix, and Noema review remain authorization
gates. This change does not approve, merge, or weaken hash-pinned
Python or npm installs.

## APA 7th references

GitHub, Inc. (n.d.). *Using a package.json file to specify the package
manager*. GitHub Docs. Retrieved August 23, 2026, from
https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry

MITRE. (2026). *CWE-494: Download of code without integrity check*.
https://cwe.mitre.org/data/definitions/494.html

National Institute of Standards and Technology. (2022). *Secure software
development framework (SSDF) version 1.1: Recommendations for mitigating
the risk of software vulnerabilities* (NIST Special Publication 800-218).
https://doi.org/10.6028/NIST.SP.800-218

pnpm. (n.d.). *pnpm install*. pnpm Docs. Retrieved August 23, 2026, from
https://pnpm.io/cli/install

Vitest. (n.d.). *Coverage*. Vitest Docs. Retrieved August 23, 2026, from
https://vitest.dev/guide/coverage
2 changes: 2 additions & 0 deletions scripts/ci/test_strix_quick_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,8 @@ assert_file_contains "$REPO_ROOT/scripts/ci/run_opencode_review_model_pool.sh" '
assert_file_contains "$workflow_file" '"$COVERAGE_SOURCE_WORKDIR/$relative_lock"' "coverage hashes nested pnpm locks from the validated worktree root"
assert_file_not_contains "$workflow_file" 'hash-object --no-filters -- "$relative_lock"' "coverage does not double-prefix nested package lock paths from the package working directory"
assert_file_contains "$workflow_file" "--trust-lockfile" "coverage suppresses registry attestation lookups only for an exact trusted-base lock"
assert_file_contains "$workflow_file" '[ "$pnpm_major" -ge 10 ]' "coverage omits --trust-lockfile on pnpm major versions before 10"
assert_file_contains "$workflow_file" "javascript_coverage_provider_declared()" "coverage does not invent a JavaScript coverage instrumenter the package did not declare"
assert_file_contains "$workflow_file" "prepare_writable_pnpm_store()" "coverage prepares a sandbox-writable clone of the trusted pnpm store"
assert_file_contains "$workflow_file" 'destination="$(mktemp -d /tmp/opencode-pnpm-store.XXXXXX)"' "coverage creates the writable pnpm store at an unpredictable root-owned path"
assert_file_contains "$workflow_file" 'cp -R /opt/pnpm-store/. "$destination/"' "coverage clones packages from the trusted image seed"
Expand Down
14 changes: 13 additions & 1 deletion tests/test_opencode_agent_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,12 @@ def test_opencode_coverage_does_not_duplicate_existing_javascript_coverage():
measure_step = workflow[measure_start:measure_end]

assert "javascript_test_script_collects_coverage()" in measure_step
assert "javascript_coverage_provider_declared()" in measure_step
assert "if javascript_test_script_collects_coverage; then" in measure_step
assert (
"if javascript_test_script_collects_coverage || javascript_coverage_provider_declared; then"
in measure_step
)
assert (
'npm) run_and_capture "JavaScript/TypeScript test coverage" npm test ;;'
in measure_step
Expand All @@ -1016,6 +1021,10 @@ def test_opencode_coverage_does_not_duplicate_existing_javascript_coverage():
'pnpm) run_and_capture "JavaScript/TypeScript test coverage" corepack pnpm run test --coverage ;;'
in measure_step
)
assert (
'pnpm) run_and_capture "JavaScript/TypeScript tests (coverage provider not declared)" corepack pnpm test ;;'
in measure_step
)
assert "pnpm test --coverage" not in measure_step
assert "pnpm test -- --coverage" not in measure_step
assert 'test("(^|[[:space:]])--coverage([.=[:space:]]|$)' in measure_step
Expand All @@ -1024,7 +1033,7 @@ def test_opencode_coverage_does_not_duplicate_existing_javascript_coverage():
assert 'corepack pnpm --filter "$package_name" run build' in measure_step
assert "corepack pnpm test" in measure_step
assert "corepack pnpm run test --coverage" in measure_step

assert "[ \"$pnpm_major\" -ge 10 ]" in measure_step

def test_opencode_coverage_discovers_changed_nested_javascript_package(tmp_path):
"""A changed JS file must select its nearest nested package.json for coverage."""
Expand Down Expand Up @@ -2195,6 +2204,9 @@ def test_opencode_privileged_review_security_boundaries_are_fail_closed():
assert "--offline" in coverage_job
assert "--frozen-lockfile" in coverage_job
assert "--trust-lockfile" in coverage_job
assert "[ \"$pnpm_major\" -ge 10 ]" in coverage_job
assert "javascript_coverage_provider_declared()" in coverage_job
assert "coverage provider not declared" in coverage_job
assert "--ignore-scripts" in coverage_job
assert "prepare_writable_pnpm_store" in coverage_job
assert '--store-dir "$writable_pnpm_store_dir"' in coverage_job
Expand Down
2 changes: 1 addition & 1 deletion tests/test_pr_review_autofix_nvidia_nim_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
DOCTORING_RECORD = Path("docs/doctoring/hourly-nvidia-nim-autofix.md")
CHANGELOG = Path("CHANGELOG.md")
REVIEW_DISPATCH_WORKFLOW = Path(".github/workflows/opencode-review-dispatch.yml")
REVIEW_DISPATCH_BLOB_SHA = "ce7939845286be9668a01d5c640e867a8490ee5c"
REVIEW_DISPATCH_BLOB_SHA = "f01025ff2becd30b7c808e18e1f53671e62d067a"


def _workflow_text(path: Path) -> str:
Expand Down
Loading