@@ -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