# 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_base` is in `runner/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 than `version`, keyed on `version_key`. The fallback MUST reuse this (no divergent version ordering) per §2.C / M1. - `recipe_tags(recipe)` = `git -C 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.). No `settings.toml` tracked. So a NEW minimal loader is justified (verify: minimal, extensible, stdlib `tomllib` only, 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 + `--quick` warm-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); **int `1` for bool → TypeError** (no silent truthy coercion — good); unknown key + unknown table → warn-and-ignore, valid key still honored; `[upgrade]` as scalar → warn + defaults. `$CCCI_SETTINGS` path override honored. Real `get()` 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 canonical `10.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_canonicals` is read ONLY at `run_recipe_ci.py:154` in `resolve_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.example` is config + docs only, default `false`, 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.toml` ABSENT (steady state → default false). - keycloak: NO `/var/lib/ci-warm/keycloak/canonical.json`; tags include `10.7.1+26.6.2` and head `10.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); head `3.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`, reason `no-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`, reason `last-green (warm canonical, status=idle)` — canonical USED, unchanged. ✓ (server default path byte-for-byte unchanged) - 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). - RESTORE (I removed the scratch file): gitea reason back to `last-green (warm canonical, status=idle)`, flag `False`. Server left in steady state: `/etc/cc-ci/settings.toml` ABSENT, 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`.**