@@ -1509,8 +1509,17 @@ function resolveSurfaceBase(): SurfaceBaseResolution | null {
15091509 const git = gitInPackage ;
15101510 const committed = readCommittedSurfaceBase ( ) ;
15111511
1512- // CI's typecheck job checks out shallow with no branch refs, so fetch the
1513- // one ref this check needs (depth 1 — a single snapshot) before giving up.
1512+ // A checkout with no branch refs (any `fetch-depth: 1` job) cannot name
1513+ // origin/main at all, so fetch the one ref this check needs before giving up.
1514+ //
1515+ // This fetch is GUARDED by the probe above and that is load-bearing (#6359):
1516+ // where the ref already resolves — every full clone, and every CI job that
1517+ // checks out `fetch-depth: 0` — it does not run, so it cannot undo the depth
1518+ // its job asked for. Where it does run, it is `--depth=1` because the only
1519+ // thing it is trying to buy is the ability to NAME origin/main; deepening it
1520+ // here would silently make every shallow build pay for a full history it was
1521+ // configured not to want. The job that needs walkable ancestry declares that
1522+ // in its checkout step, which is where the cost is visible.
15141523 let tipProbe = git ( 'rev-parse' , '--verify' , '--quiet' , 'origin/main^{commit}' ) ;
15151524 if ( tipProbe . status !== 0 ) {
15161525 git ( 'fetch' , '--quiet' , '--depth=1' , 'origin' , '+refs/heads/main:refs/remotes/origin/main' ) ;
@@ -1526,7 +1535,29 @@ function resolveSurfaceBase(): SurfaceBaseResolution | null {
15261535 const mergeBase = git ( 'merge-base' , 'HEAD' , tip ) ;
15271536 const rev = mergeBase . status === 0 ? mergeBase . stdout . trim ( ) : tip ;
15281537 if ( mergeBase . status !== 0 ) {
1529- console . log ( ` (shallow history — using origin/main tip ${ tip . slice ( 0 , 12 ) } as the baseline anchor)` ) ;
1538+ // That "…is the merge base anyway" holds only while the merge ref is
1539+ // fresh. It is generated when the PR opens or updates and goes STALE as
1540+ // main advances, so on a branch that forked earlier the tip anchor
1541+ // carries keys the fork point never had — and this gate reads every one
1542+ // of them as a line THIS commit deleted. The direction is worth spelling
1543+ // out because the verdict it produces ("deleted without proof") reads
1544+ // like a severe spec violation and costs far more to diagnose than to
1545+ // fix: #6359 was one CI job missing `fetch-depth: 0`, and the PR it
1546+ // reddened (#6356) had not touched packages/spec at all.
1547+ //
1548+ // Diagnostic only — the verdict below is unchanged. Making this route
1549+ // stop MISJUDGING rather than merely announcing itself is a separate
1550+ // decision with a much wider blast radius: this block is top-level, so
1551+ // every `gen:schema` runs it, which means every shallow job that builds
1552+ // @objectstack /spec (ci.yml `build-core`, docker-publish, release, …)
1553+ // takes this path whenever that build is a cache miss. Tracked in #6452.
1554+ console . log (
1555+ ` (shallow history — no merge base is walkable here, so this run anchors on the\n` +
1556+ ` origin/main TIP ${ tip . slice ( 0 , 12 ) } instead. ⚠️ Under a tip anchor a key that main ADDED\n` +
1557+ ` after this branch forked is indistinguishable from a key this branch DELETED. If a\n` +
1558+ ` deletion is reported below for a file you did not touch, check that first — and if\n` +
1559+ ` this is CI, the job's checkout step needs \`fetch-depth: 0\` (#6359).)` ,
1560+ ) ;
15301561 }
15311562 const baseline = readSurfaceKeysAtRev (
15321563 git ,
0 commit comments