Skip to content

ci: allow git push in bot-write-docs allowlist - #2537

Merged
bpamiri merged 1 commit into
developfrom
peter/bot-write-docs-allow-push
May 10, 2026
Merged

ci: allow git push in bot-write-docs allowlist#2537
bpamiri merged 1 commit into
developfrom
peter/bot-write-docs-allow-push

Conversation

@bpamiri

@bpamiri bpamiri commented May 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

One-line fix to unblock end-to-end runs of the docs-request path. The first real-world run on issue #2536 (run #25619794274) successfully wrote and committed the Debug Panel guide, but couldn't open the draft PR — the bot's allowlist had specific git subcommands (status, log, diff, show, grep, add, commit) but not push. The workflow's "Push branch" step ran after the bot finished, pushing the branch too late for the bot's own gh pr create to use.

What changed

             --allowedTools "Bash(gh:*),Bash(git status),Bash(git log:*),Bash(git diff:*),Bash(git show:*),Bash(git grep:*),Bash(git add:*),Bash(git commit:*),Read,Edit,Write,Grep,Glob"
+            --allowedTools "Bash(gh:*),Bash(git status),Bash(git log:*),Bash(git diff:*),Bash(git show:*),Bash(git grep:*),Bash(git add:*),Bash(git commit:*),Bash(git push:*),Read,Edit,Write,Grep,Glob"

Why this is safe

The repository's wheels-bot push scope ruleset (16174270) restricts WHERE the bot can push to:

  • bot/**
  • fix/bot-*/**
  • docs/bot-*/**

So granting Bash(git push:*) to the bot does not expand its blast radius — it just lets the bot execute the push the ruleset will permit anyway. Mirrors bot-propose-fix.yml's Bash(git:*) wildcard, which has been working safely since PR #2533.

What this means for issue #2536

The branch docs/bot-2536-debug-panel-features-have-no-dedicated-docs-sectio is already on origin with the bot's full docs content. Two options after this PR merges:

  1. Manually open a PR from that branch — fastest way to see the rest of the cascade run tonight (TDD gate skip, Reviewer A, Reviewer B). The PR would be authored by you (not the bot), and would include the bot's commits as-is. The issue's wheels-bot:write-docs:2536 marker correctly belongs to the bot, so don't add additional bot markers in the new PR.

  2. Delete the branch and re-trigger via a fresh issue — cleaner test of the full pipeline (with this fix in place, the bot will open its own PR). Requires a new docs-request issue since Debug Panel features have no dedicated docs section in the guides #2536's existing wheels-bot:write-docs:2536 marker would block re-triggering on the same issue.

Test plan

  • Merge to develop.
  • (Optional) Pick option 1 or 2 above to verify the rest of the docs-request cascade.
  • Confirm: the next docs-request run with docs-confidence:high triggers write-docs, the bot pushes its own branch, and gh pr create succeeds inside the bot run (not deferred to manual).

🤖 Generated with Claude Code

The first end-to-end run of the docs-request path on issue #2536
([#25619794274](https://github.com/wheels-dev/wheels/actions/runs/25619794274))
revealed that bot-write-docs's allowlist scoped git too narrowly:
specific subcommands (status, log, diff, show, grep, add, commit) but
not push. The bot wrote the docs, committed them, then attempted
`gh pr create` — which needs the branch on remote, but the bot couldn't
push it. The workflow's "Push branch" step ran AFTER the bot finished,
pushing too late for the bot's `gh pr create` call.

Result: the docs/bot-2536-* branch landed on origin with full content,
but no PR was opened. The bot caught this in its issue comment and
explained the situation correctly ("the workflow's push step will
publish the branch after this run; once it is on the remote, the
draft PR can be opened from that branch") — high-quality failure
reporting, but the cascade stopped there.

Add `Bash(git push:*)` to the allowlist. The wheels-bot push-scope
ruleset (16174270) restricts WHERE the bot can push to bot/**,
fix/bot-*/**, and docs/bot-*/**, so granting push capability does
not expand the bot's blast radius — it just lets the bot execute
the push the ruleset will permit anyway. Mirrors propose-fix's
`Bash(git:*)` wildcard (which has been working since #2533).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bpamiri
bpamiri merged commit 2b443e6 into develop May 10, 2026
6 checks passed
@bpamiri
bpamiri deleted the peter/bot-write-docs-allow-push branch May 10, 2026 04:42

@wheels-bot wheels-bot Bot left a comment

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.

Wheels Bot — Reviewer A

TL;DR: This PR adds Bash(git push:*) to the bot's allowedTools in bot-write-docs.yml to unblock end-to-end runs of the docs pipeline. The permission grant is correct and necessary, but the fix is incomplete: .claude/commands/write-docs.md step 7 still explicitly tells the bot not to push ("The caller workflow handles the actual git push"), so the bot may not use the new permission. Without also updating the command's push instruction, gh pr create in step 8 will fail for the same reason as before.


Correctness

Stale prompt instruction in write-docs.md contradicts the intent of this fix.

.claude/commands/write-docs.md, step 7 (line 130):

The caller workflow handles the actual `git push` — just commit
cleanly. Do **not** use `--amend` or `--force`.

Step 8 (line 133) then asks the bot to:

gh pr create --draft --base develop

gh pr create requires the branch to exist on origin. Step 7 explicitly tells the bot the caller handles the push. Step 8 asks the bot to open the PR itself. These two instructions are contradictory, and this PR does not touch write-docs.md to resolve that contradiction.

The permission grant is necessary — without Bash(git push:*) the bot cannot push even if it tries. But it is not sufficient. A bot following step 7 literally will skip the push and arrive at step 8 with the branch still only on the local runner, causing the identical gh pr create failure this PR is meant to fix.

The complete fix requires updating write-docs.md step 7 (or adding a step 7a) to replace the stale instruction with an explicit push command:

git push -u origin HEAD

And removing the sentence that says the caller handles the push, since the bot is now responsible for it.


Docs

The "Push branch" step (lines 106-120) is now a safety net rather than the primary push path. Its change-detection heuristic (git diff --quiet origin/develop -- && git diff --cached --quiet) compares the working tree to origin/develop, so when the bot has committed new doc files the step will still see differences and attempt a second git push, which succeeds silently as a no-op if the bot already pushed. This is harmless, but a comment on the step explaining it is now a fallback for failed bot pushes would reduce future confusion.


Commits

ci: allow git push in bot-write-docs allowlist — valid commitlint format (type ci, no scope per CLAUDE.md convention for .github/workflows/ changes, subject under 100 chars, not ALL-CAPS). No issue here.


Security

Bash(git push:*) is broader than needed (covers --force, --delete, tag pushes), but this is consistent with bot-propose-fix.yml's Bash(git:*) wildcard which covers all git subcommands. The repository ruleset 16174270 is the correct defense-in-depth layer, and the PR's reasoning on why this is safe holds.

@wheels-bot

wheels-bot Bot commented May 10, 2026

Copy link
Copy Markdown
Contributor

Wheels Bot — Reviewer B (round 1)

A's review is accurate and well-reasoned. The core finding — that granting Bash(git push:*) is necessary but not sufficient because write-docs.md step 7 (line 130) still explicitly instructs the bot to let the caller handle the push — is correct and directly confirmed by the file. The verdict of CHANGES_REQUESTED is appropriate.

Sycophancy

None detected. A requested changes despite the PR being a clear one-liner with a reasonable motivation.

False positives

None detected. I verified each claim:

  • gh pr create requires the branch on origin — correct.
  • Step 7 / step 8 contradiction — confirmed. Line 130 of write-docs.md reads "The caller workflow handles the actual git push — just commit cleanly." Step 8 then instructs gh pr create --draft --base develop, which fails if the branch is local-only. The contradiction is real.
  • "Push branch" step heuristic — A described it as git diff --quiet origin/develop -- && git diff --cached --quiet. Lines 113-116 of the updated workflow confirm this verbatim. A's characterization of it becoming a fallback no-op is accurate.
  • Security noteBash(git push:*) permitting --force, --delete, and tag pushes is factually correct. The repository ruleset as the defense-in-depth layer is the right framing, and noting consistency with bot-propose-fix.yml's Bash(git:*) is accurate.

Missed issues

None significant. The diff is a single-line change; A correctly identified that the incomplete fix lives in the prose of the prompt command, not in the workflow YAML itself. A's suggested fix (replace step 7's "caller handles push" sentence with an explicit git push -u origin HEAD) is actionable and correct.

One very minor omission: the write-docs.md Rails section (lines 12-23) scopes the bot to doc paths only and says "full git for your branch only" — which implicitly permits pushing. A's fix aligns with that framing, but citing it would make the argument tighter. This is editorial, not a substantive gap.

Verdict alignment

CHANGES_REQUESTED is consistent with A's findings. The permission grant without the matching prompt update leaves the pipeline broken in the same way as before.

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