Skip to content

Backlog cleanup: pagination, lint hook, dead code#6

Merged
flyingrobots merged 6 commits intomainfrom
chore/backlog-cleanup
Mar 29, 2026
Merged

Backlog cleanup: pagination, lint hook, dead code#6
flyingrobots merged 6 commits intomainfrom
chore/backlog-cleanup

Conversation

@flyingrobots
Copy link
Copy Markdown
Owner

Summary

Three items from the PR #5 retrospective backlog:

  • GraphQL pagination: Review thread fetch in GhCliAdapter now pages past the 100-thread limit using cursor-based pagination. PRs with >100 threads (like Harden Doghouse trust, correctness, and character #5 itself with 104) no longer silently truncate, preventing false "merge ready" verdicts.
  • Markdownlint pre-commit hook: scripts/hooks/pre-commit runs markdownlint-cli2 on staged .md files. Excludes docs/archive/ and docs/code-reviews/ (bulk-formatted in Harden Doghouse trust, correctness, and character #5, but shouldn't gate commits). Gracefully skips if markdownlint-cli2 isn't installed. Config in .markdownlint-cli2.jsonc.
  • Dead code removal: Deleted tools/bootstrap-git-mind.sh — legacy script from the pre-Doghouse era that generates a dead entry point for sources that no longer exist.

Test plan

  • pytest tests/doghouse -v — 48 passed
  • Pre-commit hook ran on this commit's CHANGELOG.md — 0 errors
  • doghouse --help — CLI loads

flyingrobots and others added 3 commits March 29, 2026 13:44
Legacy bootstrap script from the pre-Doghouse era. The sources it
references (src/git_mind) were deleted during the reboot. The script
generates a dead entry point and has no remaining purpose.
…moval

- Implement GraphQL cursor pagination for review threads in
  GhCliAdapter. PRs with >100 threads now fetch all pages instead
  of silently truncating at the first 100.
- Add markdownlint pre-commit hook (scripts/hooks/pre-commit) with
  .markdownlint-cli2.jsonc config. Skips docs/archive/ and
  docs/code-reviews/ by design. Gracefully skips if markdownlint-cli2
  is not installed.
- Remove dead tools/bootstrap-git-mind.sh (legacy artifact from
  pre-Doghouse era with no remaining purpose).
- Configure core.hooksPath to scripts/hooks.
- Update CHANGELOG.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 29, 2026

Warning

Rate limit exceeded

@flyingrobots has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 19 minutes and 42 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 19 minutes and 42 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c25fec44-1449-41ca-9c66-00e6c0206b83

📥 Commits

Reviewing files that changed from the base of the PR and between 0b50b3d and df33ee8.

📒 Files selected for processing (7)
  • .markdownlint-cli2.jsonc
  • CHANGELOG.md
  • docs/code-reviews/PR6/2be9725f8f91d2df313e17e22bb1b403f88d6d1a.md
  • docs/code-reviews/PR6/eb263486b01a8eb3844a6159788b646506475cfe.md
  • scripts/hooks/pre-commit
  • src/doghouse/adapters/github/gh_cli_adapter.py
  • tools/bootstrap-git-mind.sh

Walkthrough

Implements cursor-based GraphQL pagination for unresolved review threads in the GitHub adapter, adds markdownlint configuration and a pre-commit hook that lints staged Markdown (excluding archives and code-reviews), archives two code-review Markdown files, and removes an obsolete bootstrap script.

Changes

Cohort / File(s) Summary
Markdown linting config & hook
\.markdownlint-cli2.jsonc, scripts/hooks/pre-commit, CHANGELOG.md
Adds markdownlint-cli2 configuration with custom rule overrides and ignore globs; adds an executable pre-commit hook that lints staged .md files (excludes docs/archive/** and docs/code-reviews/**); documents the hook in CHANGELOG.
GraphQL pagination (GitHub adapter)
src/doghouse/adapters/github/gh_cli_adapter.py
Reworks fetch_blockers to perform cursor-based pagination via repeated gh api graphql calls, accumulating reviewThreads.nodes across pages and using pageInfo (hasNextPage, endCursor) to drive iteration; preserves existing blocker extraction and truncation logic.
Archived code-review artifacts
docs/code-reviews/PR6/eb263486b01a8eb3844a6159788b646506475cfe.md, docs/code-reviews/PR6/2be9725f8f91d2df313e17e22bb1b403f88d6d1a.md
Adds two archived Markdown code-review documents with frontmatter and feedback tables.
Removed tooling
tools/bootstrap-git-mind.sh
Deletes the bootstrap script that previously scaffolded a git-mind package and initialized a repository.

Sequence Diagram(s)

sequenceDiagram
participant Adapter as GitHub Adapter
participant GH as gh CLI
participant API as GitHub GraphQL API
Adapter->>GH: call graphql(query, variables[, cursor])
GH->>API: execute GraphQL request
API-->>GH: return { reviewThreads: { nodes, pageInfo } }
GH-->>Adapter: stdout JSON page
Adapter->>Adapter: extract unresolved threads, append nodes
alt pageInfo.hasNextPage == true
  Adapter->>GH: loop with -F cursor=pageInfo.endCursor
else
  Adapter-->>Adapter: finish accumulation
end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

Threads paged in cursors, one by one they fall,
Pre-commit guards Markdown, nipping sloppiness small,
An old bootstrap script fades out of sight,
Archive notes tucked in, tidy and tight,
CodeRabbit grins — the pipeline hums right.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title precisely captures the three main changes: GraphQL pagination improvements, addition of a markdownlint pre-commit hook, and removal of dead code from the bootstrap script.
Description check ✅ Passed The description is directly related to the changeset, clearly detailing all three major changes with specific context about pagination limits, hook behavior, and dead code removal.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/backlog-cleanup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 559f86606b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/hooks/pre-commit`:
- Around line 12-19: The current pipeline splits filenames on whitespace because
it echoes STAGED_MD into xargs; replace that with a NUL-delimited pipeline so
filenames with spaces are preserved: produce the staged list as NUL-separated
entries (use git's NUL output and grep's NUL mode or otherwise emit STAGED_MD
with NUL separators) and invoke markdownlint-cli2 via xargs in NUL-safe mode (so
xargs receives the original filenames intact) instead of the current echo
"$STAGED_MD" | xargs markdownlint-cli2.

In `@src/doghouse/adapters/github/gh_cli_adapter.py`:
- Around line 120-124: The pagination loop uses page_info =
thread_data.get("pageInfo", {}) and sets cursor = page_info["endCursor"] when
hasNextPage is true, but it doesn't guard against a null or repeated endCursor;
update the loop in gh_cli_adapter.py (around the cursor/page_info handling) to
validate that page_info.get("endCursor") is non-null and different from the last
cursor before assigning and continuing, otherwise break (or raise) to avoid
refetching the same page indefinitely; you can implement this by tracking
previous_cursor and comparing it to page_info["endCursor"] and only updating
cursor and continuing when it changes.
- Around line 93-97: The code currently appends ["-F", "cursor="] when cursor is
falsy which sends an empty after parameter; change the logic around gql_args so
that when cursor is falsy you do not add any "-F", "cursor=..." entries (only
append the "-F", f"cursor={cursor}" pair when cursor is truthy), and when
reading the next cursor use page_info.get("endCursor") into cursor and validate
it (e.g., only set cursor for the next iteration if page_info.get("endCursor")
is not None) so you never pass a null/empty endCursor into the next request;
update the references to cursor, gql_args, page_info and endCursor accordingly.
🪄 Autofix (Beta)

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: ASSERTIVE

Plan: Pro

Run ID: db83fbd2-9f1f-46ba-8481-89bab5427590

📥 Commits

Reviewing files that changed from the base of the PR and between 0b50b3d and 559f866.

📒 Files selected for processing (6)
  • .markdownlint-cli2.jsonc
  • CHANGELOG.md
  • docs/code-reviews/PR6/eb263486b01a8eb3844a6159788b646506475cfe.md
  • scripts/hooks/pre-commit
  • src/doghouse/adapters/github/gh_cli_adapter.py
  • tools/bootstrap-git-mind.sh
💤 Files with no reviewable changes (1)
  • tools/bootstrap-git-mind.sh

flyingrobots and others added 3 commits March 29, 2026 15:17
- Omit cursor arg on first GraphQL page (was sending empty string,
  which GitHub rejects as invalid cursor)
- Add cursor-progression guard to prevent infinite loop if endCursor
  is null or unchanged
- Use NUL-delimited file handling in pre-commit hook to safely handle
  filenames with spaces
@flyingrobots
Copy link
Copy Markdown
Owner Author

@coderabbitai review please 🥕

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 29, 2026

@flyingrobots Carrot accepted. 🥕 Kicking off a full review now — I'll tear through the pagination logic, the hook script, and the dead code removal with zero mercy.


🧠 Learnings used
Learnt from: flyingrobots
Repo: flyingrobots/draft-punks PR: 2
File: docs/code-reviews/PR2/410ce3439856a4cdf6ae7df8fd3936e7bbb67bba.md:81-85
Timestamp: 2025-09-29T08:57:34.199Z
Learning: When reviewing auto-generated CodeRabbit content or review artifacts, do not criticize marketing links or promotional content that are part of the standard CodeRabbit template output.
✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/hooks/pre-commit`:
- Around line 13-17: The pre-commit hook builds STAGED_MD via a git diff
pipeline that then filters out docs/archive/ and docs/code-reviews/ with grep,
which duplicates ignores already declared in .markdownlint-cli2.jsonc; remove
the redundant exclusion filters by editing the STAGED_MD assignment to stop
piping to the two grep -v '^docs/archive/' and grep -v '^docs/code-reviews/'
commands so that markdownlint-cli2 receives all staged .md files and its
"ignores" configuration controls exclusions.
🪄 Autofix (Beta)

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: ASSERTIVE

Plan: Pro

Run ID: d72a94e9-16a9-4406-b406-e514ced05dbf

📥 Commits

Reviewing files that changed from the base of the PR and between 559f866 and df33ee8.

📒 Files selected for processing (3)
  • docs/code-reviews/PR6/2be9725f8f91d2df313e17e22bb1b403f88d6d1a.md
  • scripts/hooks/pre-commit
  • src/doghouse/adapters/github/gh_cli_adapter.py

Comment on lines +13 to +17
STAGED_MD=$(git diff --cached --name-only -z --diff-filter=ACM -- '*.md' \
| tr '\0' '\n' \
| grep -v '^docs/archive/' \
| grep -v '^docs/code-reviews/' \
|| true)
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.

🧹 Nitpick | 🔵 Trivial

Redundant exclusion filters — the linter config already handles this.

Lines 15-16 manually exclude docs/archive/ and docs/code-reviews/, but .markdownlint-cli2.jsonc (lines 14-20) already declares identical ignores:

"ignores": [
  "docs/archive/**",
  "docs/code-reviews/**"
]

This creates two sources of truth. When someone adds a third exclusion to the config, they'll forget to update the hook (or vice versa), and then you'll waste 20 minutes debugging why linting "works differently" locally vs in the hook.

The simpler approach: pass all staged .md files to markdownlint-cli2 and let its config handle exclusions.

♻️ Simplified hook without redundant grep filters
     # Lint staged .md files only (skip archived docs and code-review worksheets)
     # Use NUL-delimited output to handle filenames with spaces safely.
-    STAGED_MD=$(git diff --cached --name-only -z --diff-filter=ACM -- '*.md' \
-        | tr '\0' '\n' \
-        | grep -v '^docs/archive/' \
-        | grep -v '^docs/code-reviews/' \
-        || true)
+    STAGED_MD=$(git diff --cached --name-only -z --diff-filter=ACM -- '*.md')
 
-    if [ -n "$STAGED_MD" ]; then
-        echo "$STAGED_MD" | tr '\n' '\0' | xargs -0 markdownlint-cli2
+    if [ -n "$STAGED_MD" ]; then
+        printf '%s' "$STAGED_MD" | xargs -0 markdownlint-cli2
         echo "pre-commit: markdown lint passed."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/hooks/pre-commit` around lines 13 - 17, The pre-commit hook builds
STAGED_MD via a git diff pipeline that then filters out docs/archive/ and
docs/code-reviews/ with grep, which duplicates ignores already declared in
.markdownlint-cli2.jsonc; remove the redundant exclusion filters by editing the
STAGED_MD assignment to stop piping to the two grep -v '^docs/archive/' and grep
-v '^docs/code-reviews/' commands so that markdownlint-cli2 receives all staged
.md files and its "ignores" configuration controls exclusions.

@flyingrobots flyingrobots merged commit eeaae41 into main Mar 29, 2026
4 checks passed
@flyingrobots flyingrobots deleted the chore/backlog-cleanup branch March 29, 2026 22:45
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.

1 participant