Skip to content

land-stack: check a PR is not superseded before rebasing it - #455

Merged
EdbertChan merged 2 commits into
mainfrom
plan/land-stack-checks-superseded-before-rebasing
Sep 12, 2026
Merged

land-stack: check a PR is not superseded before rebasing it#455
EdbertChan merged 2 commits into
mainfrom
plan/land-stack-checks-superseded-before-rebasing

Conversation

@EdbertChan

@EdbertChan EdbertChan commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Summary

Before land-stack rebases a PR or fixes its conflicts, it now runs a check that says whether the PR's work already landed.

If it did, the PR is closed instead of rebased, so newer work is not undone.

Review Claim

land-stack step 2 runs scripts/check_branch_not_superseded.py before any rebase or conflict fix: LIVE goes on, SUPERSEDED closes the PR, UNCHECKED is fixed and rerun.

Review Lane

behavior

Review Unit

product-skill

Safety Invariant

Only the skill's instructions and their test change. The step runs a check that only reads git state, and the step numbers stay 1 to 4.

Slice Rationale

This PR reads the check added by the PR below it, so it stacks on that one.

The check sits inside step 2 instead of a new step 3. A new step would renumber the later steps, and a router test fixture under engine/ pins those numbers, which would mix two review units in one PR.

Non-goals

  • No new step number; the router fixture and tests/test_install.py are untouched.
  • The land-bottom-up and check-each-merge steps are unchanged.
  • Does not wire the check into a hook or CI.

Test Plan

Test Plan
  • python3 -m unittest discover -s product/skills/land-stack/tests: Ran 21 tests ... OK
  • python3 -m unittest discover -s engine/hooks/playbook-router/tests: Ran 29 tests ... OK
  • python3 -m unittest tests.test_install.TestSkillSymlinks.test_playbook_router_linked_and_prompt_hook_wired_for_claude: OK
  • python3 engine/skills/make-pr/scripts/preflight.py --base <the check's branch>: declare Review Unit: product-skill, ok preflight passed

Revert Plan

Revert Plan
  • Safe to revert? Yes.
  • Revert command: git revert <merge-sha>
  • Post-revert steps: None. land-stack goes back to its current step 2.
  • Data migration? No

🤖 Generated with Claude Code

https://claude.ai/code/session_01Gnua5cuAAF1ey1b7zRqJCC


Note

Low Risk
Only land-stack skill instructions and documentation tests change; the new step invokes an existing read-only git gate and does not alter merge/queue behavior.

Overview
land-stack step 2 now requires running scripts/check_branch_not_superseded.py on each PR after verify_stack.py and before any rebase or conflict resolution, still without adding a new numbered step.

The skill documents git fetch, the path via the skill symlink into catstack, and how to interpret exits: LIVE (0) continues, SUPERSEDED (3) means close the PR with a comment instead of rebasing, UNCHECKED (2+) must be fixed and rerun and must not be treated as LIVE.

A new unittest module locks that prose to the repo: gate script location, ordering between verify and land-bottom-up, EXIT_CODES parity with the gate module, close-not-rebase for superseded, and the fail-closed rule for unchecked.

Reviewed by Cursor Bugbot for commit b013159. Bugbot is set up for automated code reviews on this repo. Configure here.

EdbertChan and others added 2 commits September 11, 2026 14:05
…y landed

A branch behind its base still lists differing files, and that list does
not say which side is newer. scripts/check_branch_not_superseded.py reads
the direction and prints LIVE (exit 0), SUPERSEDED (exit 3) or UNCHECKED
(exit 2). It only reads git state.

Carved out of #375 onto current main. The exemplars move from
GATE_EXEMPLARS/gate_check to the PROMISED_CATCH/PROMISED_ALLOW/
flags_exemplar contract that main's docstring meta-gate now requires.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gnua5cuAAF1ey1b7zRqJCC
Change-Id: Id11ddf24d24facf8805295adfbe28d5687becdf5
Step 2 now runs scripts/check_branch_not_superseded.py before any rebase or
conflict fix. LIVE goes on; SUPERSEDED closes the PR instead of rebasing it
over newer work; UNCHECKED is fixed and rerun, never read as LIVE.

The check sits inside step 2 rather than as a new step 3, so the step
numbers the playbook-router fixture and tests/test_install.py pin stay put
and this slice touches only product/skills/land-stack.

Carved out of #375 and stacked on the gate it runs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gnua5cuAAF1ey1b7zRqJCC
Change-Id: I91527ae753cc84fe92c8b03088b2cc06740f5ccf
@cursor

cursor Bot commented Sep 12, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_236131cd-5e4c-47bb-a2c8-41cfa4dcdccf)

@EdbertChan
EdbertChan changed the base branch from plan/gate-a-pr-that-is-net-behind-its-base-is-superseded-not-salvageable to main September 12, 2026 06:14
@EdbertChan
EdbertChan merged commit c0fb784 into main Sep 12, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant