decisions(2w): W3 WC5 promote-on-green-cold mechanism (re-seed canonical from fresh green-latest deploy; never lose known-good; gate=enrolled+green+cold+latest)

This commit is contained in:
2026-05-29 04:01:59 +01:00
parent f2cfee5c32
commit cf5999cdda

View File

@ -670,3 +670,26 @@ volume(recipe)` (undeploy, volume retained = idle data-warm), `seed_canonical(re
canonical → undeploy keep volume → redeploy reattach → data survives; re-warmable from scratch).
**Automatic promote-on-green-cold (WC5) + nightly (WC6) are W3** — for W1 the canonical is seeded
programmatically to prove the model; the cold-advances-canonical wiring comes later.
## Phase 2w — W3 WC5 promote-on-green-cold mechanism (2026-05-29)
**Promote = re-seed the canonical from a fresh deploy of the green-verified latest (NOT "keep the
cold run's per-run volume").** Rationale: a cold run uses a fresh per-run domain `<recipe>-<6hex>`
with a fresh volume (cold stays authoritative + fresh); its volume names are per-run-specific and
differ from the canonical's `warm-<recipe>` volume names, so the per-run volume can't be directly
reused as the canonical without a fragile name-remap. AND the cardinal guardrail "never lose the
known-good" forbids touching the existing canonical until a new green one is ready.
So: on a run that is **enrolled (recipe_meta.WARM_CANONICAL) + GREEN + COLD (not --quick) + on LATEST
(no PR head, i.e. REF empty — the nightly/manual-latest run, NOT a PR `!testme`)**, AFTER the normal
per-run teardown, the orchestrator PROMOTES: deploy `warm-<recipe>` at latest → wait healthy →
undeploy → `canonical.seed_canonical(version=latest, commit=head)` (snapshot-while-undeployed +
atomic registry/snapshot replace). The old known-good is replaced ATOMICALLY only on a green promote
(a red run never reaches promote → known-good safe). The canonical's data = a clean install of the
green-verified latest (a valid known-good baseline; --quick reattaches + upgrades it). Cost: one extra
(canonical) deploy per promote — acceptable for cold/nightly (not latency-sensitive). The FIRST such
green run SEEDS the canonical. `--quick` never promotes (proven W2). Only cold advances (WC5).
Promote gate predicate (unit-tested): `is_enrolled(recipe) and overall==0 and not quick and not ref`.
(`not ref` = a catalogue-latest run, i.e. the nightly sweep or a manual `RECIPE=<r>` run — a PR
`!testme` carries REF=PR-head and must NOT advance the canonical to a PR's code.)