claim(M2-settings): live server verified — no-canonical recipe (keycloak) -> release tag 10.7.1+26.6.2; flag true bypasses gitea canonical to release-tag path, restored false. Deployed /etc/cc-ci@99d6bbc; awaiting Adversary
Some checks failed
continuous-integration/drone/push Build is failing

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 17:04:16 +00:00
parent 99d6bbc1a1
commit a9ff941dda
3 changed files with 88 additions and 8 deletions

View File

@ -15,10 +15,10 @@
- [x] **B6 (M1 claim)** — clean tree, push, claim M1 in STATUS-settings.md.
### M2 (after M1 PASS)
- [ ] **B7** — deploy to cc-ci (`/etc/cc-ci` git pull + nixos-rebuild if needed); confirm harness reads
- [x] **B7** — deploy to cc-ci (`/etc/cc-ci` git pull + nixos-rebuild if needed); confirm harness reads
settings (absent → default false; or file present false).
- [ ] **B8** — live evidence (a): a recipe WITHOUT a canonical resolves base to newest release tag `< head`
- [x] **B8** — live evidence (a): a recipe WITHOUT a canonical resolves base to newest release tag `< head`
(not raw main-tip).
- [ ] **B9** — live evidence (b): flip `SKIP_CANONICALS_FOR_UPGRADE = true` (scratch) → a canonical-bearing
- [x] **B9** — live evidence (b): flip `SKIP_CANONICALS_FOR_UPGRADE = true` (scratch) → a canonical-bearing
recipe ALSO resolves to the release-tag base (canonical bypassed); then restore false.
- [ ] **B10 (M2 claim)** — claim M2; on fresh PASS of M1+M2 → `## DONE`.
- [x] **B10 (M2 claim)** — claim M2; on fresh PASS of M1+M2 → `## DONE`.

View File

@ -82,3 +82,23 @@ M2 plan (after M1 PASS):
- Deploy: ensure `/etc/cc-ci` is at the phase commit (git pull); settings.py is pure-python loaded at
runtime from the checkout, so no nixos-rebuild needed for the harness to pick it up (the `cc-ci-run`
wrapper execs python on the checkout's runner/). Confirm on server.
## 2026-06-17 — M1 PASS + M2 verified live, claimed
M1 Adversary cold-PASS (REVIEW-settings.md @17:00Z, no VETO). Advanced to M2.
Deployed phase commit to `/etc/cc-ci` via `git pull --ff-only` (HEAD 99d6bbc); no nixos-rebuild needed
(pure runner python read at runtime; the nightly sweep runs from /etc/cc-ci and Drone reads the same
absolute settings path). Added `scripts/show-upgrade-base.py` — a faithful, lightweight live probe that
calls the DEPLOYED `resolve_upgrade_base` against live settings + canonical registry + recipe tags,
avoiding a heavy per-recipe deploy/test/teardown while still proving the real resolution decision on the
server. Chose this over full `cc-ci-run runner/run_recipe_ci.py` runs (samever's approach) because my
change is purely in base RESOLUTION, not tier execution — the BasePlan is the whole claim.
Evidence-(b) recipe choice: scanned all 16 canonical recipes; only `gitea` has canonical≠head
(3.5.3 vs 3.6.0), making it the cleanest bypass demo — flag false reads the canonical
("last-green (warm canonical, status=idle)"), flag true bypasses to the release-tag path
("no-canonical fallback: newest release tag older than head 3.6.0..."). The resolved version is 3.5.3
both ways (the canonical happens to equal the newest predecessor tag), so the REASON string is the proof
of bypass — honest and matches the plan wording "ALSO resolve to that release-tag base (canonical
bypassed)". All other recipes are in steady state (canon==head) where step-back and the fallback share
the same helper and so coincide. Server restored to steady state (settings.toml absent → false).

View File

@ -3,10 +3,10 @@
**Phase:** server-level `settings.toml` + `SKIP_CANONICALS_FOR_UPGRADE` + release-tag-first no-canonical
fallback. Plan: `/srv/cc-ci/cc-ci-plan/plan-phase-settings-ci-server-config.md`.
## Gate: M1 CLAIMED, awaiting Adversary
## Gate: M1 PASS (Adversary @2026-06-17T17:00Z, REVIEW-settings.md) · M2 CLAIMED (see below)
**Commit:** `cd19c1b` (feat: settings loader + flag + fallback + unit tests). Tree clean, pushed to
origin/main.
**M1 commit:** `cd19c1b` (feat: settings loader + flag + fallback + unit tests) — Adversary cold-PASS,
no VETO. **M2 deployed:** `99d6bbc` on `/etc/cc-ci`. Tree clean, pushed to origin/main.
### WHAT is claimed (M1 — implemented + unit-tested)
1. **Settings loader** `runner/harness/settings.py` — stdlib `tomllib`, one `[upgrade]` table with
@ -73,4 +73,64 @@ nix shell nixpkgs#python311Packages.pytest -c python3 -c "import sys; sys.path.i
needing reformat — confirmed present at HEAD f68f1c5, NOT in this phase's diff. Not fixed here (narrow
scope). My 5 phase files are ruff-clean + format-clean.
## M2 — NOT yet claimed (live server verification). Pending M1 PASS.
---
## Gate: M2 CLAIMED, awaiting Adversary @2026-06-17T17:25Z
M1 is Adversary-PASS (REVIEW-settings.md verdict @17:00Z, fed2678/cd19c1b). M2 = verified live on cc-ci.
**Deployed:** `/etc/cc-ci` at **99d6bbc** (pushed to origin/main; the deployed checkout the nightly
sweep runs from, and the absolute path the Drone recipe-CI runner reads). No nixos-rebuild needed — the
change is pure runner Python loaded at runtime from the checkout. Live settings file
`/etc/cc-ci/settings.toml` is **ABSENT** → default false (server steady state restored after the test).
### WHAT is claimed (M2)
- The live server harness reads the settings file from the host path `/etc/cc-ci/settings.toml`
(absent → default false), confirmed by the flag value flipping with the file's presence.
- **(a)** A recipe **without** a canonical (`keycloak`, no `canonical.json`) resolves its upgrade base
to the **newest release tag `< head`** (`10.7.1+26.6.2`), NOT the raw main-tip.
- **(b)** With `SKIP_CANONICALS_FOR_UPGRADE = true` (scratch file), a **canonical-bearing** recipe
(`gitea`, canonical `3.5.3+1.24.2-rootless`) resolves to the **release-tag base** (canonical
BYPASSED) — proven by the reason changing from `last-green (warm canonical, status=idle)` to
`no-canonical fallback: newest release tag older than head 3.6.0+1.24.2-rootless`. Scratch file then
removed → restored to false (reason back to `last-green (warm canonical)`).
- Default false ⇒ this server's canonical-bearing path is unchanged (gitea false → `last-green` base).
### HOW to verify (cold, on the server, from /etc/cc-ci or your own clone)
The probe runs the EXACT deployed `resolve_upgrade_base` against live settings + live canonical registry
(`/var/lib/ci-warm/<r>/canonical.json`) + live recipe tags (`~/.abra/recipes/<r>`). Faithful, no
deploy/teardown.
```
ssh cc-ci
cd /etc/cc-ci && git rev-parse --short HEAD # 99d6bbc (or later)
ls /etc/cc-ci/settings.toml # ABSENT -> default false
# CASE 1 — flag false (default, no file): (a) keycloak, plus gitea unchanged
HOME=/root cc-ci-run scripts/show-upgrade-base.py keycloak gitea
# CASE 2 — flag true (scratch), then RESTORE
printf '[upgrade]\nskip_canonicals_for_upgrade = true\n' > /etc/cc-ci/settings.toml
HOME=/root cc-ci-run scripts/show-upgrade-base.py gitea keycloak
rm -f /etc/cc-ci/settings.toml # restore default false
HOME=/root cc-ci-run scripts/show-upgrade-base.py gitea
```
### EXPECTED (verbatim BasePlan lines observed @17:2017:25Z)
- CASE 1 (false):
- `keycloak``BasePlan(kind='version', version='10.7.1+26.6.2', ref='', reason='no-canonical fallback: newest release tag older than head 10.8.0+26.6.3')` (canonical=None; newest_release_tag<head=10.7.1+26.6.2; NOT main-tip 12ac6db8…)
- `gitea` `BasePlan(kind='version', version='3.5.3+1.24.2-rootless', ref='', reason='last-green (warm canonical, status=idle)')` (canonical=3.5.3 present used)
- CASE 2 (true):
- `gitea` `BasePlan(kind='version', version='3.5.3+1.24.2-rootless', ref='', reason='no-canonical fallback: newest release tag older than head 3.6.0+1.24.2-rootless')` (canonical 3.5.3 present but BYPASSED reason is the release-tag path)
- `keycloak` same as CASE 1 (no canonical either way)
- RESTORE (file removed false):
- `gitea` reason back to `last-green (warm canonical, status=idle)`; flag reads `False`.
### WHERE
- Deployed code: `/etc/cc-ci` @ 99d6bbc (origin/main). Probe: `scripts/show-upgrade-base.py`.
- Live registry: `/var/lib/ci-warm/{keycloak (none),gitea}/canonical.json`. Recipe tags:
`~/.abra/recipes/{keycloak,gitea}`. Settings path: `/etc/cc-ci/settings.toml` (absent now).
Server left in steady state: `/etc/cc-ci/settings.toml` ABSENT (default false), checkout clean @99d6bbc.
On a fresh Adversary PASS of M2 (with M1 PASS standing), I will write `## DONE`.