Skip to content

[Review pipeline] Zero PRs mergeable in fast-mlsirm/LineageWeave: hash-pinning, cross-repo status 403, dispatch throughput #1212

Description

@seonghobae

Problem

Zero PRs are currently mergeable in ContextualWisdomLab/fast-mlsirm (60 open) or ContextualWisdomLab/LineageWeave (12 open) because the required branch-protection review (required_approving_review_count: 1) has not been satisfied by any bot on any current-head PR in either repo (reviewDecision is REVIEW_REQUIRED, CHANGES_REQUESTED, or empty on every open PR — none APPROVED). PR authors cannot self-approve (GitHub platform rule), so this is a hard blocker on the whole PR backlog in both repos, not a per-PR defect.

Investigated via gh run view/gh api .../check-runs/.../annotations on recent opencode-review-dispatch.yml and *-hourly-review-repair.yml runs. Three independent, concrete root causes found:

1. LineageWeave's uv.lock cannot be hash-pinned because two dependencies are git-sourced

scripts/ci/materialize_base_python_requirements.py requires the base branch's uv.lock to export as a fully hash-pinned requirements closure before the sandboxed coverage-evidence job (and therefore the whole approval decision) can run. LineageWeave's uv.lock pins fast-mlsirm and RankWeave via source = { git = "https://github.com/ContextualWisdomLab/....git?rev=<sha>#<sha>" }. uv export cannot emit a --hash=sha256:... for a git dependency (there is no fixed sdist/wheel artifact to hash — installing from git means running the package's build backend), so every export of LineageWeave's main lock fails _is_fully_hash_pinned_requirement, and _export_uv_lock raises "uv export for tracked base lock uv.lock was not fully hash-pinned". Every dispatch run against a LineageWeave PR fails at the coverage-evidence job for this reason (confirmed on PR #373, #387, #258, #349 dispatch runs 2026-08-21 21:3x UTC), regardless of what the PR itself changes.

Reproduced: LineageWeave's pinned fast-mlsirm commit (5006c38...) is 477 commits ahead of the latest tagged release (v0.6.0), and fast-mlsirm's release-tag.yml only runs gh release create — it does not build or attach an installable sdist/wheel asset, and the package is not published to PyPI (pypi.org/pypi/fast-mlsirm/json → 404) despite the org's PYPI_API_KEY secret already being available. Same shape of problem likely applies to RankWeave.

Recommended fix (do not relax the sandbox's hash-pinning requirement — that requirement is a real supply-chain control, since installing an unpinned/unhashed git dependency in an untrusted-PR sandbox means running arbitrary build-backend code from a mutable ref class):

  • Add a maturin build --release (or equivalent) step to fast-mlsirm's and RankWeave's release workflow that builds sdist + wheels and attaches them as GitHub Release assets (or publishes to PyPI using the existing PYPI_API_KEY).
  • Cut a release close to the commit LineageWeave currently depends on.
  • Switch LineageWeave's pyproject.toml entries for fast-mlsirm/RankWeave from git sources to a versioned PyPI dependency (or a direct release-asset URL dependency, which uv can hash), then regenerate uv.lock.

2. Cross-repo opencode-review status publish always fails with 403

In opencode-review-dispatch.yml, the step that publishes the optional opencode-review commit status back to the target repo (e.g. repos/ContextualWisdomLab/LineageWeave/statuses/<sha>) using the opencode-app exchanged token fails every time with gh: Resource not accessible by integration (HTTP 403) (confirmed on runs against appguardrail#969, LineageWeave#373). The OpenCode GitHub App does not appear to have statuses:write granted on these target repos, or is not installed there with that permission. This step is non-authoritative (the doc string says "the exact-head formal review remains authoritative") but it fails loudly on every run and wastes a job step; either grant the App the permission on all org repos it dispatches to, or drop the step.

3. Review-dispatch throughput is far below the PR creation rate

fast-mlsirm-hourly-review-repair.yml (and the generic pr-review-merge-scheduler.yml) invoke scripts/ci/pr_review_fix_scheduler.py / pr_review_merge_scheduler.py with MAX_DISPATCHES: 1 per run, i.e. at most ~1 new review dispatch per repo per scheduled run. Against a backlog of 60 open PRs in fast-mlsirm alone, this cannot keep the queue current even before accounting for root cause #1 above. Separately, the scheduler's own GitHub GraphQL calls (listing open PRs) intermittently fail after only 3 retries with a 1s/2s/4s backoff (Transient GitHub GraphQL error on attempt 1..3/4), aborting the entire scheduled run with no partial progress (confirmed failures at 2026-08-21T22:00 and 21:01 UTC for fast-mlsirm). Recommend widening the retry budget/backoff for transient GraphQL errors before concluding failure, and revisiting MAX_DISPATCHES once root cause #1 is fixed and the backlog is under control (raising throughput without fixing #1 would just burn compute on runs that fail at coverage-evidence anyway).

Evidence

  • gh run view 32529248149 --repo ContextualWisdomLab/.github (LineageWeave#373 dispatch, coverage-evidence failure annotation: Could not materialize base Python locks: uv export for tracked base lock uv.lock was not fully hash-pinned)
  • gh run view 32531069679 --repo ContextualWisdomLab/.github (fast-mlsirm-hourly-review-repair, Transient GitHub GraphQL error x3 then abort)
  • gh run view 32536566379 --repo ContextualWisdomLab/.github (cross-repo status 403 against appguardrail#969)
  • gh pr list --repo ContextualWisdomLab/fast-mlsirm --state open --json reviewDecision / same for LineageWeave: zero APPROVED among 72 combined open PRs.

Suggested scope for follow-up PRs (do not bundle into one PR)

  1. fast-mlsirm, RankWeave: add release-asset (or PyPI) publishing to the release workflow.
  2. LineageWeave: once (1) ships a release, switch the two git-sourced pyproject.toml entries to the released, hash-pinnable versions and regenerate uv.lock.
  3. .github: fix or remove the cross-repo opencode-review status-publish step (403).
  4. .github: widen the scheduler's GraphQL retry budget; revisit MAX_DISPATCHES after (1)-(2) land.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: dependenciesDependency or lockfile maintenancearea: securitySecurity boundary, hardening, or vulnerability preventionpriority: mediumNormal-priority or P2 workstatus: triagedOpen issue has an organization taxonomy assignmenttype: featureNew or expanded product capability

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions