chore(prevb): bootstrap phase state + settled dynamic-base/previous decisions
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
31
machine-docs/BACKLOG-prevb.md
Normal file
31
machine-docs/BACKLOG-prevb.md
Normal file
@ -0,0 +1,31 @@
|
||||
# BACKLOG — phase `prevb`
|
||||
|
||||
SSOT: `/srv/cc-ci/cc-ci-plan/plan-phase-prevb-previous-dynamic-base.md`.
|
||||
|
||||
## Build backlog
|
||||
|
||||
### M1 — implemented + green locally
|
||||
- [ ] B1. Dynamic upgrade-base resolution: last-green (warm canonical registry version) → fallback
|
||||
target-branch (`main`) tip → else skip (declared reason). Replace the static
|
||||
`previous_version(vers[-2])` default in `run_recipe_ci.upgrade_base`. Wire into `main()` deploy.
|
||||
- [ ] B2. `tests/<recipe>/previous/` mechanism: discovery, declared-target-version marker, base-only
|
||||
application (added to base deploy's COMPOSE_FILE), head exclusion (never applied to PR head),
|
||||
version-guard + stale-flag on mismatch.
|
||||
- [ ] B3. Discourse migration: shrink `compose.ccci.yml` to environmental-only
|
||||
(`order: stop-first`), delete bitnamilegacy image pins + sidekiq block; remove
|
||||
`UPGRADE_BASE_VERSION` from `tests/discourse/recipe_meta.py`. (Expect NO `previous/`.)
|
||||
- [ ] B4. Unit tests for the new surface: base resolution (last-green / main-tip / skip), `previous/`
|
||||
match / skip / stale, environmental-vs-version overlay layering. Update `test_upgrade_base.py`
|
||||
to the new resolver API without weakening coverage.
|
||||
- [ ] B5. Discourse upgrade tier GREEN locally: base (bitnamilegacy:3.5.0) → head; assert deployed
|
||||
`app` image == `discourse/discourse:3.5.3` (NOT bitnamilegacy) and no `sidekiq` service post-deploy.
|
||||
- [ ] B6. CLAIM M1 (clean tree + STATUS verification block).
|
||||
|
||||
### M2 — proven in real CI + spot-check
|
||||
- [ ] B7. discourse PR #4 `!testme` GREEN in real CI; head ran `discourse/discourse:3.5.3`, migration exercised.
|
||||
- [ ] B8. Spot-check ≥3 other upgrade-tier recipes (warm-canonical / published-predecessor / ex-`.ccci`
|
||||
e.g. keycloak/cryptpad/ghost) still green under dynamic base. Reconcile levels/records.
|
||||
- [ ] B9. CLAIM M2 → `## DONE` after fresh Adversary PASS on M1+M2.
|
||||
|
||||
## Adversary findings
|
||||
(Adversary-owned section — Builder does not edit below.)
|
||||
@ -1441,3 +1441,24 @@ but stays well within the ≤90 s budget. Acceptable.
|
||||
(same model as keycloak realm marker). Idempotent creation (409 = already exists → OK).
|
||||
`pre_restore` deletes it to create a genuine divergence from backup state; `test_restore` asserts
|
||||
its return. The sqlite3 DB is the persistence layer being tested.
|
||||
|
||||
- **Dynamic upgrade base — SETTLED (2026-06-17, phase prevb).** The upgrade tier's BASE version is
|
||||
resolved at run time, replacing the static `previous_version(vers[-2])` default. Resolution order:
|
||||
(1) **last-green** = the warm-canonical registry record (`canonical.read_registry(recipe).version`,
|
||||
status warm/idle) when present; (2) fallback **target-branch (`main`) tip** = the recipe repo's
|
||||
`main` HEAD (a git ref, chaos-deployed) — the true predecessor the PR merges onto; (3) **else skip**
|
||||
the upgrade tier with a declared reason (new recipe / no predecessor / head==main). EXPECTED_NA[upgrade]
|
||||
and `upgrade∉stages` still short-circuit to skip first. `UPGRADE_BASE_VERSION` is RETAINED as an
|
||||
optional explicit override (wins when set) for the rare PR-adds-version-above-newest-tag case, but is
|
||||
no longer the default and is removed from discourse. This intentionally changes every recipe's default
|
||||
base from `vers[-2]` to last-green/main-tip (plan-mandated; M2 spot-check validates non-regression).
|
||||
|
||||
- **Per-recipe `previous/` overlay — SETTLED (2026-06-17, phase prevb).** `tests/<recipe>/previous/`
|
||||
optionally holds the minimal config to deploy the *previous (last-green) version* when it can't deploy
|
||||
as-published (e.g. `compose.previous.yml` for an image relocation). It declares the version it targets
|
||||
(a `previous/VERSION` marker line) and the harness applies it **only to the base deploy and only when
|
||||
the resolved base is that exact published version**; it is NEVER applied to the PR head, and on a
|
||||
main-tip base or version mismatch it is SKIPPED and flagged stale ("previous/ targets X, base is Y —
|
||||
remove it"). The all-deploys `compose.ccci.yml` overlay is now ENVIRONMENTAL-only (node-reality tweaks,
|
||||
no version-specific image pins or service add/drop); version-specific repairs live in `previous/`.
|
||||
Discourse ships NO `previous/` (base bitnamilegacy:3.5.0 deploys clean).
|
||||
|
||||
37
machine-docs/JOURNAL-prevb.md
Normal file
37
machine-docs/JOURNAL-prevb.md
Normal file
@ -0,0 +1,37 @@
|
||||
# JOURNAL — phase `prevb` (Builder reasoning; append-only)
|
||||
|
||||
## 2026-06-17 — Bootstrap + recon
|
||||
|
||||
Read SSOT (plan-phase-prevb), plan.md §6.1/§7/§9, Adversary's REVIEW-prevb (live, idle awaiting M1 claim).
|
||||
|
||||
**Mapped the harness upgrade flow** (`runner/run_recipe_ci.py`, `harness/lifecycle.py`,
|
||||
`harness/generic.py`, `harness/meta.py`, `harness/canonical.py`):
|
||||
- Base decision: `upgrade_base(stages, meta, recipe)` → `None` if upgrade∉stages or EXPECTED_NA[upgrade],
|
||||
else `meta.UPGRADE_BASE_VERSION or lifecycle.previous_version(recipe)` (= `recipe_versions[-2]`).
|
||||
`base = prev or target`; `prev` also gates whether the upgrade tier runs.
|
||||
- Deploy: `deploy_app(version=base)` → pinned `recipe_checkout(version)` + (auto-chaos if overlay/lightweight tag);
|
||||
`version=None` → chaos deploy of the current (head) checkout.
|
||||
- Overlay `compose.ccci.yml`: copied into the checkout (`provide_ccci_overlay`), referenced by
|
||||
`EXTRA_ENV.COMPOSE_FILE`, persists untracked across the head re-checkout → applies to ALL deploys.
|
||||
- Upgrade op (`generic.perform_upgrade`): `recipe_checkout_ref(head_ref)` then chaos redeploy; the
|
||||
ccci overlay persists → leaks version-specific pins onto the head. **That is the bug.**
|
||||
- Last-green source: `canonical.read_registry(recipe)` → `{version, commit, status}` (promoted only on
|
||||
GREEN LATEST cold runs for `WARM_CANONICAL` recipes). No separate "last-green" file.
|
||||
|
||||
**Ground-truth discourse facts** (gitea API, verified — see STATUS for the table). Key correction vs
|
||||
plan §3 prose: main is `bitnamilegacy/discourse:3.5.0` (not 3.3.1 — main advanced). Thesis holds: base
|
||||
(last-green/main = bitnamilegacy 3.5.0, deployable) → head (PR #4 = official discourse/discourse:3.5.3,
|
||||
sidekiq dropped). So discourse needs NO `previous/`; the env overlay shrinks to `order: stop-first`.
|
||||
|
||||
**Design decisions (WHY):**
|
||||
- *Resolution order* last-green → main-tip → skip. main-tip = the recipe's `main` branch HEAD = the true
|
||||
predecessor the PR merges onto (more faithful than the old `vers[-2]`, which could span 2 version jumps).
|
||||
This intentionally changes EVERY recipe's default base from `vers[-2]` to main-tip — plan-mandated, not a
|
||||
regression; M2 spot-check validates representative recipes still go green.
|
||||
- *Keep `UPGRADE_BASE_VERSION` as an optional explicit override* (still wins when set), but remove it from
|
||||
discourse and make the DEFAULT dynamic. Rationale: fully deleting the meta field would break `plausible`
|
||||
(its meta sets it) and the documented "PR adds a version above newest tag" escape hatch, without a deploy
|
||||
test — risk vs guardrail "don't regress other recipes". The plan's "UPGRADE_BASE_VERSION removed" is in the
|
||||
discourse-migration context; the normal/discourse path is now hardcode-free. Recorded in DECISIONS.
|
||||
- *`previous/` scoped to last-green (published-version) base only* — version-guarded by a declared target;
|
||||
on a main-tip base or version mismatch it is skipped + flagged stale. Discourse ships none (base deploys clean).
|
||||
27
machine-docs/STATUS-prevb.md
Normal file
27
machine-docs/STATUS-prevb.md
Normal file
@ -0,0 +1,27 @@
|
||||
# STATUS — phase `prevb` (dynamic upgrade base + per-recipe `previous/`)
|
||||
|
||||
SSOT: `/srv/cc-ci/cc-ci-plan/plan-phase-prevb-previous-dynamic-base.md`.
|
||||
State files: this + BACKLOG-prevb.md, REVIEW-prevb.md (Adversary), JOURNAL-prevb.md. DECISIONS.md shared.
|
||||
|
||||
## Phase
|
||||
Started 2026-06-17. Gates: **M1** (implemented + green locally), **M2** (proven in real CI + spot-check).
|
||||
|
||||
## Now
|
||||
- In flight: M1 implementation (dynamic base resolution + `previous/` mechanism + discourse migration + unit tests).
|
||||
- No gate CLAIMED yet.
|
||||
|
||||
## Ground-truth facts (verified 2026-06-17, recorded for Adversary)
|
||||
- `recipe-maintainers/discourse` PR **#4** (`discourse-official-image` `ae5a8180` → `main` `f87c612d`), open.
|
||||
- **main** (`compose.yml`): `app`/`sidekiq` image = `bitnamilegacy/discourse:3.5.0`; `app` healthcheck
|
||||
`start_period: 20m`; `app.deploy.update_config.order: start-first`; `sidekiq` service present.
|
||||
- **PR #4 head**: `app.image = discourse/discourse:3.5.3` (official), **`sidekiq` service deleted**,
|
||||
loadbalancer port 3000→80, official-image entrypoint wrappers added. (PR `.diff` confirms both.)
|
||||
- Published tags max = `0.7.0+3.3.1`; main (3.5.0) is AHEAD of all tags → main-tip is a branch ref, not a tag.
|
||||
- Current `tests/discourse/compose.ccci.yml` re-pins `app`+`sidekiq` to `bitnamilegacy/discourse:3.3.1`,
|
||||
re-adds `sidekiq`, sets `start_period:20m`, `order:stop-first` — applied to ALL deploys via
|
||||
`EXTRA_ENV.COMPOSE_FILE` → forces the PR head back to bitnamilegacy:3.3.1 + sidekiq (the bug).
|
||||
- Note vs plan §3 prose: main is `bitnamilegacy:3.5.0`, not `3.3.1` (main advanced); thesis unchanged —
|
||||
the base (last-green/main, bitnamilegacy 3.5.0) deploys clean, NO `previous/` needed for discourse.
|
||||
|
||||
## Blocked
|
||||
(none)
|
||||
Reference in New Issue
Block a user