Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3da6a25
feat(coverage): add bounded PyO3 peer-evidence gate
seonghobae Aug 5, 2026
4f972b5
test(coverage): prove PyO3 peer gate fail-closed
seonghobae Aug 5, 2026
02495f0
docs(coverage): record PyO3 peer-evidence boundary
seonghobae Aug 5, 2026
8b722be
docs(changelog): record PyO3 peer-evidence gate
seonghobae Aug 5, 2026
e7f6a2b
test(coverage): require repo-root-aware nested PyO3 trust boundaries
seonghobae Aug 6, 2026
a4538f5
fix(coverage): bind nested PyO3 trust paths to repository root
seonghobae Aug 6, 2026
34bf083
test(coverage): require PyO3 deferral integration and exact-head peer…
seonghobae Aug 6, 2026
4d54a38
ci(coverage): add permanent PyO3 peer-gate quality matrix
seonghobae Aug 6, 2026
84948a3
test(coverage): cover repo-root and default-source fail-closed branches
seonghobae Aug 6, 2026
44667f5
ci(coverage): verify exact-head PyO3 peer gate
seonghobae Aug 7, 2026
2fc66c6
ci: add temporary read-only source snapshot
seonghobae Aug 7, 2026
a95432c
test(coverage): expose peer-gate file race boundaries
seonghobae Aug 7, 2026
aaf8af8
docs(doctoring): record descriptor-safe peer evidence reads
seonghobae Aug 7, 2026
901349e
test(coverage): block requirements-directory peer deferral
seonghobae Aug 7, 2026
da4cf98
chore: add one-shot PyO3 workflow integration patcher
seonghobae Aug 7, 2026
1fe00a1
chore(coverage): remove unnecessary pull-request source snapshot
seonghobae Aug 7, 2026
f5f2f05
chore(coverage): remove PR-controlled PyO3 integration patcher
seonghobae Aug 7, 2026
e0ed79c
chore(coverage): remove duplicate PyO3 peer-gate quality workflow
seonghobae Aug 7, 2026
96f8f77
chore(coverage): stage PyO3 peer workflow integration
seonghobae Aug 7, 2026
0583fb7
chore(coverage): remove staged PyO3 integration patch artifact
seonghobae Aug 7, 2026
1f615f8
fix(ci): bound peer-gate actionlint scope
seonghobae Aug 12, 2026
64e8058
fix(review): close native peer evidence gaps
seonghobae Aug 12, 2026
308ea06
docs(coverage): cite CWE-829 for PyO3 peer evidence
seonghobae Aug 13, 2026
f687af9
fix(coverage): ignore prose under docs/requirements in PyO3 deferral
seonghobae Aug 13, 2026
36ada03
fix(coverage): accept only bounded relative requirement includes
seonghobae Aug 13, 2026
3b39db4
chore(pyo3): restore bounded peer-evidence scope
seonghobae Aug 15, 2026
07c1358
fix(pyo3): harden bounded peer-evidence reads
seonghobae Aug 20, 2026
30eb187
fix: close native peer gate coverage gaps
seonghobae Aug 20, 2026
1053a14
fix: complete native peer focused coverage
seonghobae Aug 20, 2026
6146bb9
test: cover bounded requirement includes portably
seonghobae Aug 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
238 changes: 237 additions & 1 deletion .github/workflows/opencode-review-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,7 @@ jobs:
summary_file="${RUNNER_TEMP}/coverage-evidence.md"
summary_output_file="${RUNNER_TEMP}/coverage-evidence-output.md"
failures=0
python_native_peer_check_required=0
r_peer_check_required=0

append() {
Expand Down Expand Up @@ -898,6 +899,104 @@ jobs:
rm -f "$log_file"
}

run_python_native_extension_classifier() {
local project_dir="$1"
local python_native_pytest_log="$2"
local python_native_changed_files="$3"
local python_native_pyproject_snapshot="$4"

[ -s "$python_native_pyproject_snapshot" ] || return 1
python3 -I "$GITHUB_WORKSPACE/scripts/ci/python_native_extension_peer_gate.py" \
classify-pytest \
--log "$python_native_pytest_log" \
--pyproject "$python_native_pyproject_snapshot" \
--logical-pyproject "$project_dir/pyproject.toml" \
--changed-files "$python_native_changed_files" \
--repo-root "$COVERAGE_SOURCE_WORKDIR"
}

run_python_test_and_capture() {
local label="$1"
local project_dir="$2"
shift 2
local python_native_pytest_log
local python_native_changed_files
local python_native_pyproject_snapshot
local rc

python_native_pytest_log="$(mktemp "$RUNNER_TEMP/python-native-pytest.XXXXXX")"
python_native_changed_files="$(mktemp)"
python_native_pyproject_snapshot="$(mktemp)"
changed_files_for_coverage >"$python_native_changed_files"
Comment thread
seonghobae marked this conversation as resolved.
chmod 0444 "$python_native_changed_files"
if [ -f "$project_dir/pyproject.toml" ] \
&& [ ! -L "$project_dir/pyproject.toml" ]; then
install -m 0444 -- \
"$project_dir/pyproject.toml" \
"$python_native_pyproject_snapshot"
fi

append "### ${label}"
append ""
append '```text'
append_command "$@"
set +e
timeout --kill-after=20 900 setpriv \
--reuid "$OPENCODE_SANDBOX_UID" \
--regid "$OPENCODE_SANDBOX_GID" \
--clear-groups \
env \
-u ACTIONS_ID_TOKEN_REQUEST_TOKEN \
-u ACTIONS_ID_TOKEN_REQUEST_URL \
-u ACTIONS_RUNTIME_TOKEN \
-u GH_TOKEN \
-u GITHUB_TOKEN \
GITHUB_ENV=/dev/null \
GITHUB_PATH=/dev/null \
GITHUB_OUTPUT=/dev/null \
GITHUB_STEP_SUMMARY=/dev/null \
BASH_ENV=/dev/null \
UV_NO_BUILD=1 \
GIT_CONFIG_NOSYSTEM=1 \
GIT_CONFIG_GLOBAL=/dev/null \
GIT_CONFIG_COUNT=1 \
GIT_CONFIG_KEY_0=safe.directory \
GIT_CONFIG_VALUE_0=/work \
HOME=/work/.opencode-sandbox-home \
XDG_CACHE_HOME=/work/.opencode-sandbox-cache \
CARGO_HOME=/work/.opencode-sandbox-home/.cargo \
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
"$@" >"$python_native_pytest_log" 2>&1
rc=$?
set -e
emit_captured_log "$python_native_pytest_log"
append '```'
append ""

if [ "$rc" -eq 0 ]; then
append "- Result: PASS"
elif run_python_native_extension_classifier \
"$project_dir" \
"$python_native_pytest_log" \
"$python_native_changed_files" \
"$python_native_pyproject_snapshot" >/dev/null 2>&1; then
append "### Python native-extension source-only deferral"
append ""
append "- Result: DEFERRED"
append "- Reason: the unchanged declared PyO3 module was unavailable in the source-only sandbox; exact-head Python, Rust/PyO3, and package CheckRuns must all complete successfully before approval."
append ""
python_native_peer_check_required=1
else
append "- Result: FAIL (exit ${rc})"
failures=$((failures + 1))
fi
append ""
rm -f \
"$python_native_pytest_log" \
"$python_native_changed_files" \
"$python_native_pyproject_snapshot"
}

run_r_package_testthat() {
local package_name="$1"
local log_file rc classification description_snapshot
Expand Down Expand Up @@ -1041,7 +1140,7 @@ jobs:
if [ -n "${PR_BASE_SHA:-}" ] && [ -n "${PR_HEAD_SHA:-}" ] \
&& trusted_git rev-parse --verify --quiet "$PR_BASE_SHA^{commit}" >/dev/null \
&& trusted_git rev-parse --verify --quiet "$PR_HEAD_SHA^{commit}" >/dev/null; then
trusted_git diff --name-only --find-renames "$PR_BASE_SHA" "$PR_HEAD_SHA"
trusted_git diff --name-only --no-renames "$PR_BASE_SHA" "$PR_HEAD_SHA"
else
trusted_git ls-files
fi
Expand Down Expand Up @@ -7120,6 +7219,143 @@ jobs:
return 2
}

coverage_defers_to_python_native_peer_checks() {
printf '%s\n' "${COVERAGE_EVIDENCE_SUMMARY:-}" |
grep -Fq -- "- Python native-extension peer evidence: deferred source-only collection requires successful exact-head peer checks"
}

collect_successful_python_native_peer_check_evidence() {
local output_file="$1"
local owner="${GH_REPOSITORY%%/*}"
local name="${GH_REPOSITORY#*/}"
local graphql_page_file graphql_nodes_file cursor has_next_page next_cursor
local page_count=0
local -a graphql_args
graphql_page_file="$(mktemp)"
graphql_nodes_file="$(mktemp)"
cursor=""
: >"$graphql_nodes_file"

# Materialize trusted current-head GraphQL check-runs as the helper's
# bounded JSON contract. Every page is bound independently to the
# current head; missing or repeating cursors fail closed.
while true; do
page_count=$((page_count + 1))
if [ "$page_count" -gt 100 ]; then
printf 'GitHub Checks lookup exceeded the bounded 100-page limit.\n' >&2
rm -f "$graphql_page_file" "$graphql_nodes_file"
return 1
fi
graphql_args=(
api graphql
-f owner="$owner"
-f name="$name"
-F number="$PR_NUMBER"
-f query='
query($owner:String!,$name:String!,$number:Int!,$cursor:String) {
repository(owner:$owner,name:$name) {
pullRequest(number:$number) {
headRefOid
statusCheckRollup {
contexts(first: 100, after: $cursor) {
pageInfo {
hasNextPage
endCursor
}
nodes {
__typename
... on CheckRun {
name
status
conclusion
checkSuite {
workflowRun {
workflow {
name
}
}
}
}
}
}
}
}
}
}
'
)
if [ -n "$cursor" ]; then
graphql_args+=(-f cursor="$cursor")
fi
if ! timeout "$(check_lookup_api_timeout_seconds)s" \
gh "${graphql_args[@]}" >"$graphql_page_file"; then
rm -f "$graphql_page_file" "$graphql_nodes_file"
return 1
fi
if ! jq -e --arg head_sha "$PR_HEAD_SHA" '
.data.repository.pullRequest as $pr
| (($pr.headRefOid // "") == $head_sha)
and (($pr.statusCheckRollup.contexts.nodes | type) == "array")
and (($pr.statusCheckRollup.contexts.pageInfo.hasNextPage | type) == "boolean")
' "$graphql_page_file" >/dev/null; then
printf 'GitHub Checks page was stale or malformed.\n' >&2
rm -f "$graphql_page_file" "$graphql_nodes_file"
return 1
fi
jq --arg head_sha "$PR_HEAD_SHA" '[
(.data.repository.pullRequest.statusCheckRollup.contexts.nodes // [])[]
| select(.__typename == "CheckRun")
| {
__typename: "CheckRun",
workflow: (.checkSuite.workflowRun.workflow.name // ""),
name: (.name // ""),
head_sha: $head_sha,
status: (.status // ""),
conclusion: (.conclusion // "")
}
]' "$graphql_page_file" >>"$graphql_nodes_file"
has_next_page="$(jq -r '.data.repository.pullRequest.statusCheckRollup.contexts.pageInfo.hasNextPage' "$graphql_page_file")"
next_cursor="$(jq -r '.data.repository.pullRequest.statusCheckRollup.contexts.pageInfo.endCursor // empty' "$graphql_page_file")"
if [ "$has_next_page" != "true" ]; then
break
fi
if [ -z "$next_cursor" ] || [ "$next_cursor" = "$cursor" ]; then
printf 'GitHub Checks pagination returned an empty or repeated cursor.\n' >&2
rm -f "$graphql_page_file" "$graphql_nodes_file"
return 1
fi
cursor="$next_cursor"
done

jq -s 'add // []' "$graphql_nodes_file" >"$output_file"
rm -f "$graphql_page_file" "$graphql_nodes_file"

python3 "$GITHUB_WORKSPACE/scripts/ci/python_native_extension_peer_gate.py" \
require-checks \
--checks-json "$output_file" \
--head-sha "$PR_HEAD_SHA" \
--required-check "CI::python" \
--required-check "CI::rust" \
--required-check "CI::package" >/dev/null
}

require_python_native_peer_checks_for_deferred_coverage() {
local checks_file
if ! coverage_defers_to_python_native_peer_checks; then
return 0
fi
checks_file="$(mktemp)"
if collect_github_checks_with_retry \
collect_successful_python_native_peer_check_evidence "$checks_file"; then
rm -f "$checks_file"
printf 'Verified successful exact-head Python, Rust/PyO3, and package CheckRuns after bounded source-only native-extension deferral.\n'
return 0
fi
rm -f "$checks_file"
printf '::notice::Python native-extension source-only deferral cannot authorize approval without successful exact-head Python, Rust/PyO3, and package CheckRuns.\n'
return 1
}

coverage_defers_to_r_cmd_check() {
printf '%s\n' "${COVERAGE_EVIDENCE_SUMMARY:-}" |
grep -Fq -- "- R test evidence: deferred package-load failures require a successful current-head peer R CMD check"
Expand Down
Loading
Loading