Skip to content

docs(#2091): document gh api --paginate + jq per-page semantics - #2288

Merged
rh-hemartin merged 2 commits into
mainfrom
agent/2091-paginate-jq-guidance
Jun 19, 2026
Merged

docs(#2091): document gh api --paginate + jq per-page semantics#2288
rh-hemartin merged 2 commits into
mainfrom
agent/2091-paginate-jq-guidance

Conversation

@rh-hemartin

Copy link
Copy Markdown
Member

Summary

Adds a Shell scripting section to AGENTS.md documenting the gh api --paginate + jq per-page behavior that caused the loop-guard bug in PR #1834.

What's documented

  • gh api --paginate applies --jq per page, not over combined output
  • Aggregating filters (length, sort_by, group_by, add, min_by, max_by) silently break when used directly in --jq with --paginate
  • Correct pattern: collect all pages first, then pipe to jq -s for slurp-mode aggregation
  • Review guidance: flag --paginate --jq '... | length' (or similar) as a medium-severity finding

Validation

Per issue #2091: next code agent PRs using gh api --paginate with jq should use jq -s for aggregation. Review agent should not flag the per-page pagination issue on new code.

Closes #2091

@rh-hemartin rh-hemartin self-assigned this Jun 15, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 15, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 7:13 AM UTC · Ended 7:15 AM UTC
Commit: 4e21a60 · View workflow run →

@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

Site preview

Preview: https://28db6bfa-site.fullsend-ai.workers.dev

Commit: 2677c80985ce4aa79f2a1aaa3b3cdaf06d900207

@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 15, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:18 AM UTC · Completed 7:29 AM UTC
Commit: 63c9907 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [protected-path] AGENTS.md, .github/workflows/reusable-fix.yml — These files are on the protected-path list. The PR is linked to issue Code agent should understand gh api --paginate + jq per-page semantics #2091 and the description explains the rationale for the change (documenting gh api --paginate + jq per-page semantics and fixing existing bugs that use the anti-pattern). Human approval is always required for protected-path changes, regardless of context.

Low

  • [error-handling] .github/workflows/reusable-fix.yml:258 — Moving 2>/dev/null to only the gh api command (rather than the entire pipeline) means jq stderr is no longer suppressed. If jq encounters a parse error (e.g., truncated output from a killed gh api process), the error message will now appear in workflow logs. This is arguably an improvement (better observability) rather than a bug — the || fallback still catches the non-zero exit and sets FIX_COMMITS to the cap.

  • [error-handling-consistency] internal/scaffold/fullsend-repo/scripts/post-review.sh:167 — The error fallback pattern changes from || echo "0" (inside command substitution) to || RECENT_REDISPATCH=0 (outside command substitution). Both are functionally correct. The new pattern matches the structural approach used in reusable-fix.yml where the || assignment is also outside the subshell.

Info

  • [prior-finding-resolved] .github/workflows/reusable-fix.yml:258 — Prior medium-severity finding about --paginate --jq '... | length' per-page bug is resolved by this PR. The new pattern correctly uses jq -s 'add | ...' to aggregate across all pages.

  • [prior-finding-resolved] internal/scaffold/fullsend-repo/scripts/post-review.sh:160 — Prior medium-severity finding about --paginate --jq '... | length' per-page bug is resolved by this PR. The new pattern correctly uses jq -s 'add // [] | ...' to aggregate across all pages.

Previous run

Review

Findings

Medium

  • [protected-path] AGENTS.md, .github/workflows/reusable-fix.yml — These files are on the protected-path list. The PR is linked to issue Code agent should understand gh api --paginate + jq per-page semantics #2091 and the description explains the rationale for the change (documenting gh api --paginate + jq per-page semantics and fixing existing bugs that use the anti-pattern). Human approval is always required for protected-path changes, regardless of context.

Low

  • [error-handling] .github/workflows/reusable-fix.yml:256 — Moving 2>/dev/null to only the gh api command (rather than the entire pipeline) means jq stderr is no longer suppressed. If jq encounters a parse error (e.g., truncated output from a killed gh api process), the error message will now appear in workflow logs. This is arguably an improvement (better observability) rather than a bug.

Info

  • [prior-finding-resolved] .github/workflows/reusable-fix.yml:256 — Prior medium-severity finding about --paginate --jq '... | length' per-page bug is resolved by this PR. The new code correctly pipes to jq -s 'add | [.[] | select(...)] | length' which aggregates across all pages.

  • [prior-finding-resolved] internal/scaffold/fullsend-repo/scripts/post-review.sh:159 — Prior medium-severity finding about --paginate --jq '... | length' per-page bug is resolved by this PR. The new code correctly uses jq -s 'add | [.[] | select(...)] | length' with the || echo "0" fallback.

Previous run

Review

Findings

Medium

  • [protected-path] AGENTS.md — This file is on the protected-path list. The PR is linked to issue Code agent should understand gh api --paginate + jq per-page semantics #2091 and the description explains the rationale for the change. Human approval is always required for protected-path changes, regardless of context.

  • [existing-bug] .github/workflows/reusable-fix.yml:256 — Uses --paginate --jq '[.[] | select(...)] | length' — the exact anti-pattern documented by this PR. The length aggregation runs per-page, so if commits span multiple pages, each page produces its own count. This could undercount fix commits and allow more fix iterations than ITERATION_CAP intends. Pre-existing bug, not introduced by this PR.
    Remediation: Change to gh api ... --paginate | jq -s 'add | [.[] | select(.commit.author.name == "fullsend-fix")] | length'

  • [existing-bug] internal/scaffold/fullsend-repo/scripts/post-review.sh:159 — Uses --paginate --jq '[...] | length' to count recent re-dispatch comments. The length aggregation runs per-page. If comments span multiple pages, the multi-number output causes a bash comparison error, defaulting to allowing a re-dispatch rather than blocking one. Pre-existing bug, not introduced by this PR.
    Remediation: Pipe through a separate jq -s 'add | length' step instead of using --jq for the aggregation.

Low

  • [code-example-style] AGENTS.md:56 — Code comment capitalization is inconsistent: # WRONG uses all caps while # Correct uses title case. Consider using consistent capitalization (e.g., both all-caps: # WRONG / # CORRECT).
Previous run

Review

Findings

Medium

  • [protected-path] AGENTS.md, .github/workflows/reusable-fix.yml — These files are on the protected-path list. The PR is linked to issue Code agent should understand gh api --paginate + jq per-page semantics #2091 and the description explains the rationale for the change (documenting gh api --paginate + jq per-page semantics and fixing existing bugs that use the anti-pattern). Human approval is always required for protected-path changes, regardless of context.

Low

  • [error-handling] .github/workflows/reusable-fix.yml:256 — Moving 2>/dev/null to only the gh api command (rather than the entire pipeline) means jq stderr is no longer suppressed. If jq encounters a parse error (e.g., truncated output from a killed gh api process), the error message will now appear in workflow logs. This is arguably an improvement (better observability) rather than a bug.

Info

  • [prior-finding-resolved] .github/workflows/reusable-fix.yml:256 — Prior medium-severity finding about --paginate --jq '... | length' per-page bug is resolved by this PR. The new code correctly pipes to jq -s 'add | [.[] | select(...)] | length' which aggregates across all pages.

  • [prior-finding-resolved] internal/scaffold/fullsend-repo/scripts/post-review.sh:159 — Prior medium-severity finding about --paginate --jq '... | length' per-page bug is resolved by this PR. The new code correctly uses jq -s 'add | [.[] | select(...)] | length' with the || echo "0" fallback.

Previous run (2)

Review

Findings

Medium

  • [protected-path] AGENTS.md — This file is on the protected-path list. The PR is linked to issue Code agent should understand gh api --paginate + jq per-page semantics #2091 and the description explains the rationale for the change. Human approval is always required for protected-path changes, regardless of context.

  • [existing-bug] .github/workflows/reusable-fix.yml:256 — Uses --paginate --jq '[.[] | select(...)] | length' — the exact anti-pattern documented by this PR. The length aggregation runs per-page, so if commits span multiple pages, each page produces its own count. This could undercount fix commits and allow more fix iterations than ITERATION_CAP intends. Pre-existing bug, not introduced by this PR.
    Remediation: Change to gh api ... --paginate | jq -s 'add | [.[] | select(.commit.author.name == "fullsend-fix")] | length'

  • [existing-bug] internal/scaffold/fullsend-repo/scripts/post-review.sh:159 — Uses --paginate --jq '[...] | length' to count recent re-dispatch comments. The length aggregation runs per-page. If comments span multiple pages, the multi-number output causes a bash comparison error, defaulting to allowing a re-dispatch rather than blocking one. Pre-existing bug, not introduced by this PR.
    Remediation: Pipe through a separate jq -s 'add | length' step instead of using --jq for the aggregation.

Low

  • [code-example-style] AGENTS.md:56 — Code comment capitalization is inconsistent: # WRONG uses all caps while # Correct uses title case. Consider using consistent capitalization (e.g., both all-caps: # WRONG / # CORRECT).

@fullsend-ai-review fullsend-ai-review 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.

See the review comment for full details.

Comment thread AGENTS.md
**Do not** use aggregating jq filters directly in `--jq` with `--paginate`:

```bash
# WRONG — `length` runs per-page; produces one number per page, not a total

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] code-example-style

Code comment capitalization is inconsistent: # WRONG uses all caps while # Correct uses title case.

Suggested fix: Change # Correct to # CORRECT to match the all-caps style, or use title case for both.

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Jun 15, 2026

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Multi-agent review (4 agents: claude-coder, claude-researcher, gemini-code-review, cursor-code-review). Core guidance is technically accurate — two MEDIUM findings on explanation accuracy and completeness. See inline comments.

Comment thread AGENTS.md Outdated
Comment thread AGENTS.md
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 16, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:41 AM UTC · Completed 6:53 AM UTC
Commit: 3777cd7 · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed requires-manual-review Review requires human judgment labels Jun 16, 2026
@rh-hemartin
rh-hemartin requested a review from waynesun09 June 17, 2026 13:03

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Multi-agent review (5 agents: 2x claude-coder, claude-researcher, gemini-code-review, cursor-code-review). Prior MEDIUM findings resolved. One new MEDIUM on error handling — see inline.

| jq -s "add | [.[] | select(.body | contains(\"${REDISPATCH_MARKER}\"))
| select(.created_at > (now - 300 | strftime(\"%Y-%m-%dT%H:%M:%SZ\")))]
| length" 2>/dev/null || echo "0")
| length" || echo "0")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[MEDIUM] Fallback value corruption under pipefail

This script runs with set -euo pipefail. The || echo "0" fallback is inside the $(...) command substitution, so if gh api writes partial data then exits non-zero:

  1. jq processes the partial data and writes its result (e.g., 0) to stdout
  2. Pipeline exits non-zero due to pipefail
  3. || echo "0" triggers, appending a second 0 to stdout
  4. RECENT_REDISPATCH captures both lines: "0\n0"
  5. [ "${RECENT_REDISPATCH}" -gt 0 ] fails with integer expression expected

The else branch runs (redispatch happens) — fail-open and functionally correct, but produces noisy stderr. The reusable-fix.yml version avoids this because its fallback reassigns the variable (FIX_COMMITS="${ITERATION_CAP:-5}").

Reproduced locally:

$ bash -c 'set -o pipefail; X=$( (echo "3"; exit 1) | cat || echo "0"); echo "X=[$X]"'
X=[3
0]

Suggested fix: Move the fallback outside the command substitution and add add // [] to guard against null on empty input:

RECENT_REDISPATCH=$(gh api \
  "repos/${REPO_FULL_NAME}/issues/${PR_NUMBER}/comments" \
  --paginate 2>/dev/null \
  | jq -s "add // [] | [.[] | select(.body | contains(\"${REDISPATCH_MARKER}\"))
        | select(.created_at > (now - 300 | strftime(\"%Y-%m-%dT%H:%M:%SZ\")))] 
   | length") || RECENT_REDISPATCH=0

Flagged by 1/5 review agents (claude-coder), verified by reproducing in bash.

@rh-hemartin
rh-hemartin force-pushed the agent/2091-paginate-jq-guidance branch from 3777cd7 to 4cd91a3 Compare June 18, 2026 06:50
rh-hemartin and others added 2 commits June 18, 2026 08:50
gh api --paginate applies the --jq expression independently to each
page, not over the combined output. Aggregating filters like length,
sort_by, and group_by silently produce per-page results, causing
multi-line output that breaks bash integer comparisons.

Add a Shell scripting section documenting:
- The wrong pattern (--paginate --jq '... | length')
- The correct pattern (pipe to jq -s for slurp-mode aggregation)
- Review guidance to flag this as a medium-severity finding

Signed-off-by: Hector Martinez <hemartin@redhat.com>
Fix misleading explanation of --paginate output behavior, add --slurp
flag documentation, and prevent pipefail fallback corruption in the
redispatch guard by moving the fallback outside the command substitution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Hector Martinez <hemartin@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 18, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:54 AM UTC · Completed 7:06 AM UTC
Commit: 2677c80 · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed requires-manual-review Review requires human judgment labels Jun 18, 2026

@ralphbean ralphbean left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM.

@rh-hemartin
rh-hemartin added this pull request to the merge queue Jun 19, 2026
Merged via the queue into main with commit 8d542e2 Jun 19, 2026
14 checks passed
@rh-hemartin
rh-hemartin deleted the agent/2091-paginate-jq-guidance branch June 19, 2026 06:17
@fullsend-ai-retro

fullsend-ai-retro Bot commented Jun 19, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 6:22 AM UTC · Completed 6:30 AM UTC
Commit: 2677c80 · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #2288 — document gh api --paginate + jq per-page semantics

Timeline

  1. June 9: Retro agent created issue #2091 from PR #1834, identifying that the code agent didn't understand --paginate + --jq per-page behavior.
  2. June 15 07:09: Human (rh-hemartin) opened PR #2288 with initial documentation commit. A quick follow-up commit was pushed 3 minutes later.
  3. June 15 07:13–07:29: Automated review ran twice (first cancelled due to rapid push, second completed). Found only a low-severity style nit about comment capitalization.
  4. June 15 16:20: Human reviewer (waynesun09) ran multi-agent review (4 agents). Found 2 MEDIUM findings: (a) the explanation of --paginate output behavior was technically misleading, and (b) the --slurp flag alternative was not documented.
  5. June 17 13:42: Second human multi-agent review (5 agents). Prior MEDIUMs resolved. Found 1 new MEDIUM: pipefail fallback corruption in post-review.sh.
  6. June 18 15:28: Human (ralphbean) approved with LGTM.
  7. June 19 06:17: PR merged.

Assessment

The workflow operated well overall. The retro→issue→code→review→merge pipeline completed successfully end-to-end. The retro agent's original issue (#2091) was well-scoped and led to a useful documentation addition plus two real bug fixes in shell scripts.

Review quality gap: The automated review agent found only a cosmetic style nit, while the human-orchestrated multi-agent review caught substantive technical inaccuracies and a real bug. This pattern — shallow automated review on documentation PRs — is already tracked by existing issues:

  • #2199: Review agent should fact-check technical claims in documentation PRs
  • #1480: Review agent provides shallow feedback on documentation PRs
  • #1322: Code agent should validate CLI flag semantics in documentation against source code

No new proposals are warranted — the improvement areas identified are well-covered by existing open issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

requires-manual-review Review requires human judgment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Code agent should understand gh api --paginate + jq per-page semantics

3 participants