Refuse to start against a base branch that has fallen behind - #183
Merged
Conversation
A stale base is the one wrong setting every later stage reports as a success. The agent works, the checks pass, the reviewer approves, the commit lands — onto a lineage nobody develops on any more. There is no failure to notice, so nothing noticed, and the cost is not one item but every item in the run. Measured on rdpapp: work was based on a branch cut from a local working tree that turned out to be 121 commits behind the authoritative remote and 27 ahead, carrying an alternate implementation never promoted into the released lineage. Six items were delivered onto it before a human who knew the lineage said so. All six are discarded. `preflight` fetches once and compares. Behind by a little is reported and allowed, because every branch is a few commits behind and blocking on that would make the check noise nobody reads. Behind by more than `STALE_BASE_LIMIT` is refused, with `--allow-stale-base` to override, mirroring `--allow-dirty`. Two things this gets right only because a test caught them getting it wrong: **A branch that tracks nothing is still measured.** The first version returned "no single obvious line of work to compare against" when a base had no upstream and the repository had several remotes — which is the rdpapp shape exactly, so it passed the case it was written for. It now compares against every remote's default head, because "which remote is authoritative" is not a question a preflight check can answer and not one it should guess at. **An unrelated remote cannot vouch for a stale base.** Measuring against every remote then let a two-commit unrelated repository, sitting in the same checkout as a second remote, mark a base thirty behind the real one as current. Only remotes sharing history with the base count as candidate lineages. Unreachable remotes, absent upstreams and repositories with no remote at all are reported and pass. None of them are evidence that a base is stale, and reporting them as failures trains people to pass the override by default. Runs in **both** modes, unlike the dirty-tree check: session mode gives each item a pristine worktree, and a pristine worktree of the wrong lineage is still the wrong lineage. Closes #180. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #180.
A stale base is the one wrong setting every later stage reports as a success — agent works, checks pass, reviewer approves, commit lands, onto a lineage nobody develops on. Measured on rdpapp: 121 commits behind the authoritative remote, six items delivered onto it, all discarded.
Verified against the real repository:
Two flaws caught by tests before commit:
Runs in both modes: a pristine worktree of the wrong lineage is still the wrong lineage.
Five tests. All four gates green locally.
🤖 Generated with Claude Code