7.9 KiB
REVIEW — phase settings (Adversary)
SSOT: /srv/cc-ci/cc-ci-plan/plan-phase-settings-ci-server-config.md Gates: M1 (loader + flag + release-tag-first fallback, unit-tested) · M2 (verified live on server)
Status: awaiting Builder bootstrap. No STATUS-settings.md / claim yet as of 2026-06-17T16:45Z.
dash phase is DONE (M1+M2 PASS, commit 7507cf4) — this is the next phase.
Baseline captured (pre-change, for the "false = byte-for-byte unchanged" guardrail)
Cold-read of the code I'll be verifying against (no anchoring — code + plan only):
resolve_upgrade_baseis inrunner/run_recipe_ci.py:112. Current no-canonical chain:canonical(version, w/ samever step-back) → main-tip (recipe_branch_commit "main") → skip. The plan (§2.C) inserts newest release tag < head BEFORE main-tip on every no-canonical path.- The samever helper to reuse:
warm_reconcile.newest_older_version(tags, version)(runner/warm_reconcile.py:161) — newest version-tag strictly older thanversion, keyed onversion_key. The fallback MUST reuse this (no divergent version ordering) per §2.C / M1. recipe_tags(recipe)=git -C <recipe_dir> tag(warm_reconcile.py:267) — tag source.- NO existing TOML config module today: CI-server config is scattered
os.environ.get(...)(CCCI_*,ABRA_DIR,MAX_TESTS, etc.). Nosettings.tomltracked. So a NEW minimal loader is justified (verify: minimal, extensible, stdlibtomllibonly, defaults baked in, graceful on absent/malformed file/unknown key).
Verification checklist I will run when M1 is CLAIMED
- Default is
false→ this server's upgrade-base resolution byte-for-byte unchanged. - flag false + canonical present → canonical (unchanged).
- flag false + NO canonical → newest release tag < head (NOT main-tip).
- no canonical AND no older release tag → main-tip.
- none → skip.
- flag true → canonical lookup BYPASSED → same release-tag-first fallback.
- absent file / absent key → default false; malformed file → no crash, clear handling.
- fallback REUSES
samever's helper (no parallel version-ordering impl). - scope narrow: promotion +
--quickwarm-reattach UNTOUCHED by the flag. - loader cannot crash the harness on a bad/absent file.
Verdicts
M1: PASS @2026-06-17T17:00Z (claim fed2678 / code cd19c1b) — cold-verified
Verified from my own clone, fresh shell, against plan §2/§3/§5 + the code — not the Builder's narrative. Read JOURNAL only AFTER writing this verdict (contextualization only).
Tests (re-run cold):
test_upgrade_base.py+test_settings.py→ 32 passed.- Full unit suite → 315 passed (no regression).
- ruff check →
All checks passed!; ruff format →4 files already formatted.
Independent probes (I patched the I/O boundaries myself — did NOT rely on Builder's fixtures):
- Loader (real TOML files written to /tmp): absent/empty/absent-key →
False;true→True,false→False; malformed TOML → WARN +False(no crash); string value →TypeError(clear msg); int1for bool → TypeError (no silent truthy coercion — good); unknown key + unknown table → warn-and-ignore, valid key still honored;[upgrade]as scalar → warn + defaults.$CCCI_SETTINGSpath override honored. Realget()with no/etc/cc-ci/settings.toml(absent on host) →False. - Resolver matrix (my own monkeypatch of canonical/recipe_tags/main/flag):
- false + canonical(≠head) → canonical unchanged; tags & main provably NOT consulted (raised if so).
- false + no canonical → newest release tag < head (
10.7.1+26.6.2), main NOT consulted. - false + no canonical + only-head tag → main-tip. false + nothing → skip.
- true + canonical present → BYPASS → release tag
10.7.1, NOT canonical10.5.0. - true + canonical + no older tag → routes full chain → main-tip.
Guardrails checked:
- Default false / no-op for the default path: canonical-present resolution (this server's steady
state) is byte-for-byte unchanged — proven by the probe that asserts tags/main are never consulted.
NOTE: the no-canonical fallback IS intentionally changed even under false (release-tag-first), per
plan §2.C "always-on … improves this server too" and M1's mandated test
…prefers_release_tag_over_main_tip. That is the spec, not a regression — it only fires for recipes with no canonical (un-promoted), giving a real release base instead of a WIP main-tip. - Reuses samever helper: fallback calls
warm_reconcile.newest_older_version(recipe_tags(r), head)— the SAME single-source ordering helper as the step-back. No divergent version ordering. - Narrow scope:
skip_canonicalsis read ONLY atrun_recipe_ci.py:154inresolve_upgrade_base.promote_canonical/should_promote_canonical/--quick(951/965/1102) do not touch it. - Stdlib only: loader imports
os, sys, tomllib, dataclasses— no third-party. - No secrets:
settings.toml.exampleis config + docs only, defaultfalse, explicit "NO SECRETS". - Cannot crash harness: any bad/absent file degrades to defaults (WARN); only a present wrong-TYPE value raises (loud, intended).
No defects. No VETO. M1 cold-PASS. → M2 (live server) may be claimed.
M2: PASS @2026-06-17T17:35Z (claim a9ff941 / deployed /etc/cc-ci @99d6bbc) — cold live-verified
Verified live on cc-ci from a fresh ssh, against plan §3-M2 / §5. I gathered the raw facts FIRST
(predicted the outcomes), then ran the real deployed resolver myself, and controlled the scratch file
so I own the restore.
Deployment integrity: deployed /etc/cc-ci HEAD = 99d6bbc (on origin/main); git diff cd19c1b 99d6bbc -- runner/ is EMPTY — the deployed runner logic is byte-identical to the code I
cold-PASSed at M1. Only docs + scripts/show-upgrade-base.py were added. The probe is faithful: it
calls the real run_recipe_ci.resolve_upgrade_base with live registry / live tags / live head version
(read the script — no mock).
Raw facts I confirmed independently before running the probe:
/etc/cc-ci/settings.tomlABSENT (steady state → default false).- keycloak: NO
/var/lib/ci-warm/keycloak/canonical.json; tags include10.7.1+26.6.2and head10.8.0+26.6.3→ newest tag < head =10.7.1+26.6.2. - gitea: canonical
3.5.3+1.24.2-rootless(status idle); head3.6.0+1.24.2-rootless; newest tag < head =3.5.3.
Live probe (I ran it myself, all from the real /etc/cc-ci/settings.toml DEFAULT_PATH, NOT env):
- CASE 1 (file absent → false):
- keycloak (no canonical) →
version 10.7.1+26.6.2, reasonno-canonical fallback: newest release tag older than head 10.8.0+26.6.3— a real published predecessor, NOT main-tip. ✓ (a) - gitea (canonical present) →
version 3.5.3+1.24.2-rootless, reasonlast-green (warm canonical, status=idle)— canonical USED, unchanged. ✓ (server default path byte-for-byte unchanged)
- keycloak (no canonical) →
- CASE 2 (scratch file → true):
- flag reads True from /etc/cc-ci/settings.toml → gitea's canonical 3.5.3 is BYPASSED: reason
flips to
no-canonical fallback: newest release tag older than head 3.6.0+1.24.2-rootless(resolves to release tag, not the canonical lookup). The reason change is the proof of bypass. ✓ (b) - keycloak → unchanged (no canonical either way).
- flag reads True from /etc/cc-ci/settings.toml → gitea's canonical 3.5.3 is BYPASSED: reason
flips to
- RESTORE (I removed the scratch file): gitea reason back to
last-green (warm canonical, status=idle), flagFalse. Server left in steady state:/etc/cc-ci/settings.tomlABSENT, checkout clean @99d6bbc.
Harness file-pickup proven: the live flag value flipped False → True → False purely from the
presence/absence of the real host file /etc/cc-ci/settings.toml — the M2 "harness picks up the file"
requirement, demonstrated on the actual deployed path (not $CCCI_SETTINGS).
No defects. No VETO. M2 cold live-PASS. Both M1 + M2 have fresh Adversary PASSes — Builder cleared
to write ## DONE.