diff --git a/cc-ci-plan/plan-phase-samever-older-base-fallback.md b/cc-ci-plan/plan-phase-samever-older-base-fallback.md index 3e60d9c..ee457e7 100644 --- a/cc-ci-plan/plan-phase-samever-older-base-fallback.md +++ b/cc-ci-plan/plan-phase-samever-older-base-fallback.md @@ -22,9 +22,16 @@ guarded **unequally**: When does the canonical equal the head version? The canonical advances **only** on a GREEN + COLD + LATEST run of a `WARM_CANONICAL`-enrolled recipe (`should_promote_canonical` = `is_enrolled and overall==0 and not quick and not ref`; a PR `!testme` carries `ref` so it NEVER promotes). So the -canonical is always the latest-published version that last passed a cold sweep. The gap therefore bites -when a PR **does not bump the version** (head version == latest published == canonical), or on a re-test -after the canonical advanced to the head's version — base and head become the same version. +canonical is always the latest-published version that last passed a cold sweep. + +**This is the STEADY STATE of the nightly sweep, not a rare edge (operator insight 2026-06-17).** The +nightly cold-on-latest run is exactly what *promotes* the canonical to LATEST. So once one green nightly +run promotes `canonical → vX`, **every subsequent nightly run — until a new version ships — finds +`canonical == latest == the version under test`**, and its upgrade tier resolves `base == head` → a +same-version no-op → effectively no upgrade test the second night. (The non-version-bump PR is the same +collision, less common.) So the step-back is the *common* nightly path, not an oddball — the resolver must +handle it as the norm. With the fix, the second nightly run tests `vX-1 → vX` (a real upgrade; a repeat of +the first night's, but real, not vacuous). ## 2. Design (A) @@ -65,12 +72,14 @@ cold-verifies from a clean checkout: a same-version PR now upgrades from a **rea version < head version, evidenced), not a no-op and not a skip; teeth (a broken head still RED); the version-bump path (canonical→head) is untouched. -**M2 — proven in real CI.** Demonstrate on a **same-version scenario**: a recipe+PR where head version == -canonical version (a non-version-bump PR, or construct it by pointing the canonical at the head's -version), and show the upgrade tier deploys an **older published base → head** with evidence -`base_version < head_version` (a genuine delta, HC1 confirms head is head). Confirm a normal version-bump -PR — re-run **discourse #4** or an equivalent — is **UNAFFECTED** (still canonical→head). Spot-check ≥1 -other enrolled recipe. Fresh Adversary PASS on both milestones → `## DONE`. +**M2 — proven in real CI.** Demonstrate on the **realistic trigger — the nightly steady state**: a +**cold-on-latest run of an enrolled recipe whose canonical already == latest** (i.e. simulate the +second consecutive nightly with no new version — seed/point the canonical at LATEST, then run +cold-on-latest). Show its upgrade tier **steps back to the previous published version** (evidence +`base_version < latest`, a genuine delta — not a same-version no-op, not a skip). Also cover the +PR form (a non-version-bump PR where head version == canonical) the same way. Confirm a normal +version-bump PR — re-run **discourse #4** or equivalent — is **UNAFFECTED** (canonical, which is older, +→ head). Spot-check ≥1 other enrolled recipe. Fresh Adversary PASS on both milestones → `## DONE`. ## 4. Guardrails