Summary
The staged-promotion pipeline already builds and promotes candidate → stable
internally, but "release channels" are not yet a documented, user-consumable
feature. Ship channels as a first-class capability in 0.6.0: stable +
candidate fully operational for external consumers, documented, and
discoverable.
This was split out of the v0.5.0 announcement review: the bullet claiming "users
can publish and test candidates independently before promoting to stable" was
dropped from the 0.5.0 announcement because that user-facing story is not yet
true (see Gap analysis).
Current state (what already works as of v0.5.0)
- RC images are published.
.github/workflows/rc-publish.yml builds each
candidate as ghcr.io/knaisoma/data-olympus:X.Y.Z-rc.N plus a moving :rc
channel tag, and cuts a GitHub pre-release. Image-only: RCs are never
pushed to PyPI and never move :latest. (Tag 0.5.0-rc.2 exists.)
- Byte-identical promotion.
.github/workflows/tag-release.yml re-tags the
verified RC digest to vX.Y.Z + :latest (tag-release.yml:123), so what
ships as stable is exactly the image that was verified as a candidate.
- Channel moves without rebuild.
.github/workflows/set-channel.yml
re-points a moving channel tag (e.g. :kndev) at an existing digest; drives
RC canary / promotion / rollback on kn-dev via Keel.
- PyPI is stable-only.
publish-pypi.yml uploads only on v* release tags;
RCs never reach PyPI.
- Smoke test exists.
data-olympus verify runs liveness / readiness /
search round-trip / enforcement against a live target and returns distinct
exit codes for unreachable vs check-failed (added v0.4.2).
Gap analysis (why it is not user-facing yet)
- Undocumented for users. There is no "release channels" section anywhere.
docs/operations.md §3.1 mentions "a mutable channel tag" generically but
never names :rc, never explains stable vs candidate, and never shows the
deploy-candidate → verify → promote flow.
- Default trial path has no candidates.
docs/quickstart.md steers users
to uvx data-olympus / uv tool install (PyPI), but PyPI carries no RCs.
Only Docker/Kubernetes deployers can consume candidates today, and only if
they already know the :rc tag exists.
- Framing reversal to make deliberately. The v0.4.2 notes call this
pipeline "internal tooling [that] does not change how you run the server."
Promoting it to a user-facing feature is a positioning change that the 0.6.0
notes must state explicitly and supersede.
- No published channel contract. The channel tag names (
:latest, :rc,
X.Y.Z-rc.N, vX.Y.Z) are convention, not a documented, stable contract
users can pin against.
Goal for 0.6.0
Stable and candidate channels are fully operational, documented, and
consumable by external users, with a published contract for what each channel
means and how to subscribe, pin, verify, and promote.
Scope / work items
Docs
Contract / mechanics
Verification / CI
Positioning
Acceptance criteria
- A new user can, from the docs alone, deploy a candidate, run
verify, and
promote to stable without reading any CI YAML.
- The channel tag contract is written down and stable.
- The candidate consumption path (Docker and/or PyPI) is unambiguous and matches
what CI actually publishes.
- 0.6.0 release notes position channels as user-facing and retract the
"internal only" statement.
Out of scope (candidate follow-ups)
- Additional channels beyond stable/candidate (nightly / edge).
- Automated canary analysis or progressive rollout.
Context: split out of the v0.5.0 release announcement review. The "publish and
test candidates independently" bullet was dropped from the 0.5.0 announcement;
this issue tracks making the capability real for 0.6.0.
Summary
The staged-promotion pipeline already builds and promotes candidate → stable
internally, but "release channels" are not yet a documented, user-consumable
feature. Ship channels as a first-class capability in 0.6.0: stable +
candidate fully operational for external consumers, documented, and
discoverable.
This was split out of the v0.5.0 announcement review: the bullet claiming "users
can publish and test candidates independently before promoting to stable" was
dropped from the 0.5.0 announcement because that user-facing story is not yet
true (see Gap analysis).
Current state (what already works as of v0.5.0)
.github/workflows/rc-publish.ymlbuilds eachcandidate as
ghcr.io/knaisoma/data-olympus:X.Y.Z-rc.Nplus a moving:rcchannel tag, and cuts a GitHub pre-release. Image-only: RCs are never
pushed to PyPI and never move
:latest. (Tag0.5.0-rc.2exists.).github/workflows/tag-release.ymlre-tags theverified RC digest to
vX.Y.Z+:latest(tag-release.yml:123), so whatships as stable is exactly the image that was verified as a candidate.
.github/workflows/set-channel.ymlre-points a moving channel tag (e.g.
:kndev) at an existing digest; drivesRC canary / promotion / rollback on kn-dev via Keel.
publish-pypi.ymluploads only onv*release tags;RCs never reach PyPI.
data-olympus verifyruns liveness / readiness /search round-trip / enforcement against a live target and returns distinct
exit codes for unreachable vs check-failed (added v0.4.2).
Gap analysis (why it is not user-facing yet)
docs/operations.md §3.1mentions "a mutable channel tag" generically butnever names
:rc, never explains stable vs candidate, and never shows thedeploy-candidate →
verify→ promote flow.docs/quickstart.mdsteers usersto
uvx data-olympus/uv tool install(PyPI), but PyPI carries no RCs.Only Docker/Kubernetes deployers can consume candidates today, and only if
they already know the
:rctag exists.pipeline "internal tooling [that] does not change how you run the server."
Promoting it to a user-facing feature is a positioning change that the 0.6.0
notes must state explicitly and supersede.
:latest,:rc,X.Y.Z-rc.N,vX.Y.Z) are convention, not a documented, stable contractusers can pin against.
Goal for 0.6.0
Stable and candidate channels are fully operational, documented, and
consumable by external users, with a published contract for what each channel
means and how to subscribe, pin, verify, and promote.
Scope / work items
Docs
docs/operations.md: define stablevs candidate; publish the channel tag contract (
:latest= currentstable,
vX.Y.Z= immutable stable,:rc= current candidate,X.Y.Z-rc.N= immutable candidate); show the deploy-candidate →data-olympus verify→ promote-to-stable flow with copy-pasteableKubernetes snippets.
README.mdand add a short "Trying release candidates"subsection to
docs/quickstart.md.vX.Y.Z, or move a channel backto the prior digest à la
set-channel).Contract / mechanics
:rcchannel already works; decide whether PyPI PEP 440 pre-releases
(
X.Y.Zrc N, installed via--prerelease) are also in scope. If yes,extend
rc-publish.ymlto publish the pre-release to PyPI and document theuvx/uvinstall story; if no, say so explicitly in the channel docs sothe boundary is unambiguous.
:latestas the stable channel or introduce an explicit:stablealias(preferred for a governance service, to avoid
:latestambiguity).link them from the channel docs.
Verification / CI
verifyas the supported gate a user runs against a deployedcandidate before promoting, including the exit-code contract.
nox/make target) that deploys:rcto a scratch namespace and runs
verifyagainst it.Positioning
explicitly supersede the v0.4.2 "internal tooling" framing.
Acceptance criteria
verify, andpromote to stable without reading any CI YAML.
what CI actually publishes.
"internal only" statement.
Out of scope (candidate follow-ups)
Context: split out of the v0.5.0 release announcement review. The "publish and
test candidates independently" bullet was dropped from the 0.5.0 announcement;
this issue tracks making the capability real for 0.6.0.