fix(land): a speculative lap is judged against the base it borrowed - #1027
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Warning Review limit reachedNext included review available in 52 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: button-inc/batten/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: button-inc/batten/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 Walkthrough📝 WalkthroughPriority: ➖ Normal Merge Risk: ⚪ Minimal · up to No actionable merge-blocking issue is established; the change is mergeable after normal checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change corrects how speculative landings are judged, while ordinary runs retain their existing base. A caller that controls the verification environment can now influence the two local gate comparisons, although the inspected landing path controls that value and CI runs independent checks. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Hardening Proposals
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
fc3ed30 to
28b9d37
Compare
`verify:gated` arms two gates with a base ref, and both named `origin/main`
unconditionally on a premise the body states in its own comment: `verify` has
already refused this branch unless it is rebased on current `origin/main`, so the
task is a function of (commit, current trunk).
That premise is false on a speculative lap. `land` replays the branch onto the
lease holder's UNLANDED commits — "the main that is about to exist" — so the tree
is a function of (commit, the holder's base), and judging it against trunk
charges the holder's diff to the BORROWER.
It refuses rather than merely misreporting, which is what made it expensive.
`lint::groom` keys the claim receipt on the branch name, and a borrower carries
one of its own, minted for its own row and naming no weakening: `Groom::Read({})`
is "the groom looked and admitted nothing", a refusal by design (CLOUD-841,
evidence of absence rather than absence of evidence). The holder's `Weakens:`
trailer cannot admit it, because the borrower's groom already answered.
MEASURED 2026-09-25/26, five laps over four different borrowed tips
(`5fa3732a`, `2e6b457e`, `c3315ac6`, `3617f103`), every one refusing
`recorder[board-issue-created] recorder-changed` and its sibling — while
`mise run test:cargo` over the identical integrated commit was 6057/6057 green.
Directly: `BATTEN_CONFIG_FROM=origin/main` gives 2 smells on that tree and
`BATTEN_CONFIG_FROM=3617f103`, the borrowed base, gives 0.
`commit-lint` had the same hole and its instance is already in this repository's
cost record: CLOUD-1775's body tabulates a lap lost to "28 commits claim no
CLOUD-<n> issue". Those 28 were the holder's.
`BATTEN_SPEC_BASE` is what `land` already publishes for exactly this question
(`speculation::PUBLISHED_AS`, CLOUD-748), with `land.rs`'s own
`a_body_gate_is_told_which_base_the_lap_borrowed` asserting it arrives. Reading
it here is the bound CLOUD-1711 put on `race::authored_log`, applied to the two
gates that still lacked it.
NOTHING ESCAPES JUDGEMENT, which is what makes this a fix rather than a
relaxation: every commit is still judged once, on its own branch, against the
base it actually sits on. The holder's weakenings are adjudicated on the holder's
own lap, against trunk, under the holder's groom.
The pair of cases is the pair for a reason. Without the mirror, "read
`BATTEN_SPEC_BASE`" is satisfied by dropping the base entirely — the dead-gate
class — and a bare `$BATTEN_SPEC_BASE` would arm `config lint` with an empty ref
off a bet and judge nothing at all, which is the silence house style §8 arms this
gate against. Both were shown to fail: restoring either literal reddens both.
Refs: CLOUD-1702
28b9d37 to
a78419b
Compare
|
/fast-forward |
Closes CLOUD-1702
This is the defect currently blocking every branch behind the landing lease, including #1025 and #1026.
The premise that speculation breaks
verify:gatedarms two gates with a base ref, and both namedorigin/mainunconditionally — on a premise the body states in its own comment:That is true of an ordinary lap and false on a speculative one:
landreplays the branch onto the lease holder's unlanded commits — "the main that is about to exist" — so the tree is a function of (commit, the holder's base). Judging it against trunk charges the holder's diff to the borrower.Why it refuses rather than just misreporting
lint::groomkeys the claim receipt on the branch name. A borrower carries one of its own, minted for its own row and naming no weakening —Groom::Read({}), which is "the groom looked and admitted nothing" and refuses by design (CLOUD-841: evidence of absence, not absence of evidence). The holder'sWeakens:trailer cannot admit it, because the borrower's groom has already answered.commit-linthad the same hole, and its instance is already in this repository's cost record: CLOUD-1775's body tabulates a lap lost tocommit-lint— 28 commits "claim no CLOUD-N issue". Those 28 were the holder's.Measured, not assumed
override spendis not a CI bypass, and the whole allowlist is inherited #1026 borrowed four different tips (5fa3732a,2e6b457e,c3315ac6,3617f103); every one refusedrecorder[board-issue-created] recorder-changedand its sibling.mise run test:cargoover the identical integrated commitlandrefused (0c3f3324) is 6057/6057 green. Both tests also pass on the borrowed tip alone, and on a branch with no claim receipt the same tree admits both weakenings astrailer-alone.BATTEN_CONFIG_FROM=origin/main→ 2 smells on that tree;BATTEN_CONFIG_FROM=3617f103(the borrowed base) → 0 smells.The change
Both armings become
${BATTEN_SPEC_BASE:-origin/main}. That variable is whatlandalready publishes for exactly this question (speculation::PUBLISHED_AS, CLOUD-748), withland.rs's owna_body_gate_is_told_which_base_the_lap_borrowedasserting it arrives. It is the bound CLOUD-1711 put onrace::authored_log, applied to the two gates that still lacked it, and a no-op wherever no bet is live — an ordinary local lap and CI both leave it unset.Nothing escapes judgement, which is what makes this a fix rather than a relaxation: every commit is still judged once, on its own branch, against the base it actually sits on. The holder's weakenings are adjudicated on the holder's own lap, against trunk, under the holder's groom.
Tests
Two cases in
crates/batten/tests/it/verify_unprovisioned.rs, which already owns the reader for this task body:BATTEN_SPEC_BASE" is satisfied by dropping the base entirely (the dead-gate class), and a bare$BATTEN_SPEC_BASEwould armconfig lintwith an empty ref off a bet and judge nothing at all.Shown able to fail: restoring either literal reddens both; with the fix, 17/17 in the suite pass. The first draft of these cases failed for the wrong reason — a bare
findfor the variable name matched the prose above the arming — so the helper requires the gate invocation on the same line, which is the traptask_body's own comment records one layer up.Generated by Claude Code