aboutsummaryrefslogtreecommitdiff
path: root/claude-rules
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-10 12:59:07 -0500
committerCraig Jennings <c@cjennings.net>2026-05-10 12:59:07 -0500
commit549e67670074c82ca9303a647a5c68cf5529959f (patch)
tree6e3d154c279ea9f69d6d6b84f7d555936bf3e1f3 /claude-rules
parentc1e162cc74f00d5251a7a5eedcc8dd7eb9870459 (diff)
downloadrulesets-549e67670074c82ca9303a647a5c68cf5529959f.tar.gz
rulesets-549e67670074c82ca9303a647a5c68cf5529959f.zip
docs(commits): add Step 0 pre-flight reconcile and pre-push check
The publish flow had no fetch step before commit, PR creation, or push. Long sessions or multi-machine work could land local commits on a stale base, producing non-fast-forward push failures that you have to unwind under publish-step pressure. Step 0 fetches all remotes and checks the current branch against its upstream before Step 1's code review. If the branch is behind, the rule branches on tree state and divergence shape: clean fast-forward, surface dirty-tree behind, or surface a true divergence and ask before rebasing or merging. The Step 0 wording covers the new-branch case (no upstream → skip the divergence check, the first push sets it). The Pre-push reconcile bullet in Merge Strategy handles the smaller window between Step 0 and the actual push. Reviewing and drafting can take several minutes; another machine or teammate can push during that window. One more fetch immediately before push is cheaper than recovering after a failed push.
Diffstat (limited to 'claude-rules')
-rw-r--r--claude-rules/commits.md52
1 files changed, 51 insertions, 1 deletions
diff --git a/claude-rules/commits.md b/claude-rules/commits.md
index 84f408b..754c53f 100644
--- a/claude-rules/commits.md
+++ b/claude-rules/commits.md
@@ -218,9 +218,52 @@ problem belong out. Same conciseness pressure as commit-message bodies.
Commits and PRs are team-visible, permanent, and hard to amend once shared
(especially after push or after a reviewer has replied). Before executing
`git commit` or `gh pr create`, the change must pass a local code review
-*and* the message must be reviewed by the user. The flow has two steps, in
+*and* the message must be reviewed by the user. The flow has three steps, in
order.
+### Step 0: pre-flight reconcile (mandatory)
+
+Before reviewing the diff, fetch from the remote and reconcile against the
+upstream of the current branch. Reconciliation can change the working state
+when a rebase brings in upstream commits that touch staged files, and that
+would invalidate Step 1's review. Handling drift first means the review and
+the commit message describe the post-reconcile state.
+
+1. Fetch all remotes:
+
+ git fetch --all --prune
+
+2. If the current branch has no upstream (new branch, never pushed), skip
+ to Step 1 — there's nothing to reconcile against, and the first push
+ sets the upstream.
+
+3. Otherwise, check divergence against `@{u}`:
+
+ git rev-list --left-right --count @{u}...HEAD
+
+ Output is `<behind>\t<ahead>`. Decide based on the pair:
+
+ - **0 behind, anything ahead** — no-op. Continue to Step 1.
+ - **Behind only, clean tree** — fast-forward: `git merge --ff-only @{u}`.
+ - **Behind only, dirty tree** — surface to the user. Don't auto-stash or
+ auto-merge. Offer to commit or stash first, or skip the reconcile and
+ proceed knowing the push may need attention later.
+ - **Diverged (behind AND ahead)** — surface to the user. Ask whether to
+ rebase the local commits onto upstream (default for feature branches),
+ merge the upstream branch in (rare; preserves both lines), or skip and
+ proceed with the divergence. Don't auto-rebase.
+
+4. **PR flow only.** Also fetch the base branch (usually `main`) and check
+ whether the feature branch's base is behind. Surface this informationally;
+ don't auto-rebase the feature branch without asking. The "X commits
+ behind base" badge on the PR is a follow-up decision, not a reason to
+ block publish.
+
+The startup workflow's `git fetch --all --prune` doesn't substitute for
+Step 0. Upstream can advance during a long session, especially across
+machines or with teammates pushing in parallel. Run Step 0 every time the
+publish flow starts.
+
### Step 1: local code review (mandatory)
Run the `review-code` skill against the change:
@@ -406,6 +449,13 @@ independent gate.
confirmation before `git push`, `gh pr merge`, or any equivalent. The
Review and Publish flow above approves the *content*; merge strategy is
a separate decision that needs its own confirmation.
+- *Pre-push reconcile.* Right before `git push`, do one more
+ `git fetch <remote> <branch>` and verify the local branch is still
+ ahead-only against its upstream. If something landed between Step 0 and
+ push (review and draft together can take several minutes, and another
+ machine or teammate may push in that window), surface and resolve before
+ the push command runs. Catching drift here is cheaper than recovering
+ from a failed non-fast-forward push under publish-step pressure.
- Override the squash default only when there's a concrete reason: a
clean per-commit review history the user has explicitly asked for, a
multi-commit semantic narrative the team values, etc. Squash is the