From d4d3c2ade22393c3d66c98b56a851b3eb7e3ed92 Mon Sep 17 00:00:00 2001 From: kaizen-agents-sync Date: Sat, 18 Jul 2026 05:37: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 ba8a4c6c7ba36a1eeb5ca95c2ff31ddc8ea4bb9f Mon Sep 17 00:00:00 2001 From: "hiraoku.shinichi" Date: Sun, 19 Jul 2026 08:22:00 +0900 Subject: [PATCH 2/2] Restore 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