Skip to content

ci: add docs-request path — write-docs stage parallel to propose-fix#2535

Merged
bpamiri merged 1 commit into
developfrom
peter/bot-docs-request-path
May 10, 2026
Merged

ci: add docs-request path — write-docs stage parallel to propose-fix#2535
bpamiri merged 1 commit into
developfrom
peter/bot-docs-request-path

Conversation

@bpamiri
Copy link
Copy Markdown
Collaborator

@bpamiri bpamiri commented May 10, 2026

Summary

Adds a fourth classification path to the wheels-bot pipeline. Previously, docs-only issues fell through to other (no automation) or, when reframed as framework-design, would hit propose-fix's TDD-shaped prompt that doesn't fit doc-only work. This PR adds a parallel docs-request → write-docs path that mirrors propose-fix's shape but is doc-paths-only.

The new path

triage → docs-request + docs-confidence:high
     → bot-write-docs.yml
     → docs/bot-<issue>-<slug> branch
     → draft PR (TDD gate skips, since the branch prefix says docs)
     → Reviewer A/B run as normal so the human merge has context

What changed

New files

File Purpose
.claude/commands/write-docs.md The prompt. Doc-paths-only (no vendor/, app/, tests/). Uses MDX screenshot-placeholder comments for features that benefit from images (the bot has no headless browser).
.github/workflows/bot-write-docs.yml The workflow. Sonnet, 30-turn budget, narrow allowlist. Same wheels-bot[bot] author check pattern as the other Phase 4 auto-fire stages.

Modified files

File Change
.claude/commands/triage-issue.md New docs-request classification with explicit boundary against other ("clear deliverable in the issue?"). New branch in step 4 with confidence rating + comment template emitting docs-confidence:high.
.github/workflows/bot-tdd-gate.yml Gains is_docs output that detects docs/bot-* head refs; verify step guards on is_bot && !is_docs. Docs-only PRs by definition have no spec/impl pair.
.github/workflows/bot-update-docs.yml Skips docs/bot-* head refs to avoid the redundant case where update-docs runs on a PR whose entire purpose was docs.
docs/contributing/wheels-bot.md Six stages → seven; new "### 4. Write Docs" section; Update Docs / Reviewer A / Reviewer B renumbered 5/6/7; markers table updated.

Design decisions worth flagging

# Decision Rationale
1 Separate workflow vs. dual-mode bot-update-docs.yml bot-update-docs adds commits to an existing PR; bot-write-docs creates a new PR. Different env shape (PR number vs issue number), different concurrency key, different branch creation. Two narrow workflows keep each one clear.
2 TDD gate skips by branch prefix, not by author or label Branch prefix is the cleanest signal — it's set once at branch creation and read on every gate run. Plus it lets humans replicate the docs-only pattern by naming branches docs/bot-* (though no human would, which is fine).
3 Sonnet not Opus, 30 turns Doc work is translation-of-code, pattern-recognition. Sonnet handles it well at much lower cost than Opus. Mirrors bot-update-docs.yml's choice.
4 Screenshots are placeholder comments, not skipped Honest about the bot's limits. The PR description lists each placeholder so the human reviewer knows exactly what images need capturing.
5 Auto-fire on docs-confidence:high Phase 4 consistency — all confidence-marker auto-fires use the same shape. Kill switch + bot-author check are the safety nets.
6 Reviewer A/B still run on docs PRs PR #2534's broadened condition (bot PR even draft → review) already covers this. No new work needed.

Coordinated repo-level change

The wheels-bot push scope ruleset (16174270) needed docs/bot-*/** added to the allowed push patterns alongside bot/** and fix/bot-*/**. Done out-of-band via the GitHub UI before this PR landed.

Test plan

After merge, file an issue that should classify as docs-request (e.g., the Debug Panel docs gap discussed earlier) and observe:

  • Triage classifies as docs-request (not other or framework-design).
  • Triage emits wheels-bot:docs-confidence:high on a clear, well-scoped docs gap.
  • bot-write-docs.yml auto-fires from the marker (event = issue_comment, author = wheels-bot[bot]).
  • Bot creates docs/bot-<issue>-<slug> branch and opens a draft PR.
  • PR diff is doc-paths-only (no vendor/, app/, tests/).
  • PR body lists screenshot placeholders if any were inserted.
  • bot-tdd-gate.yml runs and exits cleanly with "Docs-only bot PR — gate is a no-op" message (no spec required).
  • bot-update-docs.yml does NOT fire on the docs PR (head ref starts with docs/bot-).
  • Reviewer A runs on the draft PR.
  • Reviewer B fires after Reviewer A submits.
  • PR remains --draft until a human marks ready and approves.

🤖 Generated with Claude Code

Tonight's pipeline test ([#2530] → [#2533]) demonstrated that
propose-fix produces solid bug-path PRs end-to-end, but the existing
classification taxonomy left a gap: pure docs-request issues fell
through into `other` (no automation) or, if reframed as
`framework-design`, would attempt the TDD-shaped propose-fix prompt
that doesn't fit doc-only work.

This PR adds a fourth classification path:

  triage → docs-request + docs-confidence:high
       → bot-write-docs.yml
       → docs/bot-<issue>-<slug> branch
       → draft PR (TDD gate skips, since the branch prefix says docs)
       → Reviewer A/B run as normal so the human merge has context

## What changed

### New files

- `.claude/commands/write-docs.md` — the prompt. Mirrors propose-fix's
  shape but is doc-paths-only (no specs, no test runs, no `vendor/`,
  `app/`, or `tests/` writes). Uses screenshot-placeholder MDX comments
  for features that benefit from images, since the bot can't run a
  headless browser.
- `.github/workflows/bot-write-docs.yml` — the workflow. Sonnet not
  Opus (doc work is pattern-recognition, not reasoning-heavy); 30-turn
  budget; narrow allowlist; same `wheels-bot[bot]` author check as the
  other Phase 4 auto-fire stages.

### Modified files

- `.claude/commands/triage-issue.md` — adds `docs-request` to the
  classification taxonomy with explicit boundary against `other`
  ("clear deliverable in the issue?"); adds the docs-request branch in
  step 4 with confidence rating + comment template emitting the
  `docs-confidence:high` marker.
- `.github/workflows/bot-tdd-gate.yml` — gains `is_docs` output that
  detects `docs/bot-*` head refs; the verify step now guards on
  `is_bot && !is_docs`. Docs-only PRs by definition have no spec/impl
  pair to validate.
- `.github/workflows/bot-update-docs.yml` — skips `docs/bot-*` head
  refs to avoid the redundant case where update-docs runs on a PR
  whose entire purpose was docs.
- `docs/contributing/wheels-bot.md` — six stages → seven; new "### 4.
  Write Docs" section; Update Docs / Reviewer A / Reviewer B
  renumbered to 5/6/7; markers table gains the three new markers
  (`docs-confidence:high`, `write-docs:<issue>`, `docs-held:<issue>`)
  and adds `docs-request` to the triage-class enumeration.

## Why a separate workflow rather than a mode of bot-update-docs

The two workflows look superficially similar but their inputs are
different shapes — bot-update-docs adds a commit to an *existing* PR
(needs PR number), bot-write-docs creates a *new* PR from an issue
(needs issue number). Combining them would require dual-mode logic
in one workflow with different env, different concurrency keys, and
a non-trivial branch on event_name. Two narrow workflows keep each
one clear about its job.

## Coordinated repo-level change

The `wheels-bot push scope` ruleset (16174270) needs `docs/bot-*/**`
added to the allowed push patterns alongside `bot/**` and `fix/bot-*/**`.
Done out-of-band via the GitHub UI before this PR landed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the docs label May 10, 2026
Copy link
Copy Markdown
Contributor

@wheels-bot wheels-bot Bot left a comment

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: Solid addition of the docs-request → write-docs pipeline path. The workflow structure, idempotency guards, TDD-gate bypass, and marker naming are all consistent with the existing Phase 4 conventions. One meaningful omission: CLAUDE.md's ## Wheels Bot section was not updated and is now stale in three distinct ways — which matters because that section is loaded as primary context on every bot run. Two minor nits follow.


Docs

CLAUDE.md §Wheels Bot not updated — four separate staleness issues

CLAUDE.md is loaded into every agent's context via the system reminder on every run. The PR correctly updated docs/contributing/wheels-bot.md, but CLAUDE.md still reflects a five-stage world:

1. Stage count (line 1091)

Five stages, all opt-out via the `[skip-claude]` label ...

With this PR the count is seven (Triage, Research, Propose Fix, Write Docs, Update Docs, Reviewer A, Reviewer B). A future triage agent reading line 1091 will have a wrong mental model of the pipeline.

2. Triage output description (line 1095)

| Triage | issue opened/reopened | Sonnet | Comment classifying as `bug` / `framework-design` / `other` (+ confidence on `bug` path). |

docs-request is missing from the classification list and the note about confidence only mentions the bug path. A triage agent using this as its authoritative reference may classify actionable docs issues as other rather than docs-request.

Suggested replacement:

| Triage | issue opened/reopened | Sonnet | Comment classifying as `bug` / `framework-design` / `docs-request` / `other` (+ confidence on `bug` and `docs-request` paths). |

3. Stage table (lines 1093–1099)

Write Docs and Update Docs are absent from the table. Suggested additions after Propose Fix:

| Write Docs | bot triage emits `docs-confidence:high` (or `workflow_dispatch`) | Sonnet | Doc-paths-only draft PR on branch `docs/bot-<issue>-<slug>`. TDD gate skips; Reviewer A/B still run. |
| Update Docs | bot PR opened / synchronized | Sonnet | Doc commits added to a freshly-opened bot fix PR (skips `docs/bot-*` branches). |

4. Marker conventions (line 1102) and auto-fire safety net (line 1113)

- `<!-- wheels-bot:triage-class:<bug|framework-design|other> -->`

Missing docs-request from the class enum. The new markers (docs-confidence:high, write-docs:<issue>, docs-held:<issue>, update-docs:<pr>) are also absent. And line 1113's auto-fire safety net only mentions the triage → research → propose-fix chain, leaving out triage → write-docs.

These are all in CLAUDE.md at lines 1091–1113, which are not in the diff. A follow-up commit touching that section would close the gap.


Conventions

Push detection uses working-tree diff rather than commit count

In .github/workflows/bot-write-docs.yml, the push step detects whether Claude produced any work:

if git diff --quiet origin/develop -- && git diff --cached --quiet; then
  echo "No changes produced — nothing to push."
  exit 0
fi
git push -u origin "${{ steps.branch.outputs.name }}"

This works correctly in practice — after a commit the working tree matches HEAD, which differs from origin/develop, so the diff is non-empty and the push fires. But the intent is "did Claude create any new commits?", and the direct check for that is:

if git log origin/develop..HEAD --oneline | grep -q .; then
  git push -u origin "${{ steps.branch.outputs.name }}"
else
  echo "No commits produced — nothing to push."
fi

The current form works but will confuse anyone debugging a future partial-failure scenario (e.g. Claude left uncommitted edits in the working tree — the diff fires but nothing is actually committed). Low priority, noting for clarity.

Prompt step 7 vs. gh pr create auto-push

write-docs.md step 7 says "The caller workflow handles the actual git push — just commit cleanly." Step 8 then instructs Claude to call gh pr create, which auto-pushes the branch to remote if it has no upstream. The separate push step in the workflow becomes a no-op in the happy path. The comment in step 7 is technically inaccurate (gh pr create is the actual pusher). Not a bug, but the explanation may mislead a future prompt editor. Adjusting step 7 to say "Do not call git push directly — the gh pr create in step 8 handles the upstream push, and the workflow has a safety-net push step for the uncommon case where gh does not push" would be clearer.


Commits

Single commit: ci: add docs-request path — write-docs stage parallel to propose-fix. Type ci, no scope, sentence-case subject, well under 100 chars. ✓ Commit message describes the why (parallel path for docs work, mirrors propose-fix's shape) rather than the what. ✓


Security

The issue_comment auto-fire condition on bot-write-docs.yml is correctly gated on github.event.comment.user.login == 'wheels-bot[bot]'. The bot-identity check is load-bearing as the comment notes, and it matches the pattern from the other Phase 4 workflows. The allowed_bots parameter on the Claude action is scoped to bot identities and does not widen the trigger surface. No issues found.

The filesystem write scope (doc paths only) is enforced at the prompt level rather than the tool allowlist — Write is unrestricted in allowedTools. This is the same accepted pattern as bot-propose-fix.yml. Worth noting that the allowlist is the only enforcement; a sufficiently confused agent could write to non-doc paths. The TDD gate skip is keyed on branch prefix, not on file paths actually changed — so a docs bot PR that snuck in a vendor/ file would still pass the gate. Acceptable risk for now but a follow-up git diff --name-only check in the gate could tighten this later.


@wheels-bot
Copy link
Copy Markdown
Contributor

wheels-bot Bot commented May 10, 2026

Wheels Bot — Reviewer B (round 1)

A's review is substantive and well-verified. The primary finding -- CLAUDE.md's Wheels Bot section not updated -- is accurate and operationally significant: CLAUDE.md is loaded as primary agent context on every bot run, and the stale stage count, missing docs-request classification, absent stage rows, and incomplete marker list are all confirmed against the diff. The two minor nits are correctly characterized as low-priority. No sycophancy, no false positives. One framing note and one verdict-alignment concern below.

Sycophancy

None detected. A used COMMENTED rather than approve, consistent with a real finding that has live operational impact.

False positives

None detected. Every claim A makes is accurate against the diff:

  • CLAUDE.md was not touched in this PR -- confirmed by reading the diff (no CLAUDE.md hunk present).
  • Stage count ("Five stages"), triage output row (missing docs-request), and stage table (five rows only) are all verifiably stale in the current file.
  • The push-detection logic (git diff --quiet origin/develop --) works correctly in the success case -- after a commit, working tree equals HEAD which differs from origin/develop, so the diff is non-quiet and the push fires. A correctly identifies the staged-but-not-committed edge case (where the diff fires but nothing is committed, resulting in a no-op push). The characterization is accurate; low-priority rating is appropriate.
  • The gh pr create auto-push note is accurate -- gh pr create pushes the branch before opening the PR, making the workflow's separate push step a redundant safety net. Step 7's claim that "the caller workflow handles the actual git push" is inaccurate.

Missed issues

One framing point worth correcting:

  • update-docs gap is pre-existing, not introduced here. A frames Update Docs as jointly absent from CLAUDE.md alongside Write Docs, implying both omissions belong to this PR. update-docs was already a stage before this PR and was already missing from CLAUDE.md's table -- this PR didn't introduce that gap. The correct framing: this PR adds Write Docs as a new stage and, since it was already editing bot docs, was a natural opportunity to close both the new (write-docs) and the pre-existing (update-docs) CLAUDE.md gaps simultaneously. A's suggested table rows are correct either way; the attribution is minor.

No cross-engine issues exist -- no CFML changed. No commit convention violations. No .ai/wheels/ reference updates needed (no new framework-facing behavior changed). The bot-tdd-gate.yml and bot-update-docs.yml conditional logic is correct.

Verdict alignment

A used COMMENTED rather than request-changes. The CLAUDE.md staleness is not purely cosmetic -- the missing docs-request classification in CLAUDE.md's triage table is a live risk: a future triage agent reading that table as its authoritative reference could classify an actionable docs issue as other and suppress automation. Request-changes would have been more defensible. COMMENTED is within the acceptable range but is the lenient end of it.

@bpamiri bpamiri merged commit 24b83e8 into develop May 10, 2026
7 checks passed
@bpamiri bpamiri deleted the peter/bot-docs-request-path branch May 10, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant