What
The Smart CI planner resolves a pull request's control base to main's tip rather than to the PR's actual base branch, so any PR stacked on another PR's branch fails the gate with a planner-error that is not a defect in the PR under test.
Live instance: PR #2531 (base issue-1898/port-release-deadline, i.e. open PR #2522), run 33843172977, job 100929506193.
❌ planner-error — Error: pull-request planning requires merge SHA and tree SHA from the same fetched merge ref
❌ trust-mismatch — plan says T3, the event re-derives T1
Root cause
.github/workflows/smart-ci-shadow.yml:53 sets CONTROL_BASE: ${{ github.sha }}. The job env for that run shows:
CONTROL_BASE: ca6fe42fe2f2228241d9480d1d9d36087fe1b27e
which is main's tip at 06:07:19Z, not #2531's base issue-1898/port-release-deadline @ d8d53002. Verified:
git merge-base --is-ancestor ca6fe42f d8d53002 -> NO
git merge-base --is-ancestor ca6fe42f origin/main -> YES
The merge ref is built against the real base, so it can never reconcile with an expectedBase taken from the default branch. This is not staleness from a retarget: #2531 was created directly against the stacked base at 06:08:46Z with no base_ref_changed event.
trust-mismatch (plan says T3, the event re-derives T1) is a second, separate defect in the same run, not a consequence of the first.
Why #2506 does not close this
#2506 ("accept a merge ref regenerated against the live protected base tip") targets the same error string — git grep 'requires merge SHA and tree SHA' finds it only at scripts/ci/smart-ci/plan.mjs:59 — and adds a --base-ref "$BASE_REF" path driven by github.event.pull_request.base.ref. For #2531 that would resolve the right SHA and plausibly clear the planner-error. But:
- The stacked case is entirely untested.
gh pr diff 2506 | grep "baseRef: '" returns exactly three hits, all 'main' or ''.
- The receipt would tell a false story. It would read "the base advanced from ca6fe42 to d8d5300" — the base did not advance; it is a different branch. A receipt is evidence, so a wrong narrative in it is its own problem.
- It does nothing about
trust-mismatch.
So #2506 should not be described as fixing #2531's red.
Suggested work
- Resolve the control base from
github.event.pull_request.base.sha / base.ref rather than github.sha for pull_request/pull_request_target events.
- Add a planner test whose
baseRef is a non-default branch.
- Distinguish "base branch is not the default branch" from "base advanced" in the receipt vocabulary.
- Triage
trust-mismatch separately.
Impact and non-impact
Advisory only today: smart-ci-shadow.yml runs in observation mode and branch protection requires only the three security contexts (Dependency Security, SAST Scan, Secret Scan), so this reddens no merge. It matters for CI-03 #2327, which registers Smart CI / Required Gate as required after ≥20 PRs without a false red — a false red on every stacked PR both corrupts that observation window and would become a hard block once registered.
All of ci-required is green on #2531; only this advisory gate is red.
Refs #2324, #2327, #2506
What
The Smart CI planner resolves a pull request's control base to
main's tip rather than to the PR's actual base branch, so any PR stacked on another PR's branch fails the gate with aplanner-errorthat is not a defect in the PR under test.Live instance: PR #2531 (base
issue-1898/port-release-deadline, i.e. open PR #2522), run 33843172977, job 100929506193.Root cause
.github/workflows/smart-ci-shadow.yml:53setsCONTROL_BASE: ${{ github.sha }}. The job env for that run shows:which is main's tip at 06:07:19Z, not #2531's base
issue-1898/port-release-deadline @ d8d53002. Verified:The merge ref is built against the real base, so it can never reconcile with an
expectedBasetaken from the default branch. This is not staleness from a retarget: #2531 was created directly against the stacked base at 06:08:46Z with nobase_ref_changedevent.trust-mismatch(plan says T3, the event re-derives T1) is a second, separate defect in the same run, not a consequence of the first.Why #2506 does not close this
#2506 ("accept a merge ref regenerated against the live protected base tip") targets the same error string —
git grep 'requires merge SHA and tree SHA'finds it only atscripts/ci/smart-ci/plan.mjs:59— and adds a--base-ref "$BASE_REF"path driven bygithub.event.pull_request.base.ref. For #2531 that would resolve the right SHA and plausibly clear the planner-error. But:gh pr diff 2506 | grep "baseRef: '"returns exactly three hits, all'main'or''.trust-mismatch.So #2506 should not be described as fixing #2531's red.
Suggested work
github.event.pull_request.base.sha/base.refrather thangithub.shaforpull_request/pull_request_targetevents.baseRefis a non-default branch.trust-mismatchseparately.Impact and non-impact
Advisory only today:
smart-ci-shadow.ymlruns in observation mode and branch protection requires only the three security contexts (Dependency Security,SAST Scan,Secret Scan), so this reddens no merge. It matters for CI-03 #2327, which registersSmart CI / Required Gateas required after ≥20 PRs without a false red — a false red on every stacked PR both corrupts that observation window and would become a hard block once registered.All of
ci-requiredis green on #2531; only this advisory gate is red.Refs #2324, #2327, #2506