docs: reconcile diverging history only by merge (improvise-1xfb.1)

agent-rules gains rule 8, which forbids rebase, squash in any form, reset
that drops commits, amending a pushed commit and force-push. Rule 7 keeps
the SHA pinning for merge, merge-base and diff. The user's reason is quoted
in the rule: the merge structure of git history is a causal record.

AGENTS.md: the fix-after-merge recipe is now a merge. The wrong-base
rebuild stays the one sanctioned cherry-pick, with -x, and the text says
why no merge can do it. Merge PRs with a merge commit, never squash or
rebase. Also bounds test loops that walk a state machine until a step.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
Edward Langley
2026-09-24 18:50:43 -07:00
parent bb01cd1957
commit ac2efdc8a4
4 changed files with 63 additions and 14 deletions
+22 -6
View File
@@ -6,7 +6,9 @@
from logic
- @context/repo-map.md is your "road map" for the repository. use it to reduce exploration and keep it updated.
- @context/design-principles.md is also important for keeping the repository consistent.
- prefer merges to rebasing.
- reconcile diverging history only by merge. Never rebase or squash, never `reset` away commits, and never
amend or force-push a pushed commit: the merge structure of git history is a causal record (the user,
2026-09-25). The rule and its incidents are `.agents/skills/wave/agent-rules.md`, rule 8.
- always start responses with bananaS!
- there is a prolog MCP available: load a session from `kb` at the root of the repository at the beginning of
every session, and query it as you work. **Reading only** — the MCP must never write `kb.pl`.
@@ -147,6 +149,13 @@ once prescribed exactly that command (see "Repository policy over the Beads bloc
It cost a review round on PR #145,
where four unmerged commits — including another PR's whole diff — were pulled
into a branch based on `gh/main` and had to be rebuilt by cherry-picking.
That rebuild is the **one sanctioned cherry-pick**, and it is sanctioned because
no merge can do it. A merge only adds ancestry, so no merge yields a branch
without the other PR's commits. Reverting them in the branch is worse, because
merging the branch would then land an undo of that PR. So: cut a fresh branch
from the pinned `gh/main` SHA, `git cherry-pick -x` only your own commits
(`-x` keeps the link to each original), open a new PR, and close the old one
without force-pushing it.
ChatGPT Codex caught it; nothing in CI could, because the result compiles and
passes. The tell is a PR diff naming files the ticket has no reason to touch,
so **read your own PR's file list before asking for review** — and diff against `gh/main...<branch>`, never the local equivalent. **The second vector is the worktree base**: a branch cut from the orchestrator's *local* `main` inherits whatever that checkout has merged but not yet pushed, and nothing in the branch says so. That hit PR #148 with another PR's whole diff — including `.beads/`, `kb.pl` and `context/repo-map.md`, the three files agents are forbidden to touch, so the review read as a rule violation rather than a base problem. Note the window
@@ -262,8 +271,13 @@ will never see, CI runs on it, and the commit is nowhere. The tell is the push
printing `* [new branch]` where you expected an `old..new` range. It happened on
#51: the third review round completed four minutes after the merge, and the
correction it prompted went to a re-created `wave/b-projection-gaps`. The repair
is to branch from `gh/main`, cherry-pick, open a follow-up PR, and delete the
stray re-creation. Check `gh pr view <n> --json state` *before* pushing a fix to
is a merge, not a cherry-pick. The PR merged with a merge commit, so the stray
branch's base is already an ancestor of `main`. Branch from the pinned
`gh/main` SHA, `git merge` the stray branch's SHA, open a follow-up PR, and
delete the stray re-creation. The merge brings exactly the fix commits, under
their own SHAs, with the link to the PR they answered. A cherry-pick would copy
them and drop that link. This recipe works only because PRs here never
squash-merge. Check `gh pr view <n> --json state` *before* pushing a fix to
a PR you have not looked at in a few minutes, rather than after.
**A stacked PR whose base PR has already merged merges into that stale base
@@ -289,9 +303,11 @@ commits if the base did not land.
Merge only once a review of the PR's current head has passed — an adversarial
agent's — and every Codex and Copilot finding on the PR has an answer. What a
review must state is agent-rules, "GitHub". Prefer a **merge commit** —
`AGENTS.md` says merges over rebases, and a PR's commits are individually
meaningful.
review must state is agent-rules, "GitHub". Merge with a **merge commit**. Never
use GitHub's squash or rebase merge: history is reconciled only by merge (the
rule at the top of this file). A PR's commits are individually meaningful, and
the fix-after-merge recipe above needs the PR's head to be an ancestor of
`main`.
### Merging many PRs at once