Skip to content

fix(ci): harden hourly automation boundaries - #24

Merged
opencode-agent[bot] merged 33 commits into
mainfrom
fix/hourly-egress-folded-endpoints
Aug 9, 2026
Merged

fix(ci): harden hourly automation boundaries#24
opencode-agent[bot] merged 33 commits into
mainfrom
fix/hourly-egress-folded-endpoints

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Fleet incident continuation

Follow-up to issue #22 after the first repair reached protected main.

Protected-main scheduled run 31250354848 at e9e52e4cae47c1c0164a37ed907719f5e899caf5 disproved the earlier closure hypothesis. Although the workflow input visibly listed api.github.com:443 and cafe.github.com:443, the installed Harden Runner agent reduced the literal-newline endpoint input to an unusable GitHub API mapping with port 0. The subsequent gh api inventory call was dropped before the existing open-PR gate could terminate cleanly.

The same fleet audit also found that ThreadWeave's Hourly PR Maintenance caller duplicated a mutable central review-fix path, invoked both central workflows at @main, forwarded all repository/organization secrets with secrets: inherit, and granted the caller the union of write permissions. The immutable central merge scheduler already performs bounded current-head review dispatch, exact-head check evaluation, one bounded branch update, and policy-compliant direct/auto-merge evaluation for the caller repository.

Repairs

Harden Runner runtime serialization

  • change all three Hourly Product Development allowed-endpoints scalars from literal | to folded >-;
  • preserve egress-policy: block and the exact reviewed endpoint sets, including both GitHub API names justified by protected-run evidence;
  • preserve deterministic open-PR, release-blocker, and dry-run decisions ahead of NVIDIA_NIM_API_KEY;
  • keep NVIDIA_NIM_API_KEY limited to the actual model-backed path;
  • apply the same runtime-safe scalar serialization to all five manual release jobs using the same pinned Harden Runner version, without adding endpoints, wildcards, credentials, or publication authority.

Hourly PR Maintenance authority

  • remove the redundant repository-local invocation of mutable pr-review-fix-scheduler.yml@main;
  • replace mutable pr-review-merge-scheduler.yml@main with immutable pin 3f65dbee6672b78802e7d71d49c390f3817bb03b;
  • remove both secrets: inherit declarations rather than inventing or forwarding a PAT-like credential;
  • reduce top-level permissions to contents: read;
  • grant only the pinned reusable job's reviewed permissions: actions: write, checks: read, contents: write, id-token: write, pull-requests: write, and statuses: read;
  • remove unused issues: write authority and preserve the existing bounded scheduler inputs.

No central .github file is changed by this pull request.

Test-first evidence

Hourly product-development endpoint input

  • 601583d3b1846c5a019ab38d180e87a40d343069 first changed the executable hourly contract to require folded endpoint input while production still used literal blocks.
  • 71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f made the smallest production change: the three scalar styles only. The contract rejects literal-block regression and hostname-suffix injection while preserving exact endpoint membership.

Manual release endpoint input

  • 3a560a6d472c2f916d2b9bf5c7e27578e0c81a77 added the release delimiter regression before production repair.
  • RED CI run 31257108909 failed on Python 3.10, 3.11, 3.12, and 3.13 exactly because all five release endpoint blocks remained literal: the focused autonomous/release suite reported 1 failed, 74 passed; actionlint/lock integrity and package verification succeeded, and SAST/Security succeeded.
  • Before production mutation, the reconstructed literal release file's Git blob SHA matched live branch blob 9ba0a086a3f240064e62981de3d8550aa3ae7cf0 exactly.
  • 507f6fef013d0a193f6626ecd680d081333eab5e changed exactly five scalar markers from | to >-; its commit diff contains no endpoint, permission, action-pin, script, release, or credential change.

Hourly PR Maintenance caller

  • 76e512e1917c34b6685c1ee91b2b9c5ee10121db added the immutable, secretless single-scheduler contract before production repair.
  • RED CI run 31257969581 failed on Python 3.10, 3.11, 3.12, and 3.13 exactly on that new contract: 1 failed, 256 passed. The failure showed the live caller still contained pr-review-fix-scheduler.yml@main, mutable merge @main, and secrets: inherit; focused 100% autonomous/release boundary coverage, actionlint/lock integrity, package verification, SAST, and Security all otherwise succeeded.
  • a012550f6e6ec9941348aa84707bd3c0388eb4eb removed the duplicate/mutable/secret-forwarding path and aligned the existing workflow contract with the immutable central scheduler.

Exact-current-head verification

Current exact head: 095754134dd7f0e6e7c3292807348a3925c5fcf7
Exact base: e9e52e4cae47c1c0164a37ed907719f5e899caf5

  • CI run 31293099351: success across lock/actionlint, Python 3.10-3.13, package, installed-wheel smoke, and pip check.
  • The Python 3.13 job reports 279 passed; the combined 1,524 statements / 528 branches and the focused 887 statements / 268 branches are all 100%.
  • SAST Semgrep run 31293099330: success.
  • Security Scan run 31293099337: success.
  • CodeQL check 93193671980: success; the prior weak-sensitive-data-hashing alert is absent after replacing the fast SHA confirmation with salted scrypt and bounding collision work.
  • Exact-head CodeRabbit commit status: success; its incremental narrative review was rate-limited and is not treated as approval.
  • Strix Security Scan run 31293098347 is still in progress, so the PR is not merge-ready.
  • All seven review threads are resolved. No qualifying formal approval exists on the current head; the two historical CHANGES_REQUESTED submissions refer to predecessor 3305c08e6372cfc213fdc7055f3e5dfa5d56387d.

Merge and operational-closure gates

Do not merge unless this exact head remains current, every required check and security gate passes, all valid exact-head feedback is addressed, branch/ruleset policy permits integration, and a qualifying independent non-author reviewer submits formal APPROVE.

Merge alone is not operational closure. After protected-main integration, issue #22 remains open until:

  1. an actual scheduled/manual Hourly PR Maintenance run executes the immutable central reusable scheduler without mutable-ref or secret-forwarding failure;
  2. an actual scheduled/manual Hourly Product Development run successfully inventories GitHub pull requests through fail-closed Harden Runner and, while the queue is non-empty, exits as open_pull_request; and
  3. after the queue is drained, a later protected-main run reaches the bounded OpenCode/NVIDIA path or an explicit documented product/release gate.

The release scalar hardening is covered by exact-head workflow contracts but is not claimed as a protected release execution. No COPILOT_GITHUB_TOKEN, guessed secret, repository-specific PAT, temporary write-capable repair workflow, egress-policy weakening, branch-protection bypass, release, or publication is introduced.

Summary by CodeRabbit

  • 워크플로 개선

    • PR 유지보수가 고정 버전의 중앙 병합 스케줄러를 통해 실행됩니다.
    • 제품 개발 작업 제한 시간이 180분으로 확대되었습니다.
    • 개발 게이트에서 자격 증명을 안전하게 처리하고, 검증 실패 시 중단합니다.
    • 결과물에 민감한 자격 증명이 포함되지 않았는지 자동 검사합니다.
    • 릴리스 및 개발 작업의 네트워크 접근과 권한 설정을 강화했습니다.
  • 테스트

    • PR 유지보수, 개발 게이트, 릴리스 보안 설정의 자동 검증을 강화했습니다.
    • 자격 증명 보호 및 CI 커버리지 검증을 추가했습니다.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 7 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9bb12870-00d1-472b-898b-52d54e68518e

📥 Commits

Reviewing files that changed from the base of the PR and between c0f88b9 and f4c85f7.

📒 Files selected for processing (5)
  • scripts/ci/secret_fingerprint_guard.py
  • tests/test_ci_autonomous_coverage_contract.py
  • tests/test_codeql_fingerprint_suppression_contract.py
  • tests/test_hourly_product_secret_fingerprint.py
  • tests/test_secret_fingerprint_collision_regression.py
📝 Walkthrough

Walkthrough

시간별 PR 유지보수는 고정 리비전의 중앙 merge 스케줄러를 호출합니다. 제품 개발은 결정론적 게이트와 NVIDIA 자격 증명 검증을 분리합니다. 결과물은 자격 증명 지문으로 검사합니다. CI와 릴리스 검증은 해당 가드와 folded endpoint 형식을 확인합니다.

Changes

시간별 자동화 워크플로

Layer / File(s) Summary
중앙 PR 병합 스케줄러 호출
.github/workflows/hourly-pr-maintenance.yml, tests/test_hourly_pr_maintenance_contract.py, tests/test_workflows.py
기존 review-fix 작업을 제거하고 고정 리비전의 중앙 merge 스케줄러를 제한된 권한으로 호출합니다. 리뷰, 브랜치 업데이트, 자동 병합 설정을 계약 테스트로 검증합니다.
제품 개발 게이트와 자격 증명 경계
.github/workflows/hourly-product-development.yml, tests/test_hourly_product_egress_contract.py, tests/test_workflows.py
결정론적 게이트가 자격 증명 없이 먼저 종료 상태를 판정합니다. NIM broker 단계에서 자격 증명을 검증하고 결과물 검사 전에 지문을 생성합니다.
자격 증명 지문 가드
scripts/ci/secret_fingerprint_guard.py, tests/test_hourly_product_secret_fingerprint.py, .github/workflows/ci.yml, tests/test_ci_autonomous_coverage_contract.py
원문과 인코딩 표현의 rolling hash 및 SHA-256 지문을 저장합니다. 결과물의 지문을 검색하고 잘못된 입력을 fail-closed 방식으로 거부합니다. CI는 모듈 테스트와 100% 미만 커버리지 실패 조건을 실행합니다.
릴리스 egress 설정과 계약 테스트
.github/workflows/release.yml, tests/test_release_workflow.py
5개 릴리스 작업의 allowed-endpoints를 folded scalar 형식으로 변경합니다. harden-runner, 차단형 egress 정책과 작업별 endpoint 집합을 검증합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant HourlyProductDevelopment
  participant DeterministicGate
  participant NIMCredentialBroker
  participant SecretFingerprintGuard
  participant ArtifactCapture
  HourlyProductDevelopment->>DeterministicGate: PR 및 release-blocker 상태 평가
  DeterministicGate-->>HourlyProductDevelopment: 실행 준비 상태 반환
  HourlyProductDevelopment->>NIMCredentialBroker: NVIDIA 자격 증명 검증
  NIMCredentialBroker->>SecretFingerprintGuard: 지문 파일 생성
  ArtifactCapture->>SecretFingerprintGuard: 패치, 통계, 제안서 검사
  SecretFingerprintGuard-->>ArtifactCapture: 검사 결과 반환
Loading

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 시간별 CI 자동화 경계 강화라는 변경의 주요 목적을 정확하고 간결하게 설명합니다.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/hourly-egress-folded-endpoints

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor Author

@opencode-agent @cwl-noema-review

Review-only request for exact current head 71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f against protected base e9e52e4cae47c1c0164a37ed907719f5e899caf5. Do not mutate the branch or merge. Revalidate the protected-main failure in run 31250354848: Harden Runner received the newline-delimited endpoint input but its installed agent retained only api.github.com with port 0 plus the space-appended cache host, then dropped the gh api connection. Verify that changing only the three allowed-endpoints YAML scalars from literal | to folded >- preserves the exact fail-closed endpoint sets while presenting the runtime space-delimited input expected by the observed parser; verify deterministic open-PR/release-blocker/dry-run exits remain ahead of NVIDIA_NIM_API_KEY; verify downstream jobs remain model-credential-free; inspect exact-head CI/actionlint/SAST/Security Scan and all review threads. Submit a formal non-author GitHub APPROVE only if this exact head is clean.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact current head 71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f. Treat all predecessor-head review/check evidence as stale. Focus on the observed Harden Runner runtime delimiter/port failure, exact fail-closed endpoint sets, the folded-scalar regression test, and preservation of deterministic gates before the optional NVIDIA model credential.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

head='71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f'
base='e9e52e4cae47c1c0164a37ed907719f5e899caf5'
repo='ContextualWisdomLab/ThreadWeave'

printf '%s\n' '== Checked-out and requested commits =='
git rev-parse HEAD
git cat-file -t "$head"
git cat-file -t "$base"
git merge-base --is-ancestor "$base" "$head" && echo 'base-is-ancestor=yes'

printf '%s\n' '== Exact-head changed files and diff =='
git diff --name-status "$base" "$head"
git diff --check "$base" "$head"
git diff --unified=80 "$base" "$head" -- .github || true

printf '%s\n' '== Candidate workflow/test files =='
fd -t f . .github 2>/dev/null || true
fd -t f . | rg -i '(harden|endpoint|workflow|actionlint|regression|test)' || true

printf '%s\n' '== PR metadata, checks, reviews, and review comments =='
gh pr view 24 --repo "$repo" --json headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,statusCheckRollup,reviews \
  --jq '{headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,checks:[.statusCheckRollup[]? | {name,status,conclusion,detailsUrl}],reviews:[.reviews[]? | {author:.author.login,state,commitId,submittedAt,body}]}'
gh api "repos/$repo/pulls/24/comments?per_page=100" \
  --jq '.[] | {user:.user.login,path,position,original_position,commit_id,body,created_at}' || true

Length of output: 26977


🏁 Script executed:

#!/bin/bash
set -euo pipefail

workflow='.github/workflows/hourly-product-development.yml'
test_file='tests/test_hourly_product_egress_contract.py'

printf '%s\n' '== Changed regression test =='
cat -n "$test_file"

printf '%s\n' '== Workflow: all Harden Runner declarations and endpoint blocks =='
rg -n -A22 -B4 'uses:\s*step-security/harden-runner|allowed-endpoints:|egress-policy:' "$workflow"

printf '%s\n' '== Workflow: deterministic development gate =='
rg -n -A80 -B5 'name: Enforce the credential and pull-request-first gate|NIM_UPSTREAM_API_KEY|NVIDIA_NIM_API_KEY|DRY_RUN|open_prs=|release_blockers=' "$workflow"

printf '%s\n' '== Workflow: job declarations and credential references =='
rg -n -A8 -B3 '^  (develop-product-gap|reverify-product-gap|publish-product-gap):|NVIDIA_NIM_API_KEY|NIM_UPSTREAM_API_KEY|integrate\.api\.nvidia\.com' "$workflow"

printf '%s\n' '== Static YAML scalar and endpoint-set validation =='
python - <<'PY'
from pathlib import Path
import re

text = Path(".github/workflows/hourly-product-development.yml").read_text()
expected = {
    "develop-product-gap": {
        "api.github.com:443", "cafe.github.com:443", "codeload.github.com:443",
        "files.pythonhosted.org:443", "github.com:443", "integrate.api.nvidia.com:443",
        "objects.githubusercontent.com:443", "pypi.org:443", "registry.npmjs.org:443",
        "release-assets.githubusercontent.com:443", "results-receiver.actions.githubusercontent.com:443",
        "*.actions.githubusercontent.com:443", "*.blob.core.windows.net:443",
    },
    "reverify-product-gap": {
        "api.github.com:443", "cafe.github.com:443", "files.pythonhosted.org:443",
        "github.com:443", "objects.githubusercontent.com:443", "pypi.org:443",
        "release-assets.githubusercontent.com:443", "results-receiver.actions.githubusercontent.com:443",
        "*.actions.githubusercontent.com:443", "*.blob.core.windows.net:443",
    },
    "publish-product-gap": {
        "api.github.com:443", "cafe.github.com:443", "github.com:443",
        "objects.githubusercontent.com:443", "results-receiver.actions.githubusercontent.com:443",
        "*.actions.githubusercontent.com:443", "*.blob.core.windows.net:443",
    },
}
jobs = {}
for job, body in re.findall(
    r"^  ([a-z][\w-]+):\n(.*?)(?=^  [a-z][\w-]+:|\Z)",
    text,
    flags=re.M | re.S,
):
    if job in expected:
        scalar = re.search(
            r"^          allowed-endpoints: (.+?)\n((?:            .*\n)+)",
            body,
            flags=re.M,
        )
        assert scalar, f"{job}: allowed-endpoints block not found"
        style, lines = scalar.groups()
        endpoints = {line.strip() for line in lines.splitlines() if line.strip()}
        jobs[job] = (style, endpoints)

for job, (style, endpoints) in jobs.items():
    print(f"{job}: style={style!r}; exact_set={endpoints == expected[job]}; count={len(endpoints)}")
    print("  endpoints=" + " ".join(sorted(endpoints)))
    assert style == ">-", f"{job}: expected folded strip scalar"
    assert endpoints == expected[job], f"{job}: endpoint set changed"
assert set(jobs) == set(expected), "missing expected Harden Runner job"
assert "allowed-endpoints: |" not in text, "literal endpoint scalar remains"
print("all exact endpoint-set checks passed")
PY

Length of output: 43285


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/ThreadWeave'
head='71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f'
test_commit='601583d3b1846c5a019ab38d180e87a40d343069'

printf '%s\n' '== Test-first commit sequence =='
git merge-base --is-ancestor "$test_commit" "$head" && echo 'test-commit-is-ancestor=yes'
git show --no-ext-diff --format='commit=%H%nparent=%P%nsubject=%s' --stat "$test_commit"
git show --no-ext-diff --format='commit=%H%nparent=%P%nsubject=%s' --stat "$head"
printf '%s\n' '== Head-only patch after regression-contract commit =='
git diff --check "$test_commit" "$head"
git diff --name-status "$test_commit" "$head"
git diff --unified=12 "$test_commit" "$head" -- .github/workflows/hourly-product-development.yml tests/test_hourly_product_egress_contract.py

printf '%s\n' '== Current check suites for requested head =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '.check_runs | sort_by(.name)[] | {name,status,conclusion,started_at,completed_at,details_url}'

printf '%s\n' '== Current GitHub review state and review-thread comments =='
gh pr view 24 --repo "$repo" --json reviewDecision,reviews,latestReviews \
  --jq '{reviewDecision,reviews:[.reviews[]? | {author:.author.login,state,commitId,submittedAt,body}],latestReviews:[.latestReviews[]? | {author:.author.login,state,commitId,submittedAt,body}]}'
gh api graphql -F owner='ContextualWisdomLab' -F name='ThreadWeave' -F number=24 -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          comments(first: 20) {
            nodes { author { login } body commit { oid } path createdAt }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'

printf '%s\n' '== Protected-main branch requirements =='
gh api "repos/$repo/branches/main/protection" \
  --jq '{required_status_checks,required_pull_request_reviews,required_signatures,enforce_admins}' || true

Length of output: 15127


@seonghobae Review complete for exact head 71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f.

I found no source-level review findings in the requested scope.

  • The head is based on e9e52e4cae47c1c0164a37ed907719f5e899caf5.
  • The test-first commit 601583d3b1846c5a019ab38d180e87a40d343069 is the direct parent.
  • The head changes only the three Harden Runner allowed-endpoints scalar styles from | to >-.
  • All three jobs retain egress-policy: block and their exact reviewed endpoint sets.
  • A folded YAML scalar supplies the endpoint lines as a space-delimited value. This matches the observed Harden Runner parser requirement without adding endpoints, wildcards, or credentials.
  • The regression test requires >-, rejects a literal-block regression, asserts each exact endpoint set, and rejects an adversarial hostname suffix.
  • The open_pull_request, release_blocker, and dry_run exits occur before NIM_UPSTREAM_API_KEY is evaluated.
  • reverify-product-gap and publish-product-gap contain no NVIDIA model credential reference.
  • All completed exact-head tests, analysis, SAST, and security checks succeeded.
  • No GitHub reviews or unresolved review threads were present when queried.

I cannot approve yet.

  • strix was still in progress.
  • Branch-protection requirements could not be read because the GitHub API returned HTTP 403.
  • No qualifying independent non-author approval exists.
  • The post-merge protected-main scheduled or manual run must still prove that the GitHub API inventory call succeeds and exits through open_pull_request while the PR queue is non-empty.
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please perform a fresh full review of exact current head 71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f against protected base e9e52e4cae47c1c0164a37ed907719f5e899caf5. The prior rate-limited attempt is not evidence. Focus on the observed Harden Runner literal-scalar runtime port loss, the folded >- endpoint-input repair without allowlist broadening, preservation of fail-closed egress, and deterministic open-PR/release-blocker/dry-run exits before the optional NVIDIA model credential. Submit a formal review on this exact head according to repository policy if clean.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/ThreadWeave'
pr='24'
head='71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f'
base='e9e52e4cae47c1c0164a37ed907719f5e899caf5'

echo '== Commit identity and ancestry =='
printf 'checked_out='; git rev-parse HEAD
git cat-file -t "$head"
git cat-file -t "$base"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'
printf 'merge_base='; git merge-base "$base" "$head"

echo '== Exact diff =='
git diff --check "$base" "$head"
git diff --name-status "$base" "$head"
git diff --unified=30 "$base" "$head" -- .github/workflows/hourly-product-development.yml tests/test_hourly_product_egress_contract.py

echo '== Candidate file map =='
fd -t f -a 'hourly-product-development.yml' .github
fd -t f -a 'test_hourly_product_egress_contract.py' tests
ast-grep outline .github/workflows/hourly-product-development.yml --items all || true
ast-grep outline tests/test_hourly_product_egress_contract.py --items all || true

echo '== Workflow and regression contract =='
cat -n .github/workflows/hourly-product-development.yml
cat -n tests/test_hourly_product_egress_contract.py

echo '== Exact-head check runs =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '.check_runs | sort_by(.name)[] | {name,status,conclusion,started_at,completed_at,details_url}'

echo '== Pull request identity, reviews, and files =='
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,statusCheckRollup,reviews,latestReviews,files \
  --jq '{headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,checks:[.statusCheckRollup[]? | {name,status,conclusion,detailsUrl}],reviews:[.reviews[]? | {author:.author.login,state,commitId,submittedAt,body}],latestReviews:[.latestReviews[]? | {author:.author.login,state,commitId,submittedAt}],files:[.files[]? | {path,additions,deletions}]}'

echo '== Unresolved review threads =='
gh api graphql -F owner='ContextualWisdomLab' -F name='ThreadWeave' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          comments(first: 30) {
            nodes { author { login } body commit { oid } path line originalLine createdAt }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'

echo '== Branch-protection policy =='
gh api "repos/$repo/branches/main/protection" \
  --jq '{required_status_checks,required_pull_request_reviews,required_signatures,enforce_admins}' || true

Length of output: 76146


@seonghobae Fresh review complete for head 71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f against base e9e52e4cae47c1c0164a37ed907719f5e899caf5.

I found no source-level findings in the requested scope.

  • The checked-out commit equals the requested head. The requested base is its merge base.
  • The workflow changes only the three Harden Runner allowed-endpoints scalars from | to >-.
  • YAML folded scalars present the endpoint entries as one space-delimited value. The - chomp indicator removes the final newline.
  • Each job retains its exact reviewed endpoint set. The change does not add endpoints, credentials, or allowlist broadening.
  • Each Harden Runner step retains egress-policy: block.
  • The regression contract requires >-, rejects a literal scalar, validates each exact endpoint set, and rejects the hostname suffix injection.
  • open_pull_request, release_blocker, and dry_run each set the stop result and execute exit 0 before the NIM_UPSTREAM_API_KEY check.
  • reverify-product-gap and publish-product-gap contain no NIM_UPSTREAM_API_KEY reference.
  • All completed exact-head checks succeeded, including tests, action analysis, SAST, dependency scanning, and filesystem security scanning.
  • The pull request has no submitted reviews and no unresolved review threads.

I could not verify protected-branch requirements. GitHub returned HTTP 403 for the branch-protection API.

I cannot submit a formal approval from this review command. Submit @coderabbitai approve as a separate top-level command if you want an approval action after this review.

⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 30 minutes.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Re-review exact unchanged head 71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f now that the prior stated 30-minute rate-limit window has elapsed. Treat all predecessor-head and rate-limit-only evidence as non-passing. Confirm the folded >- runtime-delimiter repair preserves each exact fail-closed endpoint set, deterministic open-PR/release-blocker/dry-run exits precede the NVIDIA credential, and every exact-head required check is complete. Submit a formal non-author GitHub APPROVE only if this exact head is clean and policy permits it; otherwise report the precise remaining gate without mutating the branch.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Your plan includes PR reviews subject to rate limits. Reviews are available now.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact current head 71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f only. Revalidate the observed Harden Runner newline-delimiter/port-0 failure, the three folded allowed-endpoints: >- scalars, exact fail-closed endpoint sets, and deterministic open-PR/release-blocker/dry-run exits before the optional NVIDIA model credential. Treat all predecessor-head evidence as stale.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/ThreadWeave'
pr='24'
head='71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f'
base='e9e52e4cae47c1c0164a37ed907719f5e899caf5'
workflow='.github/workflows/hourly-product-development.yml'
test_file='tests/test_hourly_product_egress_contract.py'

echo '== Exact revision identity =='
printf 'checked_out='; git rev-parse HEAD
git cat-file -t "$head"
git cat-file -t "$base"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'
printf 'merge_base='; git merge-base "$base" "$head"

echo '== Exact head diff =='
git diff --check "$base" "$head"
git diff --name-status "$base" "$head"
git diff --unified=40 "$base" "$head" -- "$workflow" "$test_file"

echo '== Candidate file outlines =='
ast-grep outline "$workflow" --items all || true
ast-grep outline "$test_file" --items all || true

echo '== Harden Runner configurations =='
rg -n -A25 -B4 'step-security/harden-runner|egress-policy:|allowed-endpoints:' "$workflow"

echo '== Gate and model credential ordering =='
rg -n -A95 -B8 'open_prs=|release_blockers=|DRY_RUN|NIM_UPSTREAM_API_KEY|NVIDIA_NIM_API_KEY|open_pull_request|release_blocker|dry_run' "$workflow"

echo '== Parsed scalar and endpoint-set validation =='
python3 - <<'PY'
from pathlib import Path
import re

text = Path(".github/workflows/hourly-product-development.yml").read_text()
expected = {
    "develop-product-gap": {
        "api.github.com:443", "cafe.github.com:443", "codeload.github.com:443",
        "files.pythonhosted.org:443", "github.com:443", "integrate.api.nvidia.com:443",
        "objects.githubusercontent.com:443", "pypi.org:443", "registry.npmjs.org:443",
        "release-assets.githubusercontent.com:443", "results-receiver.actions.githubusercontent.com:443",
        "*.actions.githubusercontent.com:443", "*.blob.core.windows.net:443",
    },
    "reverify-product-gap": {
        "api.github.com:443", "cafe.github.com:443", "files.pythonhosted.org:443",
        "github.com:443", "objects.githubusercontent.com:443", "pypi.org:443",
        "release-assets.githubusercontent.com:443", "results-receiver.actions.githubusercontent.com:443",
        "*.actions.githubusercontent.com:443", "*.blob.core.windows.net:443",
    },
    "publish-product-gap": {
        "api.github.com:443", "cafe.github.com:443", "github.com:443",
        "objects.githubusercontent.com:443", "results-receiver.actions.githubusercontent.com:443",
        "*.actions.githubusercontent.com:443", "*.blob.core.windows.net:443",
    },
}
for job, wanted in expected.items():
    body_match = re.search(
        rf"^  {re.escape(job)}:\n(.*?)(?=^  [\w-]+:|\Z)", text, re.M | re.S
    )
    assert body_match, f"{job}: missing job"
    body = body_match.group(1)
    match = re.search(
        r"^          allowed-endpoints: (.+?)\n((?:            .*\n)+)",
        body, re.M
    )
    assert match, f"{job}: missing allowed-endpoints"
    style, endpoint_lines = match.groups()
    values = {line.strip() for line in endpoint_lines.splitlines() if line.strip()}
    print(f"{job}: style={style!r} egress_block={'egress-policy: block' in body} "
          f"exact_set={values == wanted} endpoint_count={len(values)}")
    assert style == ">-", f"{job}: scalar style is {style!r}"
    assert "egress-policy: block" in body, f"{job}: egress is not block"
    assert values == wanted, f"{job}: endpoint set changed"
assert "allowed-endpoints: |" not in text
print("literal endpoint scalar absent")
PY

echo '== Regression contract relevant assertions =='
rg -n -A8 -B5 'allowed-endpoints|>\-|literal|endpoint|suffix|open_pull_request|release_blocker|dry_run' "$test_file"

echo '== Current exact-head check runs =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '.check_runs | sort_by(.name)[] | {name,status,conclusion,started_at,completed_at,details_url}'

echo '== Current PR reviews and unresolved threads =='
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,reviews,latestReviews,statusCheckRollup \
  --jq '{headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,reviews:[.reviews[]? | {author:.author.login,state,commitId,submittedAt}],latestReviews:[.latestReviews[]? | {author:.author.login,state,commitId,submittedAt}],checks:[.statusCheckRollup[]? | {name,status,conclusion,detailsUrl}]}'
gh api graphql -F owner='ContextualWisdomLab' -F name='ThreadWeave' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          comments(first: 20) {
            nodes { author { login } body commit { oid } path line originalLine createdAt }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'

Length of output: 74239


@seonghobae Fresh review complete for exact head 71a6d7e151ec6a9d53f9761ad65d4f22d3951c5f.

I found no source-level findings in the requested scope.

  • The checked-out revision equals the requested head.
  • The requested protected base is the merge base.
  • The change modifies only the three Harden Runner allowed-endpoints scalar styles and the regression contract.
  • All three Harden Runner configurations use allowed-endpoints: >-.
  • All three configurations retain egress-policy: block.
  • The reviewed endpoint sets are unchanged: 13 endpoints for develop-product-gap, 10 for reverify-product-gap, and 7 for publish-product-gap.
  • No allowed-endpoints: | scalar remains.
  • The folded scalar supplies endpoint entries as a space-delimited value. This addresses the reported newline-delimiter and port-loss behavior without expanding an allowlist.
  • The regression contract requires >-, rejects a literal scalar, validates each exact endpoint set, and rejects a hostname-suffix injection.
  • open_pull_request, release_blocker, and dry_run each write their result and execute exit 0 before the NIM_UPSTREAM_API_KEY check.
  • The current exact-head checks are complete. All completed non-skipped checks succeeded, including action analysis, Python tests, SAST, CodeQL, Semgrep, Trivy, dependency review, and review-agent checks.
  • The pull request has no submitted reviews and no unresolved review threads.

A formal approval requires a separate top-level @coderabbitai approve command.

You are interacting with an AI system.

Copy link
Copy Markdown
Contributor Author

@opencode-agent @cwl-noema-review @coderabbitai review

Review-only request for exact current head 507f6fef013d0a193f6626ecd680d081333eab5e against protected base e9e52e4cae47c1c0164a37ed907719f5e899caf5. Do not mutate the branch or merge. Revalidate the three Hourly Product Development and five manual release Harden Runner endpoint scalars, exact endpoint membership, fail-closed egress, deterministic gates before NVIDIA_NIM_API_KEY, and the absence of invented credentials or publication authority. Inspect exact-head CI 31257510926, SAST 31257510919, Security Scan 31257510936, every current review submission, and all review threads. Submit a formal non-author GitHub APPROVE only if this exact head is clean and repository policy permits it; otherwise report the precise remaining gate.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/ThreadWeave'
pr='24'
head='507f6fef013d0a193f6626ecd680d081333eab5e'
base='e9e52e4cae47c1c0164a37ed907719f5e899caf5'

echo '== Exact revision and diff =='
printf 'checked_out='; git rev-parse HEAD
git cat-file -t "$head"
git cat-file -t "$base"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'
printf 'merge_base='; git merge-base "$base" "$head"
git diff --check "$base" "$head"
git diff --name-status "$base" "$head"
git diff --unified=50 "$base" "$head" -- .github tests

echo '== Candidate workflow and regression files =='
fd -t f . .github tests | rg -i '(hourly|release|harden|egress|endpoint|contract)'

echo '== Workflow outlines =='
fd -t f -e yml -e yaml .github/workflows -x ast-grep outline {} --items all 2>/dev/null || true

echo '== Harden Runner configuration blocks =='
rg -n -A35 -B5 'uses:\s*step-security/harden-runner|egress-policy:|allowed-endpoints:' .github/workflows

echo '== Hourly deterministic gates and credential scope =='
rg -n -A105 -B10 'open_pull_request|release_blocker|dry_run|NIM_UPSTREAM_API_KEY|NVIDIA_NIM_API_KEY|integrate\.api\.nvidia\.com' .github/workflows

echo '== Release credential, permission, and publication references =='
rg -n -A8 -B8 'NVIDIA_NIM_API_KEY|NIM_UPSTREAM_API_KEY|COPILOT_GITHUB_TOKEN|permissions:|publish|release|upload|attest|id-token|packages:|contents:' .github/workflows

echo '== Exact-head check runs =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '.check_runs | sort_by(.name)[] | {name,status,conclusion,started_at,completed_at,details_url}'

echo '== Requested workflow runs =='
for run in 31257510926 31257510919 31257510936; do
  gh api "repos/$repo/actions/runs/$run" \
    --jq '{id,name,event,status,conclusion,head_sha,head_branch,run_started_at,updated_at,html_url}'
  gh api "repos/$repo/actions/runs/$run/jobs?per_page=100" \
    --jq '.jobs[] | {name,status,conclusion,started_at,completed_at,html_url}'
done

echo '== Current pull request reviews, check rollup, and threads =='
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,reviews,latestReviews,statusCheckRollup \
  --jq '{headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,reviews:[.reviews[]? | {author:.author.login,state,commitId,submittedAt,body}],latestReviews:[.latestReviews[]? | {author:.author.login,state,commitId,submittedAt,body}],checks:[.statusCheckRollup[]? | {name,status,conclusion,detailsUrl}]}'
gh api graphql -F owner='ContextualWisdomLab' -F name='ThreadWeave' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          comments(first: 30) {
            nodes { author { login } body commit { oid } path line originalLine createdAt }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'

echo '== Protected branch policy =='
gh api "repos/$repo/branches/main/protection" \
  --jq '{required_status_checks,required_pull_request_reviews,required_signatures,enforce_admins}' || true

Length of output: 205834


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/ThreadWeave'
pr='24'
head='507f6fef013d0a193f6626ecd680d081333eab5e'
base='e9e52e4cae47c1c0164a37ed907719f5e899caf5'

echo '== Endpoint block equality, excluding scalar marker =='
python3 - <<'PY'
import re
import subprocess

base = "e9e52e4cae47c1c0164a37ed907719f5e899caf5"
head = "507f6fef013d0a193f6626ecd680d081333eab5e"
files = (
    ".github/workflows/hourly-product-development.yml",
    ".github/workflows/release.yml",
)

def content(revision, path):
    return subprocess.check_output(
        ["git", "show", f"{revision}:{path}"], text=True
    )

def endpoint_blocks(text):
    blocks = []
    pattern = re.compile(
        r"(?ms)^  ([a-z][a-z0-9-]+):\n.*?"
        r"^          allowed-endpoints: ([|>][-+]?)\n"
        r"((?:^            \S.*\n)+)"
    )
    for job, marker, block in pattern.findall(text):
        endpoints = tuple(line.strip() for line in block.splitlines())
        blocks.append((job, marker, endpoints))
    return blocks

for path in files:
    old = endpoint_blocks(content(base, path))
    new = endpoint_blocks(content(head, path))
    assert len(old) == len(new), (path, len(old), len(new))
    assert [j for j, _, _ in old] == [j for j, _, _ in new], path
    print(path)
    for (job, old_marker, old_endpoints), (_, new_marker, new_endpoints) in zip(old, new):
        unchanged = old_endpoints == new_endpoints
        print(
            f"  {job}: base={old_marker!r} head={new_marker!r} "
            f"count={len(new_endpoints)} exact_membership_unchanged={unchanged}"
        )
        assert old_marker == "|", (path, job, old_marker)
        assert new_marker == ">-", (path, job, new_marker)
        assert unchanged, (path, job)
        assert len(new_endpoints) == len(set(new_endpoints)), (path, job, "duplicate endpoint")
print("all eight endpoint blocks retain exact base membership")
PY

echo '== Workflow diffs contain only scalar-marker changes =='
git diff --word-diff=porcelain "$base" "$head" -- \
  .github/workflows/hourly-product-development.yml .github/workflows/release.yml |
  awk '
    /^[-+][^+-]/ {
      line=$0
      sub(/^[-+]/, "", line)
      if (line != "          allowed-endpoints: |" && line != "          allowed-endpoints: >-") {
        print "unexpected changed workflow line: " $0
        bad=1
      }
    }
    END { if (bad) exit 1; print "only allowed-endpoints scalar markers changed" }
  '

echo '== Current remaining check and review state =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '.check_runs[] | select(.name == "strix") | {name,status,conclusion,started_at,completed_at,details_url}'
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,reviews,latestReviews \
  --jq '{headRefOid,mergeStateStatus,reviewDecision,reviews:[.reviews[]? | {author:.author.login,state,commitId,submittedAt}],latestReviews:[.latestReviews[]? | {author:.author.login,state,commitId,submittedAt}]}'
gh api graphql -F owner='ContextualWisdomLab' -F name='ThreadWeave' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          comments(first: 20) {
            nodes { author { login } commit { oid } path line body }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'

Length of output: 4190


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/ThreadWeave'
pr='24'
head='507f6fef013d0a193f6626ecd680d081333eab5e'
base='e9e52e4cae47c1c0164a37ed907719f5e899caf5'

echo '== Exact endpoint equality for Harden Runner jobs =='
python3 - <<'PY'
import re
import subprocess

base = "e9e52e4cae47c1c0164a37ed907719f5e899caf5"
head = "507f6fef013d0a193f6626ecd680d081333eab5e"
expected_jobs = {
    ".github/workflows/hourly-product-development.yml": (
        "develop-product-gap", "reverify-product-gap", "publish-product-gap",
    ),
    ".github/workflows/release.yml": (
        "build-release", "attest-release", "tag-release", "github-release", "publish-pypi",
    ),
}

def read(revision, path):
    return subprocess.check_output(["git", "show", f"{revision}:{path}"], text=True)

def jobs(text):
    section = text.split("\njobs:\n", 1)[1]
    starts = list(re.finditer(r"(?m)^  ([a-z][a-z0-9-]+):\n", section))
    blocks = {}
    for index, match in enumerate(starts):
        end = starts[index + 1].start() if index + 1 < len(starts) else len(section)
        blocks[match.group(1)] = section[match.start():end]
    return blocks

def endpoints(block):
    match = re.search(
        r"(?m)^          allowed-endpoints: ([|>][-+]?)\n"
        r"((?:            \S.*\n)+)",
        block,
    )
    assert match, "allowed-endpoints block not found"
    marker, lines = match.groups()
    return marker, tuple(line.strip() for line in lines.splitlines())

for path, names in expected_jobs.items():
    old, new = jobs(read(base, path)), jobs(read(head, path))
    print(path)
    for name in names:
        old_marker, old_endpoints = endpoints(old[name])
        new_marker, new_endpoints = endpoints(new[name])
        assert old_marker == "|", (path, name, old_marker)
        assert new_marker == ">-", (path, name, new_marker)
        assert old_endpoints == new_endpoints, (path, name, old_endpoints, new_endpoints)
        assert len(new_endpoints) == len(set(new_endpoints)), (path, name, "duplicate endpoint")
        assert "egress-policy: block" in new[name], (path, name, "egress policy")
        print(f"  {name}: endpoint_count={len(new_endpoints)} exact_membership_unchanged=true")
print("all eight endpoint blocks retain exact base membership and block egress")
PY

echo '== Workflow changes are limited to scalar markers =='
git diff --word-diff=porcelain "$base" "$head" -- \
  .github/workflows/hourly-product-development.yml .github/workflows/release.yml |
  awk '
    /^[-+][^+-]/ {
      line=$0
      sub(/^[-+]/, "", line)
      if (line != "          allowed-endpoints: |" && line != "          allowed-endpoints: >-") {
        print "unexpected changed workflow line: " $0
        bad=1
      }
    }
    END { if (bad) exit 1; print "only allowed-endpoints scalar markers changed" }
  '

echo '== Current remaining check and review state =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '.check_runs[] | select(.name == "strix") | {name,status,conclusion,started_at,completed_at,details_url}'
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,reviews,latestReviews \
  --jq '{headRefOid,mergeStateStatus,reviewDecision,reviews:[.reviews[]? | {author:.author.login,state,commitId,submittedAt}],latestReviews:[.latestReviews[]? | {author:.author.login,state,commitId,submittedAt}]}'
gh api graphql -F owner='ContextualWisdomLab' -F name='ThreadWeave' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          comments(first: 20) {
            nodes { author { login } commit { oid } path line body }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'

Length of output: 5652


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/ThreadWeave'
pr='24'
head='507f6fef013d0a193f6626ecd680d081333eab5e'

echo '== Exact-head check status =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '.check_runs | sort_by(.name)[] |
    {name,status,conclusion,started_at,completed_at,details_url}'

echo '== Current pull request identity and formal reviews =='
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,reviews,latestReviews \
  --jq '{headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,reviews:[.reviews[]? | {author:.author.login,state,commitId,submittedAt,body}],latestReviews:[.latestReviews[]? | {author:.author.login,state,commitId,submittedAt,body}]}'

echo '== Current unresolved review threads =='
gh api graphql -F owner='ContextualWisdomLab' -F name='ThreadWeave' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          comments(first: 20) {
            nodes {
              author { login }
              body
              commit { oid }
              path
              line
              originalLine
              createdAt
            }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'

echo '== Branch and ruleset policy visibility =='
gh api "repos/$repo/branches/main/protection" \
  --jq '{required_status_checks,required_pull_request_reviews,required_signatures,enforce_admins}' \
  || true
gh api "repos/$repo/rules/branches/main" --jq '.' || true

Length of output: 12479


@seonghobae Review complete for exact head 507f6fef013d0a193f6626ecd680d081333eab5e against base e9e52e4cae47c1c0164a37ed907719f5e899caf5.

I found no source-level findings in the requested scope.

  • The checked-out revision equals the requested head.
  • The requested base is the merge base.
  • The Hourly Product Development workflow uses allowed-endpoints: >- in all three Harden Runner jobs.
  • The Release workflow uses allowed-endpoints: >- in all five Harden Runner jobs.
  • All eight endpoint lists have exact base-equivalent membership.
  • The endpoint counts remain 13, 10, and 7 for Hourly Product Development.
  • The endpoint counts remain 9, 10, 5, 8, and 6 for Release.
  • All eight Harden Runner jobs retain egress-policy: block.
  • The workflow diff changes only the endpoint scalar serialization. It adds no endpoints, wildcard entries, credentials, permissions, or publication authority.
  • The Hourly Product Development gate exits with open_pull_request, release_blocker, or dry_run before it evaluates NIM_UPSTREAM_API_KEY.
  • The NVIDIA credential remains limited to the model-backed development path.
  • The downstream reverification and publication jobs remain free of the NVIDIA model credential.
  • CI run 31257510926 succeeded on the requested head.
  • SAST run 31257510919 succeeded on the requested head.
  • Security Scan run 31257510936 succeeded on the requested head.
  • The pull request has no formal review submissions.
  • The pull request has no unresolved review threads.
  • The visible organization ruleset requires resolved review threads and requires zero approving reviews.

I did not submit APPROVE.

The remaining gate is strix. It is still in_progress on the requested head. The pull request state is BLOCKED. The branch-protection API returned HTTP 403, so its settings remain unavailable through this integration.

You are interacting with an AI system.

@seonghobae seonghobae changed the title fix(ci): preserve Harden Runner endpoint ports at runtime fix(ci): harden hourly automation boundaries Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

@opencode-agent @cwl-noema-review @coderabbitai review

Review-only request for exact current head a012550f6e6ec9941348aa84707bd3c0388eb4eb against protected base e9e52e4cae47c1c0164a37ed907719f5e899caf5. Do not mutate the branch or merge. Revalidate all three incident boundaries: (1) the Hourly Product Development and manual release Harden Runner endpoint scalars are folded and retain their exact fail-closed endpoint sets; (2) deterministic open-PR/release-blocker/dry-run decisions remain ahead of NVIDIA_NIM_API_KEY, which is limited to the actual model path; and (3) Hourly PR Maintenance invokes only immutable-pinned central pr-review-merge-scheduler.yml@3f65dbee6672b78802e7d71d49c390f3817bb03b, forwards no repository secrets, has no duplicate review-fix job or mutable @main, and uses least-required caller/job permissions. Inspect exact-head CI 31258267499, SAST 31258267481, Security Scan 31258267488, the full current diff, all formal review submissions, and all review threads. Submit a formal non-author GitHub APPROVE only if this exact head is clean and repository policy permits it; otherwise report the precise remaining gate.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/ThreadWeave'
pr='24'
head='a012550f6e6ec9941348aa84707bd3c0388eb4eb'
base='e9e52e4cae47c1c0164a37ed907719f5e899caf5'

echo '== Revision identity and full change set =='
printf 'checked_out='; git rev-parse HEAD
git cat-file -t "$head"
git cat-file -t "$base"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=yes'
printf 'merge_base='; git merge-base "$base" "$head"
git diff --check "$base" "$head"
git diff --name-status "$base" "$head"
git diff --unified=50 "$base" "$head"

echo '== Candidate workflow and contract files =='
fd -t f .github tests | rg -i '(hourly|release|harden|egress|endpoint|maintenance|scheduler|contract)' || true

echo '== Workflow outlines =='
fd -t f -e yml -e yaml .github/workflows -x ast-grep outline {} --items all 2>/dev/null || true

echo '== Harden Runner blocks and model-gate ordering =='
rg -n -A45 -B6 'uses:\s*step-security/harden-runner|egress-policy:|allowed-endpoints:' \
  .github/workflows/hourly-product-development.yml .github/workflows/release.yml
rg -n -A115 -B10 'open_pull_request|release_blocker|dry_run|NIM_UPSTREAM_API_KEY|NVIDIA_NIM_API_KEY|integrate\.api\.nvidia\.com' \
  .github/workflows/hourly-product-development.yml

echo '== Hourly PR Maintenance delegation, permissions, secrets, and refs =='
fd -t f .github/workflows | rg -i 'hourly.*pr.*maintenance|pr.*maintenance' | while read -r file; do
  echo "--- $file"
  cat -n "$file"
done
rg -n -A18 -B8 'pr-review-(fix|merge)-scheduler|secrets:\s*inherit|permissions:|`@main`|3f65dbee6672b78802e7d71d49c390f3817bb03b|issues:\s*write' \
  .github/workflows

echo '== Static endpoint and delegation assertions =='
python3 - <<'PY'
from pathlib import Path
import re
import subprocess

base = "e9e52e4cae47c1c0164a37ed907719f5e899caf5"
head = "a012550f6e6ec9941348aa84707bd3c0388eb4eb"
workflow_paths = (
    ".github/workflows/hourly-product-development.yml",
    ".github/workflows/release.yml",
)

def read(revision, path):
    return subprocess.check_output(["git", "show", f"{revision}:{path}"], text=True)

def job_blocks(text):
    section = text.split("\njobs:\n", 1)[1]
    matches = list(re.finditer(r"(?m)^  ([a-z][a-z0-9-]+):\n", section))
    return {
        match.group(1): section[match.start(): matches[index + 1].start() if index + 1 < len(matches) else len(section)]
        for index, match in enumerate(matches)
    }

def endpoints(block):
    match = re.search(
        r"(?m)^          allowed-endpoints: ([|>][-+]?)\n((?:            \S.*\n)+)",
        block,
    )
    assert match, "missing allowed-endpoints"
    return match.group(1), tuple(line.strip() for line in match.group(2).splitlines())

for path in workflow_paths:
    old, new = job_blocks(read(base, path)), job_blocks(read(head, path))
    print(path)
    for name, block in new.items():
        if "allowed-endpoints:" not in block:
            continue
        old_marker, old_members = endpoints(old[name])
        marker, members = endpoints(block)
        assert old_marker == "|", (path, name, old_marker)
        assert marker == ">-", (path, name, marker)
        assert old_members == members, (path, name, "membership changed")
        assert len(members) == len(set(members)), (path, name, "duplicate member")
        assert "egress-policy: block" in block, (path, name, "egress not blocked")
        print(f"  {name}: marker={marker} endpoint_count={len(members)} base_membership_equal=true")
print("endpoint serialization and membership assertions passed")

maintenance_candidates = list(Path(".github/workflows").glob("*"))
maintenance = [
    path for path in maintenance_candidates
    if path.is_file() and "pr" in path.name.lower() and "maintenance" in path.name.lower()
]
assert len(maintenance) == 1, [str(p) for p in maintenance]
text = maintenance[0].read_text()
assert "pr-review-fix-scheduler.yml" not in text
assert "pr-review-merge-scheduler.yml@main" not in text
assert "pr-review-merge-scheduler.yml@3f65dbee6672b78802e7d71d49c390f3817bb03b" in text
assert "secrets: inherit" not in text
assert re.search(r"(?m)^permissions:\n  contents: read\s*$", text)
assert "issues: write" not in text
for permission in (
    "actions: write", "checks: read", "contents: write", "id-token: write",
    "pull-requests: write", "statuses: read",
):
    assert permission in text, permission
print(f"{maintenance[0]}: immutable secretless single-scheduler and permission assertions passed")
PY

echo '== Requested workflow runs =='
for run in 31258267499 31258267481 31258267488; do
  gh api "repos/$repo/actions/runs/$run" \
    --jq '{id,name,event,status,conclusion,head_sha,head_branch,run_started_at,updated_at,html_url}'
  gh api "repos/$repo/actions/runs/$run/jobs?per_page=100" \
    --jq '.jobs[] | {name,status,conclusion,started_at,completed_at,html_url}'
done

echo '== Exact-head checks, PR state, reviews, and unresolved threads =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '.check_runs | sort_by(.name)[] | {name,status,conclusion,details_url}'
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,reviews,latestReviews,statusCheckRollup \
  --jq '{headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,reviews:[.reviews[]? | {author:.author.login,state,commitId,submittedAt,body}],latestReviews:[.latestReviews[]? | {author:.author.login,state,commitId,submittedAt}],checks:[.statusCheckRollup[]? | {name,status,conclusion,detailsUrl}]}'
gh api graphql -F owner='ContextualWisdomLab' -F name='ThreadWeave' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          comments(first: 30) {
            nodes { author { login } body commit { oid } path line originalLine createdAt }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'

echo '== Branch protection and ruleset visibility =='
gh api "repos/$repo/branches/main/protection" \
  --jq '{required_status_checks,required_pull_request_reviews,required_signatures,enforce_admins}' || true
gh api "repos/$repo/rules/branches/main" --jq '.' || true

Length of output: 111820


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/ThreadWeave'
pr='24'
head='a012550f6e6ec9941348aa84707bd3c0388eb4eb'
base='e9e52e4cae47c1c0164a37ed907719f5e899caf5'

echo '== Hourly PR Maintenance exact content =='
cat -n .github/workflows/hourly-pr-maintenance.yml

echo '== Static endpoint and delegation assertions =='
python3 - <<'PY'
from pathlib import Path
import re
import subprocess

base = "e9e52e4cae47c1c0164a37ed907719f5e899caf5"
head = "a012550f6e6ec9941348aa84707bd3c0388eb4eb"
workflow_paths = (
    ".github/workflows/hourly-product-development.yml",
    ".github/workflows/release.yml",
)

def read(revision, path):
    return subprocess.check_output(["git", "show", f"{revision}:{path}"], text=True)

def job_blocks(text):
    section = text.split("\njobs:\n", 1)[1]
    matches = list(re.finditer(r"(?m)^  ([a-z][a-z0-9-]+):\n", section))
    return {
        match.group(1): section[
            match.start(): matches[index + 1].start()
            if index + 1 < len(matches) else len(section)
        ]
        for index, match in enumerate(matches)
    }

def endpoints(block):
    match = re.search(
        r"(?m)^          allowed-endpoints: ([|>][-+]?)\n((?:            \S.*\n)+)",
        block,
    )
    assert match, "missing allowed-endpoints"
    return match.group(1), tuple(line.strip() for line in match.group(2).splitlines())

for path in workflow_paths:
    old, new = job_blocks(read(base, path)), job_blocks(read(head, path))
    print(path)
    for name, block in new.items():
        if "allowed-endpoints:" not in block:
            continue
        old_marker, old_members = endpoints(old[name])
        marker, members = endpoints(block)
        assert old_marker == "|", (path, name, old_marker)
        assert marker == ">-", (path, name, marker)
        assert old_members == members, (path, name, "membership changed")
        assert len(members) == len(set(members)), (path, name, "duplicate member")
        assert "egress-policy: block" in block, (path, name, "egress not blocked")
        print(f"  {name}: marker={marker} endpoint_count={len(members)} base_membership_equal=true")
print("endpoint serialization and membership assertions passed")

maintenance = Path(".github/workflows/hourly-pr-maintenance.yml")
text = maintenance.read_text()
assert "pr-review-fix-scheduler.yml" not in text
assert "pr-review-merge-scheduler.yml@main" not in text
assert "pr-review-merge-scheduler.yml@3f65dbee6672b78802e7d71d49c390f3817bb03b" in text
assert "secrets: inherit" not in text
assert re.search(r"(?m)^permissions:\n  contents: read\s*$", text)
assert "issues: write" not in text
for permission in (
    "actions: write", "checks: read", "contents: write", "id-token: write",
    "pull-requests: write", "statuses: read",
):
    assert permission in text, permission
print(f"{maintenance}: immutable secretless single-scheduler and permission assertions passed")
PY

echo '== Requested workflow runs =='
for run in 31258267499 31258267481 31258267488; do
  gh api "repos/$repo/actions/runs/$run" \
    --jq '{id,name,event,status,conclusion,head_sha,head_branch,run_started_at,updated_at,html_url}'
  gh api "repos/$repo/actions/runs/$run/jobs?per_page=100" \
    --jq '.jobs[] | {name,status,conclusion,started_at,completed_at,html_url}'
done

echo '== Exact-head checks and PR state =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '.check_runs | sort_by(.name)[] | {name,status,conclusion,details_url}'
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,reviews,latestReviews,statusCheckRollup \
  --jq '{headRefOid,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,reviews:[.reviews[]? | {author:.author.login,state,commitId,submittedAt,body}],latestReviews:[.latestReviews[]? | {author:.author.login,state,commitId,submittedAt}],checks:[.statusCheckRollup[]? | {name,status,conclusion,detailsUrl}]}'

echo '== Unresolved review threads =='
gh api graphql -F owner='ContextualWisdomLab' -F name='ThreadWeave' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          isOutdated
          comments(first: 30) {
            nodes { author { login } body commit { oid } path line originalLine createdAt }
          }
        }
      }
    }
  }
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'

echo '== Branch protection and ruleset visibility =='
gh api "repos/$repo/branches/main/protection" \
  --jq '{required_status_checks,required_pull_request_reviews,required_signatures,enforce_admins}' || true
gh api "repos/$repo/rules/branches/main" --jq '.' || true

Length of output: 25940


@seonghobae Review complete for exact head a012550f6e6ec9941348aa84707bd3c0388eb4eb against base e9e52e4cae47c1c0164a37ed907719f5e899caf5.

I found no source-level findings in the requested scope.

  • The checked-out revision equals the requested head.
  • The requested base is the merge base.
  • All three Hourly Product Development and five Release Harden Runner endpoint blocks use allowed-endpoints: >-.
  • All eight endpoint sets exactly match their base-revision membership.
  • All eight Harden Runner jobs retain egress-policy: block.
  • The product-development endpoint counts remain 13, 10, and 7.
  • The release endpoint counts remain 9, 10, 5, 8, and 6.
  • open_pull_request, release_blocker, and dry_run each exit before the NIM_UPSTREAM_API_KEY check.
  • The NVIDIA credential remains limited to the model-backed development path.
  • The downstream reverification and publication jobs do not reference the NVIDIA credential.
  • .github/workflows/hourly-pr-maintenance.yml invokes only pr-review-merge-scheduler.yml@3f65dbee6672b78802e7d71d49c390f3817bb03b.
  • The caller has no pr-review-fix-scheduler.yml, mutable @main reference, or secrets: inherit.
  • The caller default permission is contents: read.
  • The reusable job has only actions: write, checks: read, contents: write, id-token: write, pull-requests: write, and statuses: read.
  • The requested CI run 31258267499, SAST run 31258267481, and Security Scan run 31258267488 succeeded on the requested head.
  • There are no formal review submissions and no unresolved review threads.

I did not submit APPROVE.

The remaining gate is strix. It is still in_progress on the exact head. PR #24 is BLOCKED.

The organization ruleset requires resolved review threads and requires zero approvals. The branch-protection API returned HTTP 403, so I could not verify additional branch-protection requirements through this integration.

You are interacting with an AI system.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

The stated rate-limit window has elapsed. Perform one full review of exact unchanged head a012550f6e6ec9941348aa84707bd3c0388eb4eb against base e9e52e4cae47c1c0164a37ed907719f5e899caf5. Treat every predecessor-head, status-only, pending, and rate-limit artifact as non-passing. Revalidate the folded Harden Runner runtime contract for all three hourly and five release endpoint blocks, exact endpoint membership, deterministic gates before NVIDIA_NIM_API_KEY, and the immutable secretless single central maintenance scheduler. Do not mutate or merge the branch. Submit a formal non-author GitHub APPROVE only if this exact head is clean and policy permits it; otherwise report the precise current-head finding or gate.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Your plan includes PR reviews subject to rate limits. More reviews will be available in 36 minutes.

Copy link
Copy Markdown
Contributor Author

Fleet-incident RCA handoff for exact unchanged head a012550f6e6ec9941348aa84707bd3c0388eb4eb / base e9e52e4cae47c1c0164a37ed907719f5e899caf5: the current workflow still violates the claimed credential boundary. In .github/workflows/hourly-product-development.yml, the step Enforce the credential and pull-request-first gate binds NIM_UPSTREAM_API_KEY: ${{ secrets.NVIDIA_NIM_API_KEY }} in the step environment before the shell evaluates open_pull_request, release_blocker, or dry_run. Shell ordering therefore does not prevent Actions from materializing the model secret on deterministic-stop runs.

Immediate cause: secret binding is attached to the deterministic gate step rather than to a later model-only step. Systemic cause: the regression in tests/test_hourly_product_egress_contract.py::_assert_deterministic_gate_contract proves only that deterministic shell branches appear before the shell-level if [ -z "${NIM_UPSTREAM_API_KEY:-}" ]; it does not assert that the gate step/job has no secrets.NVIDIA_NIM_API_KEY binding. Detection failure: exact-head CI can therefore be green while the credential-authority claim in the PR body is false.

Please treat this as a merge blocker and repair it test-first under the repository owner lease: first add a regression that the deterministic gate block contains no NVIDIA_NIM_API_KEY/NIM_UPSTREAM_API_KEY secret binding and that the credential is introduced only in a separately conditional model-path step; observe RED on this exact source; then make the smallest workflow change, rerun focused + full exact-head CI/security/review, and update the PR evidence. Preserve fail-closed egress and the existing exact endpoint sets. Do not merge on the current green checks alone.

Copy link
Copy Markdown
Contributor Author

@opencode-agent

Implementation request for exact current head 3774761db54601cbea3a6d800c608f9f59b8abef on branch fix/hourly-egress-folded-endpoints. This is a bounded source-write handoff; do not merge, rebase, force-push, broaden egress, alter permissions, add secrets/PATs, or touch unrelated files. Refetch the exact head immediately before mutation and abort if it moved.

The fail-first regression is already committed and authoritative: CI run 31266002458 fails exactly test_model_secret_is_materialized_only_after_deterministic_gate_selects_model_path on all Python matrix jobs because the Enforce the credential and pull-request-first gate step materializes NIM_UPSTREAM_API_KEY: ${{ secrets.NVIDIA_NIM_API_KEY }} in step env before the shell can execute open_pull_request, release_blocker, or dry_run exits. This proves shell statement ordering is not an Actions credential-boundary guarantee.

Implement the smallest complete root-cause repair in only .github/workflows/hourly-product-development.yml and tests/test_hourly_product_egress_contract.py:

  1. Make the deterministic gate step credential-free: keep GH_TOKEN and DRY_RUN, remove all NIM_UPSTREAM_API_KEY/secrets.NVIDIA_NIM_API_KEY references and remove the missing-NVIDIA branch from that step. Preserve the current GitHub inventory/release-blocker/dry-run behavior and develop=true/reason=ready output.
  2. Immediately after that gate, add a distinct step named exactly Require the NVIDIA credential for model-backed development, guarded by if: steps.gate.outputs.develop == 'true'. Bind NIM_UPSTREAM_API_KEY: ${{ secrets.NVIDIA_NIM_API_KEY }} only there. If it is empty, emit a visible ::error:: and exit 1; missing model authority after model-path selection is failure, not a green no-op.
  3. Update the existing contract helper so deterministic-gate assertions end at the new credential step and no longer search for a credential check inside the gate. Keep the committed RED regression and make it pass. Preserve the existing folded Harden Runner endpoint sets exactly, egress-policy: block, action pins, broker scoping, downstream credential-free jobs, and all other behavior.
  4. Run the focused contract test first, then the complete repository validation. Commit only when GREEN. Report the resulting exact head and verification evidence in this thread. Do not attempt the separate 45-minute-vs-3x35-minute fallback-budget defect in this change; that will be handled as the next causal slice after this boundary is green.

Copy link
Copy Markdown
Contributor Author

@opencode-agent Implementation request for exact current head a6ee115042cab74efa078171f7b75da19befadef on branch fix/hourly-egress-folded-endpoints. This is a bounded branch-write request; first refetch the exact head and abort without writing if it moved.

RCA and required scope:

  1. Proven schedulability defect. Exact-head CI 31276613811 reaches the intended RED contract test_model_fallback_budget_fits_outer_job_timeout: the workflow allows three sequential model attempts at OPENCODE_RUN_TIMEOUT_SECONDS=2100 plus the test's 1800-second orchestration reserve, requiring 8100 seconds, while develop-product-gap is still timeout-minutes: 45 (2700 seconds). GitHub-hosted Actions permits a job timeout up to 360 minutes, so a 180-minute outer budget is operationally feasible and preserves the existing bounded per-model attempts. The fail-first regression already exists. Make the smallest production repair: change only this job's outer timeout from 45 to 180 minutes unless fresh exact-head evidence proves a different bounded value is required.

  2. Current valid CodeRabbit contract findings. Strengthen tests, without broadening runtime authority or endpoint sets, so that:

    • the review-merge reusable-workflow caller rejects any job-level secrets: mapping, not only secrets: inherit, in both tests/test_hourly_pr_maintenance_contract.py and tests/test_workflows.py;
    • each manual release Harden Runner job is parsed/asserted independently for its exact expected allowed-endpoints set and egress-policy: block, preserving the existing folded-scalar assertions;
    • tests/test_workflows.py proves NIM_UPSTREAM_API_KEY / ${{ secrets.NVIDIA_NIM_API_KEY }} are absent from job-level env and the deterministic gate, exactly one raw-secret binding exists only on the conditional credential-broker/model path, and fingerprint scan is step-scoped before proposal upload/reverification/publication so scan failure cannot reach apply/publish.
      These are security-contract hardening changes; do not change production behavior merely to satisfy a brittle string count if structured parsing can prove the boundary more directly.
  3. Exact-head CI also showed test_proposal_validation_rejects_unsafe_metadata failing because a fixture-local git clone --local --no-hardlinks exited 128 in one matrix run. Reproduce/isolate this separately. Do not patch product code or weaken the test unless the clone failure is deterministic and its root cause is established; if it is transient/environmental, leave source unchanged and let exact-head rerun evidence classify it.

  4. The open GHAS SHA-256 thread is not authorization to swap or suppress cryptography. secret_fingerprint_guard.py uses SHA-256 only as an exact-equality confirmation for a high-entropy API-key leak detector after a rolling-hash prefilter; it is not password/KDF storage. Verify that threat model before any change. Do not add a weaker/custom hash, raw-secret rematerialization, scanner suppression, or a new credential solely to silence the alert.

Preserve fail-closed Harden Runner egress, the exact current endpoint sets and immutable action pins, deterministic gates before NVIDIA credential materialization, pristine per-model workspaces, 100% production statement/branch coverage, and the existing central-scheduler authority boundary. Run focused contract tests first, then Ruff/actionlint/full Python matrix-equivalent tests and security-relevant validation available locally. Commit only the smallest coherent correction to this existing branch. Do not merge, change reviewer/governance policy, create repair workflows, or touch another repository.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 136-137: release workflow의 printf 블록에서 형식 문자열의 YAML 블록 스칼라 들여쓰기를
올바르게 맞추고, `\n` 이스케이프를 동일한 printf 형식 문자열 안에 포함하도록 수정하세요.

In `@tests/test_ci_autonomous_coverage_contract.py`:
- Around line 17-25: Update
test_ci_and_release_cover_secret_guard_in_focused_boundary_suite to inspect each
workflow’s actual coverage run and coverage report command blocks rather than
searching the entire workflow text. Assert SECRET_GUARD_TEST is included in the
focused pytest arguments, and assert SECRET_GUARD_SOURCE plus --fail-under=100
are present in the corresponding coverage report --include command.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f6efb0dd-2fa9-42df-82e5-1516cc3753ea

📥 Commits

Reviewing files that changed from the base of the PR and between f8b19e3 and c0f88b9.

📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • tests/test_ci_autonomous_coverage_contract.py
  • tests/test_hourly_pr_maintenance_contract.py
  • tests/test_release_workflow.py
  • tests/test_workflows.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/test_hourly_pr_maintenance_contract.py
  • tests/test_workflows.py

Comment thread .github/workflows/release.yml Outdated
Comment thread tests/test_ci_autonomous_coverage_contract.py Outdated
@seonghobae
seonghobae force-pushed the fix/hourly-egress-folded-endpoints branch from c0f88b9 to dd9053c Compare August 8, 2026 21:22

Copy link
Copy Markdown
Contributor Author

@opencode-agent @cwl-noema-review

Review-only request for exact current head 3305c08e6372cfc213fdc7055f3e5dfa5d56387d over protected base e9e52e4cae47c1c0164a37ed907719f5e899caf5. Do not mutate, merge, rebase, or otherwise write the branch.

Revalidate the full current incident scope, including: folded >- Harden Runner endpoint serialization with the exact reviewed fail-closed endpoint sets; deterministic open-PR/release-blocker/dry-run gates before any NVIDIA credential materialization; model credential confinement to the conditional model/broker path; fingerprint-only post-model leak detection; realistic 180-minute outer fallback budget; immutable/secretless Hourly PR Maintenance caller; and the current release-workflow/coverage-contract fixes. Current exact-head repository runs are CI 31279262816, SAST 31279262812, and Security Scan 31279262818, all terminal-success at the last refetch; all returned inline review threads were resolved. Treat predecessor-head reviews as stale and inspect the exact current diff and exact-head evidence independently. Report any valid blocker precisely; do not synthesize or impersonate a human approval.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode could not approve from deterministic current-head evidence because GitHub Checks have failed.

Findings

1. HIGH Current-head GitHub Checks - Fix failed required checks before approval

  • Problem: Failed same-head checks remain for 3305c08e6372cfc213fdc7055f3e5dfa5d56387d.
  • Root cause: The model-unavailable evidence fallback is allowed only when peer GitHub Checks are complete and clean.
  • Fix: Read and fix the failed check logs below, then rerun the current-head checks.
  • Regression test: Keep the model-unavailable fallback gated on an empty failed-check rollup.

Failed checks:

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow (4 files)"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow (4 files)"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["CI script: secret_fingerprint_guard.py"]
  S2 --> I2["review and security gate shell path"]
  I2 --> R2["Review risk: CI script: secret_fingerprint_guard.py"]
  R2 --> V2["bash -n plus Strix self-test"]
  Evidence --> S3["Test (6 files)"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test (6 files)"]
  R3 --> V3["targeted test run"]
Loading

@opencode-agent

opencode-agent Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: f4c85f701e76c410c6c048c2d6566e8f8868b21b
  • Workflow run: 31300878686
  • Workflow attempt: 1
  • Gate result: APPROVE (exit 0)

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow (4 files)"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow (4 files)"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["CI script: secret_fingerprint_guard.py"]
  S2 --> I2["review and security gate shell path"]
  I2 --> R2["Review risk: CI script: secret_fingerprint_guard.py"]
  R2 --> V2["bash -n plus Strix self-test"]
  Evidence --> S3["Test (8 files)"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test (8 files)"]
  R3 --> V3["targeted test run"]
Loading

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode could not approve from deterministic current-head evidence because GitHub Checks have failed.

Findings

1. HIGH Current-head GitHub Checks - Fix failed required checks before approval

  • Problem: Failed same-head checks remain for 3305c08e6372cfc213fdc7055f3e5dfa5d56387d.
  • Root cause: The model-unavailable evidence fallback is allowed only when peer GitHub Checks are complete and clean.
  • Fix: Read and fix the failed check logs below, then rerun the current-head checks.
  • Regression test: Keep the model-unavailable fallback gated on an empty failed-check rollup.

Failed checks:

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow (4 files)"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow (4 files)"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["CI script: secret_fingerprint_guard.py"]
  S2 --> I2["review and security gate shell path"]
  I2 --> R2["Review risk: CI script: secret_fingerprint_guard.py"]
  R2 --> V2["bash -n plus Strix self-test"]
  Evidence --> S3["Test (6 files)"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test (6 files)"]
  R3 --> V3["targeted test run"]
Loading

Copy link
Copy Markdown
Contributor Author

@opencode-agent review-only request for exact current head a0e9dad19e33b895ddd1f040194443e3638e8d87 over live main e9e52e4cae47c1c0164a37ed907719f5e899caf5. Repository CI, SAST Semgrep, and Security Scan are successful on this exact head; prior CHANGES_REQUESTED submissions reference predecessor 3305c08e6372cfc213fdc7055f3e5dfa5d56387d and must not be transferred. Independently inspect the full current diff, especially fail-closed Harden Runner endpoint serialization, secret-fingerprint boundary, immutable/secretless PR-maintenance caller, release workflow syntax, and exact-head coverage contracts. Do not mutate the branch, change ready state, merge, or bypass protections; submit only a formal current-head verdict.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode reviewed the current-head bounded evidence and found no blocking issues.

Findings

No blocking findings.

Summary

Approved after inspection of changed files .github/workflows/hourly-product-development.yml, .github/workflows/hourly-pr-maintenance.yml, .github/workflows/ci.yml, .github/workflows/release.yml, scripts/ci/secret_fingerprint_guard.py, and the new contract tests. PR intent (harden hourly automation boundaries after fleet incident #22) matches the diff: folded allowed-endpoints: >- scalars, credential removed from the deterministic gate and capture step, fingerprint-only scan boundary, secretless pinned maintenance caller, job-scoped permissions. Approval sufficiency: bounded evidence affirmatively supports intent; no unresolved threads and no completed failed GitHub Checks at head f4c85f7 (predecessor CHANGES_REQUESTED reviews citing failed checks are superseded). Verification posture: Coverage execution evidence reports Result PASS (python3 -m coverage run -m pytest tests; python3 -m coverage report --show-missing --fail-under=100) and CI focused autonomous coverage now includes tests/test_hourly_product_secret_fingerprint.py and scripts/ci/secret_fingerprint_guard.py at --fail-under=100. Linter/static: ruff contract defined (python3 -m ruff check .); CodeQL fingerprint disposition pinned by tests/test_codeql_fingerprint_suppression_contract.py. TDD/regression: contract-first tests for every changed boundary — endpoint delimiter/lookalike rejection and fallback budget (tests/test_hourly_product_egress_contract.py), secretless maintenance contract (tests/test_hourly_pr_maintenance_contract.py), rolling-hash collision continuation (tests/test_secret_fingerprint_collision_regression.py), fingerprint broker boundary (tests/test_hourly_product_secret_fingerprint.py). Coverage: 100% threshold for scripts/ci including the new guard, per Coverage execution evidence PASS. Docstring coverage: configured repository docstring gates passed or advisory per Coverage execution evidence. DAG: source-backed head-flow flowchart (deterministic gate -> broker[fingerprint] -> agent -> capture -> scan -> upload -> reverify -> publish; secretless maintenance caller -> pinned scheduler @3f65dbee), reflecting the head flow vs base (base gate materialized the secret and capture bound THREADWEAVE_FORBIDDEN_SECRET). PoC/execution: no OPENCODE_EXECUTION_RECEIPT runtime receipts are present in bounded evidence; Harden Runner agent runtime delimiter behavior cannot be independently re-verified, stated as residual risk, not repository fact. DDD/domain: CI/automation domain, no domain-model changes. CDD/context: secrets no longer forwarded across workflow boundaries; egress allowlists exact per job. Similar issues: follow-up to incident #22; historical bot reviews do not corroborate current-head failures. Claim/concept check: exact per-job endpoint membership is pinned by verbatim CodeGraph test source (EXPECTED_ENDPOINTS exact set membership) and Coverage PASS. Standards search: no external standard asserted; endpoint membership unchanged (folding only), so no standards lookup is material. Compatibility/convention: naming review clean — fingerprint/scan subcommands, --output-file/--fingerprint-file/--file flags, forbidden_fingerprint_file env (multi-word snake_case); no single-word or reserved identifiers; no DB/API objects introduced. Breaking-change/backcompat: internal scheduled automation only; no public API changes; scheduler pinned from @main to full SHA is deliberate supply-chain hardening. Performance: timeout raised 45->180 minutes with asserted budget 32100s+1800s<=18060s; scan adds bounded fingerprint work. Developer experience: fail-closed ::error:: + exit 1 on missing NIM key replaces silent skip; maintenance caller reduced to one pinned job. User experience: non-web surface — workflow/CLI/test output only. Visual/DOM: non-web interaction surface (workflow YAML, CLI script, test output) reviewed; no DOM/ARIA surface in this PR. Accessibility/i18n: no UI changes. Supply-chain/license: actions pinned to full SHAs (harden-runner bf7454d0, checkout 3d3c42e5, upload-artifact 043fb46d, scheduler 3f65dbee); no new dependencies; pip_audit/bandit contracts defined. Packaging: unpackaged_source_surfaces empty; scripts/ci exercised under 100% CI coverage. Security/privacy: NVIDIA secret materialized only in the broker step after the deterministic gate, artifacts fingerprint-scanned before upload, caller no longer inherits secrets, top-level permissions narrowed to contents: read, per-job fail-closed egress.

Approval sufficiency: bounded evidence supplied affirmative approval evidence for changed files, coverage/docstring posture, risk surfaces, and current-head verification; approval is not based merely on the absence of known blockers.
Verification posture: CodeGraph evidence was initialized and bounded current-head evidence reviewed for changed-file evidence including .github/workflows/ci.yml, .github/workflows/hourly-pr-maintenance.yml, .github/workflows/hourly-product-development.yml, .github/workflows/release.yml, scripts/ci/secret_fingerprint_guard.py, and 8 more.
Linter/static: workflow/static review evidence is bounded by the current-head GitHub Checks gate and changed-file evidence.
TDD/regression: coverage execution evidence and focused changed hunks were reviewed from bounded-review-evidence.md.
Coverage: coverage execution evidence reports supported repository test suites passed.
Docstring coverage: coverage execution evidence reports configured repository docstring gates passed or docstring coverage was advisory.
DAG: CodeGraph/source-backed behavior map connects .github/workflows/ci.yml to the affected review, runtime, or workflow path and required checks.
PoC/execution: coverage-evidence job executed on the current head and reported PASS.
DDD/domain: workflow and repository-governance invariants were reviewed against changed files in bounded evidence.
CDD/context: CodeGraph evidence, changed-file history, and focused hunks were reviewed from bounded-review-evidence.md.
Similar issues: changed-file history evidence was reviewed for comparable local precedents.
Claim/concept check: bounded evidence, repository source, current-head workflow evidence, and, where numeric, scientific, statistical, or literature-backed claims are affected, original-paper/formula evidence and parameter-recovery expectations were used for claims.
Standards search: standards and external-source claims require trusted bounded source evidence prepared outside the isolated model process; no evidence-backed standards blocker is present in bounded evidence.
Compatibility/convention: changed workflow/script conventions, object naming, and reserved-word safety for schema/API/config/code surfaces were checked in bounded evidence.
Breaking-change/backcompat: deployment evidence and changed-file history were checked for backward-compatibility risk.
Performance: changed surfaces were checked for performance risk in bounded evidence.
Developer experience: changed automation, review, test, setup, and maintenance surfaces were checked for helpful or obstructive DX impact in bounded evidence.
User experience: connected user, operator, API, CLI, documentation, review-comment, status-check, rendering, and workflow-reader behavior was checked for contradictions against code, docs, and tests in bounded evidence.
Visual/DOM: deterministic repair does not infer browser runtime execution; source-backed DOM/UI evidence and trusted workflow receipts were reviewed when present, and non-web surfaces used API/CLI/log/docs/workflow evidence instead.
Accessibility/i18n: accessibility, localization, and human-readable text surfaces were checked where UI, CLI, API message, docs, logs, or review text changed.
Supply-chain/license: dependency, package, model, container, and external-tool changes were checked in bounded evidence.
Packaging: package, build, test, lint, and security contracts were checked in bounded evidence.
Security/privacy: workflow-token, review-gate, and repository-automation security/privacy boundaries were checked in bounded evidence.

Adversarial validation

{"status":"passed","probes":[{"path":".github/workflows/hourly-product-development.yml","line":38,"hypothesis":"The develop-product-gap job timeout budget cannot cover three sequential NVIDIA model fallback attempts plus orchestration reserve, so the scheduled run times out mid-pipeline (the defect class reported in incident run 31276613811).","attack_or_counterexample":"Worst-case wall time: 3 model candidates * OPENCODE_RUN_TIMEOUT_SECONDS=2100s + 30-minute orchestration reserve = 8100s (135 min) against the changed job timeout.","evidence":"Trusted source trace at .github/workflows/hourly-product-development.yml:38 observed the current-head hunk set timeout-minutes to 180 (changed from 45); the verbatim CodeGraph test source at tests/test_hourly_product_egress_contract.py:238 asserts job_timeout_minutes*60 >= len(candidates)*2100 + 1800 (180*60=10800 >= 8100) and Coverage execution evidence reports Result PASS with supported repository test suites passed, falsifying the timeout-exceeded hypothesis. source-line-sha256=c44ef41458433fff1a39b8ab1f5f850220add86444f3a0751d5e4bd668dfdda6","outcome":"falsified"},{"path":".github/workflows/hourly-pr-maintenance.yml","line":34,"hypothesis":"The hourly PR maintenance caller can still forward repository secrets to the central merge scheduler or grant it broad top-level permissions, so a compromised central workflow could exfiltrate secrets.","attack_or_counterexample":"Retain `secrets: inherit` and top-level write permissions while referencing the reusable scheduler by a floating @main ref.","evidence":"Trusted source trace at .github/workflows/hourly-pr-maintenance.yml:34 observed the current-head hunk confining write permissions to the review-merge job scope (line 34 is the job-scoped statuses: read entry), removing `secrets: inherit`, deleting the review-fix caller, reducing top-level permissions to contents: read, and pinning the reusable scheduler to full SHA 3f65dbee6672b78802e7d71d49c390f3817bb03b; tests/test_hourly_pr_maintenance_contract.py (new in this PR; history 'test(ci): reject explicit scheduler secret mappings') pins the secretless contract and Coverage execution evidence reports Result PASS, falsifying the secret-forwarding hypothesis. source-line-sha256=59c1506d593cce7b728b3deb936c0f45d561dffab8ac3df343180710c9b6d15e","outcome":"falsified"}],"residual_risk":"Harden Runner agent runtime delimiter/port behavior cannot be independently re-verified because no trusted execution receipt (OPENCODE_EXECUTION_RECEIPT) is present in bounded evidence; the fix is pinned by workflow-contract regression tests and CI green only. A scheduled run without NVIDIA_NIM_API_KEY now fails loudly (::error:: + exit 1) instead of silently skipping, a deliberate fail-closed posture change. The transient secret fingerprint file lives in RUNNER_TEMP and is removed after scan; the scan covers exactly the three packaged artifacts."}
  • Result: APPROVE
  • Reason: No confirmed defects across the changed workflow, script, and contract-test surfaces; current-head evidence shows no failed checks, no unresolved threads, Coverage execution evidence PASS, and both adversarial probes falsified.
  • Head SHA: f4c85f701e76c410c6c048c2d6566e8f8868b21b
  • Workflow run: 31300878686
  • Workflow attempt: 1

@opencode-agent
opencode-agent Bot dismissed stale reviews from themself August 9, 2026 08:54

Superseded automated OpenCode change request from a previous head; exact current head f4c85f7 has a later OpenCode approval.

@opencode-agent
opencode-agent Bot merged commit fb7dab5 into main Aug 9, 2026
36 checks passed
@opencode-agent
opencode-agent Bot deleted the fix/hourly-egress-folded-endpoints branch August 9, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants