From c1afd448eb46602d6786f1bbc852e28b96c1fedc Mon Sep 17 00:00:00 2001 From: kaizen-agents-sync Date: Mon, 20 Jul 2026 06:27:53 +0000 Subject: [PATCH 1/2] Sync Kaizen dogfood contracts --- .../references/pr-feedback-audit.md | 34 +++---------------- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/skills/pr-guardian/references/pr-feedback-audit.md b/skills/pr-guardian/references/pr-feedback-audit.md index 875a028..f5fe25a 100644 --- a/skills/pr-guardian/references/pr-feedback-audit.md +++ b/skills/pr-guardian/references/pr-feedback-audit.md @@ -27,7 +27,6 @@ query($owner:String!, $name:String!, $number:Int!, $cursor:String) { repository(owner:$owner, name:$name) { pullRequest(number:$number) { headRefOid - headRepository { nameWithOwner } reviewDecision mergeStateStatus reviewThreads(first:100, after:$cursor) { @@ -57,19 +56,7 @@ query($owner:String!, $name:String!, $number:Int!, $cursor:String) { if [[ -n "${cursor}" ]]; then args+=(-f "cursor=${cursor}") fi - if ! page="$(gh "${args[@]}")"; then - echo 'failed to fetch review threads' >&2 - exit 1 - fi - if ! jq -e ' - .data.repository.pullRequest.reviewThreads as $threads - | ($threads | type == "object") - and ($threads.nodes | type == "array") - and ($threads.pageInfo.hasNextPage | type == "boolean") - ' >/dev/null <<<"${page}"; then - echo 'reviewThreads returned an invalid or incomplete response' >&2 - exit 1 - fi + page="$(gh "${args[@]}")" jq -c '.data.repository.pullRequest.reviewThreads.nodes[]' <<<"${page}" if [[ "$(jq -r '.data.repository.pullRequest.reviewThreads.pageInfo.hasNextPage' <<<"${page}")" != true ]]; then break @@ -106,19 +93,7 @@ query($threadId:ID!, $cursor:String) { if [[ -n "${cursor}" ]]; then args+=(-f "cursor=${cursor}") fi - if ! page="$(gh "${args[@]}")"; then - echo 'failed to fetch review comments' >&2 - exit 1 - fi - if ! jq -e ' - .data.node.comments as $comments - | ($comments | type == "object") - and ($comments.nodes | type == "array") - and ($comments.pageInfo.hasNextPage | type == "boolean") - ' >/dev/null <<<"${page}"; then - echo 'review comments returned an invalid or incomplete response' >&2 - exit 1 - fi + page="$(gh "${args[@]}")" jq -c '.data.node.comments.nodes[]' <<<"${page}" if [[ "$(jq -r '.data.node.comments.pageInfo.hasNextPage' <<<"${page}")" != true ]]; then break @@ -131,15 +106,14 @@ query($threadId:ID!, $cursor:String) { done ``` -Exhaust each REST endpoint with `--paginate`; summaries and first pages are incomplete evidence. Check runs can be owned by either side of a fork PR: head-repository workflows usually create runs in the head repository, while base-repository Actions and installed apps can create them in the base repository. Read `headRepository.nameWithOwner` from the GraphQL response above, query both base and head repositories when they differ, and retain the repository name alongside every returned check-run ID. Fetch each run's annotations from the same repository that returned it, deduplicating identical run IDs. If either repository query fails or the head repository is unavailable, stop and report the audit as incomplete. +Exhaust each REST endpoint with `--paginate`; summaries and first pages are incomplete evidence: ```sh gh api --paginate 'repos///pulls//reviews?per_page=100' gh api --paginate 'repos///pulls//comments?per_page=100' gh api --paginate 'repos///issues//comments?per_page=100' gh api --paginate 'repos///commits//check-runs?per_page=100' -gh api --paginate 'repos///commits//check-runs?per_page=100' # when different -gh api --paginate 'repos///check-runs//annotations?per_page=100' +gh api --paginate 'repos///check-runs//annotations?per_page=100' ``` ## Reply, then resolve From b46737b70180711a81d8bb2a8f7169d3e353ceaa Mon Sep 17 00:00:00 2001 From: "hiraoku.shinichi" Date: Mon, 20 Jul 2026 19:30:35 +0900 Subject: [PATCH 2/2] fix: preserve PR feedback audit safeguards --- .../references/pr-feedback-audit.md | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/skills/pr-guardian/references/pr-feedback-audit.md b/skills/pr-guardian/references/pr-feedback-audit.md index f5fe25a..875a028 100644 --- a/skills/pr-guardian/references/pr-feedback-audit.md +++ b/skills/pr-guardian/references/pr-feedback-audit.md @@ -27,6 +27,7 @@ query($owner:String!, $name:String!, $number:Int!, $cursor:String) { repository(owner:$owner, name:$name) { pullRequest(number:$number) { headRefOid + headRepository { nameWithOwner } reviewDecision mergeStateStatus reviewThreads(first:100, after:$cursor) { @@ -56,7 +57,19 @@ query($owner:String!, $name:String!, $number:Int!, $cursor:String) { if [[ -n "${cursor}" ]]; then args+=(-f "cursor=${cursor}") fi - page="$(gh "${args[@]}")" + if ! page="$(gh "${args[@]}")"; then + echo 'failed to fetch review threads' >&2 + exit 1 + fi + if ! jq -e ' + .data.repository.pullRequest.reviewThreads as $threads + | ($threads | type == "object") + and ($threads.nodes | type == "array") + and ($threads.pageInfo.hasNextPage | type == "boolean") + ' >/dev/null <<<"${page}"; then + echo 'reviewThreads returned an invalid or incomplete response' >&2 + exit 1 + fi jq -c '.data.repository.pullRequest.reviewThreads.nodes[]' <<<"${page}" if [[ "$(jq -r '.data.repository.pullRequest.reviewThreads.pageInfo.hasNextPage' <<<"${page}")" != true ]]; then break @@ -93,7 +106,19 @@ query($threadId:ID!, $cursor:String) { if [[ -n "${cursor}" ]]; then args+=(-f "cursor=${cursor}") fi - page="$(gh "${args[@]}")" + if ! page="$(gh "${args[@]}")"; then + echo 'failed to fetch review comments' >&2 + exit 1 + fi + if ! jq -e ' + .data.node.comments as $comments + | ($comments | type == "object") + and ($comments.nodes | type == "array") + and ($comments.pageInfo.hasNextPage | type == "boolean") + ' >/dev/null <<<"${page}"; then + echo 'review comments returned an invalid or incomplete response' >&2 + exit 1 + fi jq -c '.data.node.comments.nodes[]' <<<"${page}" if [[ "$(jq -r '.data.node.comments.pageInfo.hasNextPage' <<<"${page}")" != true ]]; then break @@ -106,14 +131,15 @@ query($threadId:ID!, $cursor:String) { done ``` -Exhaust each REST endpoint with `--paginate`; summaries and first pages are incomplete evidence: +Exhaust each REST endpoint with `--paginate`; summaries and first pages are incomplete evidence. Check runs can be owned by either side of a fork PR: head-repository workflows usually create runs in the head repository, while base-repository Actions and installed apps can create them in the base repository. Read `headRepository.nameWithOwner` from the GraphQL response above, query both base and head repositories when they differ, and retain the repository name alongside every returned check-run ID. Fetch each run's annotations from the same repository that returned it, deduplicating identical run IDs. If either repository query fails or the head repository is unavailable, stop and report the audit as incomplete. ```sh gh api --paginate 'repos///pulls//reviews?per_page=100' gh api --paginate 'repos///pulls//comments?per_page=100' gh api --paginate 'repos///issues//comments?per_page=100' gh api --paginate 'repos///commits//check-runs?per_page=100' -gh api --paginate 'repos///check-runs//annotations?per_page=100' +gh api --paginate 'repos///commits//check-runs?per_page=100' # when different +gh api --paginate 'repos///check-runs//annotations?per_page=100' ``` ## Reply, then resolve