diff --git a/CLAUDE.md b/CLAUDE.md index cf3518b50..b7673742f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -12,7 +12,7 @@ ## Planning (ALWAYS follow this process) -- **EVERY TIME** you create or update a plan, you MUST enter a review loop: thoroughly review the plan and fix any issues found. Repeat until 3 consecutive review passes find no issues. Do NOT skip this step — it is mandatory for all plans, no exceptions. +- **EVERY TIME** you create or update a plan, you MUST enter a review loop: thoroughly review the plan and fix any issues found. Repeat until 3 consecutive review passes find no issues. Do NOT skip this step: it is mandatory for all plans, no exceptions. - In each loop iteration, print a summary of found issues before and after fixing them. ## File Organization @@ -67,7 +67,7 @@ surfaced bugs found while working here go into this repository's GitHub issues instead. See `CONTRIBUTING.md` under "Known Issues Sweep" for the full convention (including the cross-component sweep in the platform repo). -## Issue assignment — claim before you work (MANDATORY) +## Issue assignment: claim before you work (MANDATORY) Several people (and their agents) work through this repo's issue queue in parallel. GitHub issue assignment is the lock that keeps two of them from @@ -185,13 +185,13 @@ Work that is not tracked by an issue yet (for example a larger UI or integration effort) gets an issue first, assigned to whoever is doing it, so it shows up as taken. -## Post-push CI watcher (MANDATORY — even for one-line fix commits) +## Post-push CI watcher (MANDATORY, even for one-line fix commits) After **every** `git push` that publishes new commits to a PR branch on this repo (including follow-up CodeRabbit-nitpick fixes), launch a background watcher per workflow run **before** ending the turn. This is the project-level reinforcement of the global rule in -`~/.claude/git-workflow.md` §Post-push CI watcher — CUDly's pre-commit +`~/.claude/git-workflow.md` §Post-push CI watcher: CUDly's pre-commit job alone takes 9–15 min and is silently broken by routine changes (missing CI tools, pre-existing markdownlint debt, git-secrets allowlist drift), so leaving a push unwatched routinely lets CI @@ -208,7 +208,7 @@ Mechanics: 2. For each run still in `queued`/`in_progress`, launch one background watcher script via `Bash` with `run_in_background: true` (do NOT use - foreground polling — the main session must stay unblocked). The + foreground polling; the main session must stay unblocked). The minimum viable watcher polls `gh run view --json status,conclusion` every 30s and on completion either reports success or dumps the failed step digest. A reusable template lives at @@ -246,7 +246,7 @@ rules live in `~/.claude/git-workflow.md` §"Post-PR review loop" "I fixed pass 1" is not loop-exit. CUDly PRs commonly run 3–6 CR passes before settling. 6. If a fix push triggers conflicts (`mergeStateStatus: DIRTY`), resolve - them per `~/.claude/git-workflow.md` §3a — `git rebase + them per `~/.claude/git-workflow.md` §3a: `git rebase origin/`, atomic conflict resolution, `git push --force-with-lease`, post a rebase note on the PR, then continue the CR loop. @@ -258,7 +258,7 @@ When the CodeRabbit loop applies (see Review gate) and you are **delegating PR work to a subagent**, the prompt MUST include the full CR loop, not stop at the first `@coderabbitai review` ping. A fork that pushes the PR, pings CR, then exits leaves the CR threads -unresolved — same failure mode as forgetting the post-push CI watcher. +unresolved, the same failure mode as forgetting the post-push CI watcher. The subagent's exit criteria must be: "CR's most recent review has zero Actionable items AND every Nitpick is either fixed or has a justification reply on the thread", not "PR opened and CR pinged". When @@ -298,10 +298,10 @@ Verification never authorizes real purchases, deploys or the CLI's `--yes`. Any new commit or rebase restarts the gate; a missing reviewer or verification blocks the PR. -## PR labeling — mirror closing-issue labels (MANDATORY) +## PR labeling: mirror closing-issue labels (MANDATORY) Every PR opened in this repo must carry the **same** triage labels as -the issue it closes — `priority/*`, `severity/*`, `urgency/*`, +the issue it closes: `priority/*`, `severity/*`, `urgency/*`, `impact/*`, `effort/*`, `type/*`, plus `triaged` if the issue carries it. Skipping this leaves PRs invisible to the same priority queries that surface the issues, so an unlabeled PR is effectively @@ -321,7 +321,7 @@ LABELS=$(gh issue view "$ISSUE_NUM" --repo LeanerCloud/cloud-commitments-cli --j + (if [.labels[].name] | any(. == "triaged") then ["triaged"] else [] end) | join(",")') -# Guard against empty $LABELS — gh pr edit --add-label "" fails, which would +# Guard against empty $LABELS: gh pr edit --add-label "" fails, which would # silently break this MANDATORY flow. If the closing issue has no triage # labels in the selected classes, surface the gap deterministically instead. if [ -n "$LABELS" ]; then @@ -338,10 +338,10 @@ gh pr view "$PR_NUM" --repo LeanerCloud/cloud-commitments-cli --json labels \ ``` If the closing issue lacks the `triaged` label, do NOT apply -`triaged` to the PR — that would lie. Surface the gap in the PR body +`triaged` to the PR (that would lie). Surface the gap in the PR body (or as a comment on the issue) so the human can triage. -If a label doesn't yet exist in the repo (rare — the label set is +If a label doesn't yet exist in the repo (rare; the label set is populated from the existing issue queue), `gh label create` it with the same color/description as a sibling label BEFORE applying.