Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,17 @@ Before answering architecture questions or starting non-trivial work in an unfam
- Enter plan mode for ANY non-trivial task (3+ steps or architectural decisions). If something goes sideways, STOP and re-plan.
- **Plan format**: atomic tasks with explicit file paths, each independently verifiable. State what changes, where, and how to prove it works.
- **User checkpoint**: for multi-commit plans, cross-cutting refactors, or anything touching shared infrastructure (`infra-ops.md`), share the plan before implementing.
- **Plan review loop — MANDATORY gate before implementation starts**: review the plan, fix every issue, re-review. Repeat until **three consecutive passes find nothing** (any finding restarts the count at zero). Do NOT create the §1b worktree, enter ExitPlanMode, or write code until this passes. Each pass covers: the five review dimensions (see below); Reuse (§1a); scope discipline (only what was asked?); blast radius (callers, tests, migrations, downstream consumers all listed?); unknowns (verify "verify-first" items NOW, not at implementation time). Per-pass findings go in the plan as a short "review pass N" note.
- **Plan review loop — MANDATORY gate before implementation starts**: review the plan, fix every issue, re-review. Repeat until **three consecutive passes find nothing** (any finding restarts the count at zero). Do NOT create the §1b worktree, enter ExitPlanMode, or write code until this passes. Each pass covers: the six review dimensions (see below); Reuse (§1a); scope discipline (only what was asked?); blast radius (callers, tests, migrations, downstream consumers all listed?); unknowns (verify "verify-first" items NOW, not at implementation time). Per-pass findings go in the plan as a short "review pass N" note.
- Only after three clean passes: implement in distinct atomic commits, writing tests as you go.
- **⚠️ MANDATORY post-implementation review — NO EXCEPTIONS**: after implementing, review ALL changes before reporting done. Hard gate; never skip or defer. Fix every issue, re-review, don't declare done until clean.

**The five review dimensions** (used by the plan-review gate, the post-implementation review, the §1c local loop, and the `git-workflow.md` pre-commit loop):
**The six review dimensions** (used by the plan-review gate, the post-implementation review, the §1c local loop, and the `git-workflow.md` pre-commit loop):
- **Completeness**: fulfils every requirement? Nothing left out?
- **Correctness**: logic errors, off-by-ones, wrong assumptions, broken control flow?
- **Security**: injection, auth bypass, secrets exposure, OWASP top 10, input validation at boundaries?
- **Bugs**: race conditions, null derefs, edge cases, error-handling gaps, resource leaks?
- **Duplication**: re-invents anything already in the project? If yes, reuse/refactor per §1a.
- **Over-engineering**: is every parameter set by a real caller, every abstraction used by more than one consumer, every guard protecting a reachable state, every comment earning its line? Prune what fails, per `coding-standards.md` ("Simplicity & Scope (YAGNI)"), and remove it safely per that file's "Verifying a Refactor". Review this dimension **adversarially**: the author's local justification for a piece of machinery almost always holds up, so ask instead what the calling system actually does and what would break if the machinery were deleted. Correct, well-tested code guarding an unreachable state still comes out.

### 1a. Reuse Before Writing — Avoid Duplication

Expand Down Expand Up @@ -120,7 +121,7 @@ Every code change the implementer (Sonnet for simpler changes, Opus for non-triv

The loop:
1. **The implementer (Sonnet or Opus per §2) implements** an atomic task (or one logically complete chunk) per the approved plan.
2. **Opus reviews the diff locally** across the five review dimensions plus Reuse (§1a) and scope discipline. Spawn a dedicated Opus reviewer subagent (set via `model`) to keep the implementer's context clean; escalate the review to Fable only for the hardest money-path / architecture calls where peak intelligence matters. Emit a concrete findings list (`file:line` + what's wrong + suggested fix), or an explicit "no actionable findings".
2. **Opus reviews the diff locally** across the six review dimensions plus Reuse (§1a) and scope discipline. Spawn a dedicated Opus reviewer subagent (set via `model`) to keep the implementer's context clean; escalate the review to Fable only for the hardest money-path / architecture calls where peak intelligence matters. Emit a concrete findings list (`file:line` + what's wrong + suggested fix), or an explicit "no actionable findings".
3. **The implementer addresses** every finding. Mechanical, decided fixes stay with the implementer; a finding needing a design call escalates that item to Opus (or Fable for a peak call, §2 carve-out), then the decided fix goes back to the implementer.
4. **Opus re-reviews** the updated diff.
5. Repeat 3-4 until a review pass returns no actionable findings. "Until everything is addressed" means a clean pass, not "the obvious ones are fixed".
Expand Down Expand Up @@ -224,7 +225,7 @@ Full rules in `~/.claude/git-workflow.md` — **read before every commit, PR, or
- **Repo first — check at TASK START, not commit time**: if you're working in a PROJECT dir that isn't a git repo (`Is a git repository: false`, no `.git`), `git init` immediately, before the first non-trivial edit. You cannot make atomic commits — or recover intermediate states — without one, and multi-phase work in an unversioned tree loses its per-step history irreversibly. Creating a repo is safe and additive (the opposite of the never-destroy-`.git` rule §9); don't let that caution bleed into not creating one. Then commit per phase as you go, never one giant commit at the end. **Exceptions (do NOT init):** the home dir itself, system temp / scratchpad (`/tmp`, `$TMPDIR`), `~/Downloads`/`~/Desktop` and similar non-project scratch locations. Anything done in a project dir needs a repo. Detail in `git-workflow.md`.
- **Conventional commits**: `type(scope): subject`, imperative, ≤72 chars. Never mention Anthropic/Claude. Never use heredoc-based `git commit -m` — `Write` a fresh uniquely-named file under `/tmp/claude/`, commit with `git commit -F`, delete it after.
- **Small atomic commits**: one concern each, independently revertable.
- **⚠️ Mandatory pre-commit review loop — 3 clean passes**: read `git diff --cached` and check the five review dimensions (§1). Fix in the same changeset, never via follow-up commits. **Run this review on Opus as comprehensively as possible (escalate to Fable only for the hardest / highest-stakes diffs) — CodeRabbit's lens is the floor, not the ceiling** (architecture, type design, silent failures, test coverage, security, comment accuracy, performance, convention fit; fan out the `pr-review-toolkit:*` agents for substantial diffs). Goal: land clean for CR AND humans on the first pass. Catching a finding locally costs one pass; catching it after review costs a push + review wait + fix commit + another round. Shipping it well the first time is much faster.
- **⚠️ Mandatory pre-commit review loop — 3 clean passes**: read `git diff --cached` and check the six review dimensions (§1). Fix in the same changeset, never via follow-up commits. **Run this review on Opus as comprehensively as possible (escalate to Fable only for the hardest / highest-stakes diffs) — CodeRabbit's lens is the floor, not the ceiling** (architecture, type design, silent failures, test coverage, security, comment accuracy, performance, convention fit; fan out the `pr-review-toolkit:*` agents for substantial diffs). Goal: land clean for CR AND humans on the first pass. Catching a finding locally costs one pass; catching it after review costs a push + review wait + fix commit + another round. Shipping it well the first time is much faster.
- **Post-push CI watcher**: after every `git push`, enumerate all workflow runs for the pushed commit and launch one background `Agent` per run (`run_in_background: true`) named `ci-watch-<short-sha>-<workflow-slug>`. Each fetches failed logs and **fixes failures autonomously**. Coordinate via the `git-push` lock before pushing fixes. Escalate only for decisions.
- **PRs**: ≤400 lines, one concern, conventional-commit title, feature branch `type/short-description`. Never `--no-verify`; never `gh pr merge --admin` to merge past pending/failing checks (the merge-time analog of `--no-verify` — merge only from MERGEABLE+CLEAN with CR settled; a blanket "merge them" is not authorization to bypass a check; see `git-workflow.md` §4).
- **Post-PR review loop**: after `gh pr create`, trigger CodeRabbit (`@coderabbitai review`) **and spawn `cr-watch-<pr-#>` as ONE atomic action — posting the trigger without arming the watcher is a defect identical in shape to `git push` without a CI watcher; safe ordering is spawn-watcher-then-trigger so a posted trigger always implies a live watcher** (re-request CR after every push to the PR branch and wait ~10 min before triaging so CR has time to post, then 60-120s polling, soft-handle 429s — but recover from any CR rate-limit with `@coderabbitai full review`, never the incremental `@coderabbitai review`, since a throttled pass silently skips the in-flight commits and yields a false-clean), triage suggestions (actionable / dismiss-with-justification / batch-nitpick), push fixes per the pre-commit loop, then re-ping `@coderabbitai review` and loop until a clean review (**never** `@coderabbitai resolve` or hand-resolving threads to silence the bot), then `merge-watch-<pr-#>` awaits **human merge** (no self-merge by default), then deploy + verify (Chrome MCP for UI, `curl` for API, `terraform plan` for IaC), then post a recommendation-to-close on the originating issue and **file new issues for out-of-scope follow-ups**. **Before declaring PR work done for a session (or any time you spot unaddressed CR comments), run the reconciliation sweep**: every open PR you authored must have a live `cr-watch`, a clean terminal CR state, or be closed — re-arm any that slipped. Full lifecycle in `git-workflow.md`.
Expand Down
13 changes: 13 additions & 0 deletions coding-standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@ Sophistication is a cost, not a virtue. The simplest thing that works wins: fewe

Cut speculation, not behaviour. A parameter a real caller sets, a timeout the platform's default gets wrong, the auth config a private dependency needs: all load-bearing, however many lines they add. "Shorter" is the usual symptom of getting this right, not the goal.

## Verifying a Refactor

A cleanup that changes behaviour is a bug wearing a tidy diff. "Delete aggressively" is only safe paired with proof you deleted nothing that mattered, so cutting and proving are one task, not two.

- **Subtractive only.** Delete and inline; never introduce an abstraction to "simplify". A clever restructure is a behaviour change you haven't tested yet.

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Scope the “Subtractive only” rule.

Line 50 says to introduce an abstraction at the rule of three. The PR objective says to favor subtractive edits, not to forbid every new abstraction. State that deletion and inlining are preferred for behavior-preserving cleanup, while justified abstractions remain allowed when current callers require them.

Proposed wording
-- **Subtractive only.** Delete and inline; never introduce an abstraction to "simplify".
+- **Prefer subtractive edits.** Delete and inline where this removes unused code. Introduce an abstraction only when a current caller or the rule of three requires it, and verify that behavior is preserved.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@coding-standards.md` at line 67, Update the “Subtractive only” guidance in
coding-standards.md to scope it to behavior-preserving cleanup: state that
deletion and inlining are preferred, while justified abstractions remain allowed
when required by existing callers and the rule of three. Preserve the warning
against untested behavior-changing restructures.

- **Compare the generated output, not just the tests.** Where code emits an artifact (IaC plans/synth, migrations, codegen, bundles, snapshots), byte-compare it before and after and require it identical. Green tests routinely coexist with a changed artifact: in IaC a renamed logical id silently destroys and recreates live infrastructure, and no unit test sees it. Compare *every* emitted file, not just the obvious one.

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Define the handling of non-deterministic artifacts.

Line 68 requires byte-identical output for every generated artifact. Some generators include timestamps, absolute paths, generated identifiers, or unstable ordering. Require deterministic generation first. If that is not possible, define a canonical comparison for documented volatile fields and report those fields explicitly.

Proposed wording
- Compare the generated output, not just the tests. Where code emits an artifact (IaC plans/synth, migrations, codegen, bundles, snapshots), byte-compare it before and after and require it identical.
+ Compare the generated output, not just the tests. Make generation deterministic, then byte-compare every emitted file before and after and require it identical. If determinism is impossible, define and review a canonical comparison for documented volatile fields.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@coding-standards.md` at line 68, Update the generated-artifact comparison
guidance in coding-standards.md to require deterministic generation before byte
comparison. For unavoidable volatility such as timestamps, absolute paths,
generated identifiers, or ordering, define and document a canonical comparison
that normalizes only those fields and explicitly reports them; retain the
requirement to compare every emitted file.

- **Carry a protected list into the work.** Name the decisions that must survive (with the one-line reason) before starting. Hard-won constraints look exactly like cruft to a reader who wasn't there, and get "cleaned up" first.
- **Never delete a security assertion on your own judgement.** Tests pinning authorization, resource scoping, or privilege boundaries come out only with the owner's explicit sign-off, however redundant they look.
- **"Nothing here is worth removing" is a complete answer.** Manufacturing changes to show effort is how a safe refactor becomes a risky one.
- **Report what you left.** The candidates you considered and rejected, and why, are as useful to the reviewer as the diff.

If you can't prove an edit is behaviour-preserving, don't make it. A small confident diff beats a large clever one.

## Preferred Stack

- **Language**: Go for new backend/CLI projects; TypeScript/Node for frontend, lightweight CLIs, or when the ecosystem fit is strong; match the existing language for additions to existing projects
Expand Down
6 changes: 4 additions & 2 deletions git-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ This is the first thing to check, because everything else here is worthless with

Before every commit, enter a review loop (same discipline as the plan review loop). Do NOT commit after a single pass — iterate until **3 consecutive review passes find zero issues**. Do NOT skip, shortcut, or batch this step. The goal is to land clean commits in the first place, so the history doesn't need fix-up commits.

**Review on Opus, as comprehensively as possible — CodeRabbit's lens is the floor, not the ceiling.** This review is judgement-heavy, so run it at Opus tier (the §1c local review loop and the plan-review gate are its analogues — both Opus per `CLAUDE.md` §2); escalate to the Fable reserve only for the hardest / highest-stakes money-path diffs. The five dimensions above are the baseline; then go wider than any single reviewer would. Review as CodeRabbit would (its Actionable / Nitpick categories, the project's CR config, recurring past CR findings) AND as a demanding staff engineer would, across at least:
**Review on Opus, as comprehensively as possible — CodeRabbit's lens is the floor, not the ceiling.** This review is judgement-heavy, so run it at Opus tier (the §1c local review loop and the plan-review gate are its analogues — both Opus per `CLAUDE.md` §2); escalate to the Fable reserve only for the hardest / highest-stakes money-path diffs. The six dimensions above are the baseline; then go wider than any single reviewer would. Review as CodeRabbit would (its Actionable / Nitpick categories, the project's CR config, recurring past CR findings) AND as a demanding staff engineer would, across at least:

- **Architecture & design fit** — does the change belong where it landed, follow the module's patterns, and avoid leaking abstractions?
- **Type design & invariants** — are illegal states unrepresentable, invariants expressed in types rather than asserted at runtime, encapsulation intact?
Expand All @@ -53,7 +53,7 @@ For multi-concern or substantial diffs, fan out the specialised review agents in

### Each pass

Read the full staged diff (`git diff --cached`) and the relevant unstaged context, and systematically check all five dimensions:
Read the full staged diff (`git diff --cached`) and the relevant unstaged context, and systematically check all six dimensions:

- **Completeness**: Does the commit deliver what it claims? Nothing missing? All touched files consistent with the commit message? Tests updated for the changed behaviour?
- **Correctness**: Any logic errors, off-by-ones, wrong assumptions, broken invariants, stale references, type mismatches, leftover debug code, unused imports?
Expand Down Expand Up @@ -93,6 +93,8 @@ If the review finds issues, fix them in the same staged changeset — do not com

After committing, run a quick sanity scan (`git show HEAD`) to catch anything the pre-commit loop missed. If this finds issues, treat it as a process failure (the pre-commit loop should have caught them). Fix-forward in a new commit only when strictly necessary (e.g., pre-commit hook caught a legitimate issue that required the commit to land first).

**Hooks may silently not run in a worktree.** When a repo sets `core.hooksPath` to a gitignored, install-generated directory (husky's `.husky/_` is the common case), that path exists only where the install ran — usually the main checkout. Git skips hooks with no warning when it doesn't resolve, so commits from a worktree can quietly bypass lint, formatting and generated-artifact rebuilds. Since §1b puts non-trivial work in worktrees, check once per worktree (`git config core.hooksPath`, then confirm the directory exists) and run the checks by hand if it doesn't. Never paper over it with `--no-verify`.

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

root=$(git rev-parse --show-toplevel)
hooks=$(git config --get core.hooksPath || git rev-parse --git-path hooks)
case "$hooks" in /*) ;; *) hooks="$root/$hooks" ;; esac
test -x "$hooks/pre-commit"

Repository: LeanerCloud/dotclaude

Length of output: 159


🏁 Script executed:

printf '%s\n' '--- git-workflow.md ---'
sed -n '80,105p' git-workflow.md
printf '%s\n' '--- hook-related guidance ---'
rg -n -C 3 'core\.hooksPath|pre-commit|hooks|worktree' --glob '!node_modules' .
printf '%s\n' '--- repository state ---'
git config --show-origin --get core.hooksPath || true
git rev-parse --show-toplevel
git rev-parse --git-dir
git rev-parse --git-path hooks

Repository: LeanerCloud/dotclaude

Length of output: 50379


🌐 Web query:

Git core.hooksPath relative path worktree git rev-parse --git-path hooks executable hook behavior

💡 Result:

The behavior of core.hooksPath, particularly regarding relative paths and git worktrees, is governed by how Git resolves directory paths during execution [1][2][3]. Core.hooksPath Behavior Git allows you to override the default hooks directory ($GIT_DIR/hooks) using the core.hooksPath configuration variable [1][2][3]. When set to a relative path, Git interprets this path relative to the current working directory from which the Git command is executed, not necessarily the repository root or the.git directory [1][3]. Before executing a hook, Git changes its working directory to the root of the working tree (in non-bare repositories) or to the $GIT_DIR (in bare repositories) [2][3]. Git Worktree Considerations Git worktrees often lead to complications when using relative paths for core.hooksPath [4][5][6]. Because Git resolves relative paths based on the current working directory, a path that works in the main repository may fail in a worktree if the working directory structure differs [4][6]. For instance, if core.hooksPath is set to a relative path like.hooks, and you run a Git command from inside a worktree, Git will look for.hooks relative to that specific worktree's root, which may not contain the expected hooks directory [5][6]. To ensure consistent behavior across worktrees, it is generally recommended to use absolute paths [4][5][6]. Git rev-parse --git-path hooks The command git rev-parse --git-path hooks is designed to respect the core.hooksPath configuration [7][8]. If core.hooksPath is set, git rev-parse --git-path hooks will return the configured path rather than the default $GIT_DIR/hooks location [7][9]. This command is a reliable way to check where Git expects to find hooks for the current context [7]. You can use the --path-format=(absolute|relative) option (available since Git v2.31) to force the output to be an absolute or relative path, as desired [9][10]. Executable Hook Behavior Regardless of where the hooks are located (via default or core.hooksPath), Git will only execute files that have the executable bit set [11]. If a hook file is found at the specified path but lacks the executable permission, Git will ignore it [11].

Citations:


🏁 Script executed:

git --version
git help --no-man-viewer --no-info 'githooks' 2>/dev/null | sed -n '1,180p' || true
git help --no-man-viewer --no-info 'git-config' 2>/dev/null | rg -n -C 5 'core\.hooksPath|hooksPath' || true
git rev-parse --git-path --path-format=absolute hooks 2>/dev/null || true

Repository: LeanerCloud/dotclaude

Length of output: 212


🏁 Script executed:

set -u
printf '%s\n' '--- effective hook paths ---'
for value in '' '.hooks' '../shared-hooks' '/tmp/absolute-hooks'; do
  if [ -n "$value" ]; then
    printf 'core.hooksPath=%s\n' "$value"
    git -c "core.hooksPath=$value" rev-parse --git-path hooks
    git -c "core.hooksPath=$value" --path-format=absolute rev-parse --git-path hooks 2>&1 || true
  else
    printf '%s\n' 'core.hooksPath=<unset>'
    git rev-parse --git-path hooks
    git --path-format=absolute rev-parse --git-path hooks 2>&1 || true
  fi
done
printf '%s\n' '--- config and repository roots ---'
git config --get core.hooksPath; printf 'config_exit=%s\n' "$?"
git rev-parse --show-toplevel
git rev-parse --git-dir
git rev-parse --git-common-dir

Repository: LeanerCloud/dotclaude

Length of output: 2303


Check the hook file and its executable bit, not only the directory.

A present directory does not prove that pre-commit is available. Resolve the effective hooks path from the worktree root, then verify that each required hook exists and is executable. Run the checks manually if a required hook is missing or not executable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@git-workflow.md` at line 96, Update the worktree hook verification guidance
in git-workflow.md to resolve the effective core.hooksPath from the worktree
root and check each required hook file, especially pre-commit, for both
existence and executable permissions rather than checking only the directory.
Instruct users to run the corresponding checks manually when any required hook
is missing or non-executable, without using --no-verify.


## Rate-limit handling — always run a retry cron, never stall

This is a global rule (see `CLAUDE.md` Core Principles): on every request, keep a retry cron running so any throttling is caught and retried automatically rather than stalling the work. When an operation is throttled — a `429` / `403 secondary rate limit` / "rate limit" / "usage limit" / "try again later" from the GitHub API, CodeRabbit, the model/API itself, or any CLI reporting a cooldown — do NOT abandon the work and do NOT block the session busy-waiting; let the standing cron catch it and retry.
Expand Down
2 changes: 1 addition & 1 deletion issue-pr-autopilot.plan.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ You are an autonomous PLANNING agent running on a schedule (the Opus planner tie

## Second source: dotclaude (global engineering guidelines - authoritative for HOW)
A second repo LeanerCloud/dotclaude is cloned into your workspace. Locate it (e.g. `find . -name git-workflow.md -path '*dotclaude*'` or look for a sibling dotclaude/ checkout) and read these BEFORE doing any work - they are the authoritative cross-repo rules for HOW to do the work:
- CLAUDE.md - core tenets, plan/review gates, the five review dimensions
- CLAUDE.md - core tenets, plan/review gates, the six review dimensions
- triage.md - the full label rubric and the work-selection ordering you rank by
- coding-standards.md, conventions.md - so your plan targets the right idioms
- worktrees.md - plan structure (atomic tasks, explicit file paths, verifiable)
Expand Down
Loading