Skip to content

Commit 7dbe911

Browse files
committed
docs(workflow): require PRs to mirror their closing issue's triage labels (closes #237)
Adds three mandatory workflow sections to CLAUDE.md: - Post-push CI watcher: arm a background watcher after every push so CI failures are caught and fixed within the same turn rather than sitting overnight. This rule already existed in the system-prompt CLAUDE.md but was absent from the base branch. - CodeRabbit loop: iterate CR passes to silence before declaring a PR done. Same gap — the rule existed locally but not on feat/multicloud-web-frontend. - PR labeling: every PR must carry the same triage labels as the issue it closes (priority/*, severity/*, urgency/*, impact/*, effort/*, type/*, triaged). Unlabeled PRs are invisible to priority-ordered queries. The section codifies the gh invocation, multi-close merge logic, and a closing checkpoint with the same shape as the CI-watcher rule. All three sections are inserted between ## Build & Test and ## Security Rules, matching the layout already present in the working-tree checkout.
1 parent c84fd02 commit 7dbe911

1 file changed

Lines changed: 117 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,123 @@ npm run lint
6666
- ALWAYS run tests after making code changes
6767
- ALWAYS verify build succeeds before committing
6868

69+
## Post-push CI watcher (MANDATORY — even for one-line fix commits)
70+
71+
After **every** `git push` that publishes new commits to a PR branch on
72+
this repo (including follow-up CodeRabbit-nitpick fixes), launch a
73+
background watcher per workflow run **before** ending the turn. This is
74+
the project-level reinforcement of the global rule in
75+
`~/.claude/git-workflow.md` §Post-push CI watcher — CUDly's pre-commit
76+
job alone takes 9–15 min and is silently broken by routine changes
77+
(missing CI tools, pre-existing markdownlint debt, git-secrets
78+
allowlist drift), so leaving a push unwatched routinely lets CI
79+
failures sit overnight.
80+
81+
Mechanics:
82+
83+
1. After `git push`, list the runs the push triggered:
84+
85+
```bash
86+
gh run list --repo LeanerCloud/CUDly --commit "$(git rev-parse HEAD)" \
87+
--limit 10 --json databaseId,workflowName,status
88+
```
89+
90+
2. For each run still in `queued`/`in_progress`, launch one background
91+
watcher script via `Bash` with `run_in_background: true` (do NOT use
92+
foreground polling — the main session must stay unblocked). The
93+
minimum viable watcher polls `gh run view <ID> --json status,conclusion`
94+
every 30s and on completion either reports success or dumps the failed
95+
step digest. A reusable template lives at
96+
`.claude/scripts/watch-ci-run.sh` if present, or write a one-shot to
97+
`/tmp/claude/watch-<sha>-<workflow>.sh`.
98+
99+
3. If a watcher reports failure, the same session investigates and
100+
pushes a fix on the same branch (which fires a fresh watcher round).
101+
Decisions that need a human go to PR comments; everything else is
102+
autonomous per the global rule.
103+
104+
Forgetting this rule has been a recurring failure mode in this
105+
project. Before declaring a "pushed and done" turn complete, confirm
106+
at least one `ci-watch-*` background task is armed.
107+
108+
## CodeRabbit loop — iterate to silence (MANDATORY)
109+
110+
CodeRabbit reviews this repo on every push to a PR branch. The full
111+
rules live in `~/.claude/git-workflow.md` §"Post-PR review loop"
112+
(§§3, 3a) — read them. The minimum-viable loop for this project:
113+
114+
1. After every push, ping `@coderabbitai review` on the PR (CR doesn't
115+
always re-review automatically; the explicit ping makes it
116+
deterministic).
117+
2. Wait for the review (60–120s polling, soft-handle 429s).
118+
3. Triage every Actionable / Outside-diff / Nitpick finding into:
119+
actionable-fix-now, dismiss-with-justification-on-thread, or
120+
genuine-nitpick-batch-into-one-fix-commit.
121+
4. Push the fix(es), comment on the PR summarising what was addressed
122+
vs. dismissed (and why), end the comment with a fresh
123+
`@coderabbitai review` ping.
124+
5. **Repeat until CR's most recent review has zero Actionable items
125+
AND every Nitpick is either fixed or has a justification reply.**
126+
"I fixed pass 1" is not loop-exit. CUDly PRs commonly run 3–6 CR
127+
passes before settling.
128+
6. If a fix push triggers conflicts (`mergeStateStatus: DIRTY`), resolve
129+
them per `~/.claude/git-workflow.md` §3a — `git rebase
130+
origin/<base>`, atomic conflict resolution, `git push
131+
--force-with-lease`, post a rebase note on the PR, then continue
132+
the CR loop.
133+
134+
Forgetting this rule leaves CR threads silently unresolved and pushes
135+
the triage burden onto the human reviewer.
136+
137+
## PR labeling — mirror closing-issue labels (MANDATORY)
138+
139+
Every PR opened in this repo must carry the **same** triage labels as
140+
the issue it closes — `priority/*`, `severity/*`, `urgency/*`,
141+
`impact/*`, `effort/*`, `type/*`, plus `triaged` if the issue carries
142+
it. Skipping this leaves PRs invisible to the same priority queries
143+
that surface the issues, so an unlabeled PR is effectively
144+
unreviewable in priority order.
145+
146+
Mechanics — fold into the **same `gh pr create` round**, before pinging
147+
CodeRabbit:
148+
149+
```bash
150+
# Right after `gh pr create ...` returns the PR URL:
151+
PR_NUM=<the number gh just printed>
152+
ISSUE_NUM=<the issue this PR closes>
153+
154+
LABELS=$(gh issue view "$ISSUE_NUM" --repo LeanerCloud/CUDly --json labels \
155+
--jq '[.labels[].name | select(test("^(priority|severity|urgency|impact|effort|type)/")) ]
156+
+ (if [.labels[].name] | any(. == "triaged") then ["triaged"] else [] end)
157+
| join(",")')
158+
159+
gh pr edit "$PR_NUM" --repo LeanerCloud/CUDly --add-label "$LABELS"
160+
161+
# Verify
162+
gh pr view "$PR_NUM" --repo LeanerCloud/CUDly --json labels \
163+
--jq '[.labels[].name] | sort | join(",")'
164+
```
165+
166+
If the closing issue lacks the `triaged` label, do NOT apply
167+
`triaged` to the PR — that would lie. Surface the gap in the PR body
168+
(or as a comment on the issue) so the human can triage.
169+
170+
If a label doesn't yet exist in the repo (rare — the label set is
171+
populated from the existing issue queue), `gh label create` it with
172+
the same color/description as a sibling label BEFORE applying.
173+
174+
For PRs that close more than one issue (e.g., a PR that closes
175+
`#A` and `#B`): take the **highest** `priority/*` and `severity/*`
176+
across the issues; `union` the rest (`type/*`, `effort/*`, `impact/*`,
177+
etc.). The PR represents the work for both, so it should be
178+
discoverable under either filter.
179+
180+
Forgetting this rule has the same shape as forgetting the post-push
181+
CI watcher: it silently breaks priority-ordered review and triage.
182+
Before declaring a "PR opened and done" turn complete, confirm the
183+
label set on the PR matches the closing issue's set (or the merged
184+
set for multi-close PRs).
185+
69186
## Security Rules
70187

71188
- NEVER hardcode API keys, secrets, or credentials in source files

0 commit comments

Comments
 (0)