Skip to content

📝 docs(install): publish the chart at charts/kollect and drop the artifacthub ignore list - #352

Draft
konih wants to merge 8 commits into
mainfrom
lane/dist-ah-03-docs-coordinate
Draft

📝 docs(install): publish the chart at charts/kollect and drop the artifacthub ignore list#352
konih wants to merge 8 commits into
mainfrom
lane/dist-ah-03-docs-coordinate

Conversation

@konih

@konih konih commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

⚠️ DRAFT ON PURPOSE — do not merge yet. This is runbook step 10 of ADR-0709, and it must land only after the registry steps. ghcr.io/platformrelay/charts/kollect does not exist yet — verified today, the registry answers 403 — and docs/** publishes on push to main. Merging now would put helm install oci://ghcr.io/platformrelay/charts/kollect in front of adopters pointing at nothing, which is the defect class ADR-0708 forbids. Undraft once the chart history is copied and the GHCR package is public.

Part 3 of 3 for DIST-AH-03 (P0).

What changed

The chart install coordinate, and only that. Ten occurrences across README.md, docs/COMMAND-REFERENCE.md, docs/getting-started/install.md, docs/operator-manual/{index,upgrading,load-test-runbook}.md and docs/RELEASE.md. Every other ghcr.io/platformrelay/kollect in the repo is the controller image, which does not move, and was deliberately left alone — charts/kollect/values.yaml, the OLM digest chain, hack/operatorhub-pr.sh, hack/lib/olm-image-digest.sh, the lab registry mirror, and the artifacthub.io/images annotation.

docs/operator-manual/load-test-runbook.md:68 was already broken before this change: it read oci://ghcr.io/platformrelay/kollect/charts/kollect, a path that has never existed. Fixed deliberately rather than by luck.

artifacthub-repo.yml: the ignore key is deleted. repositoryID and owners stay — Verified Publisher needs both. At the new path the regex would match nothing: no v* tags there, and 0.9.00.13.0 are deleted and forbidden from republication. The replacement comments record the one thing that has been re-learned most expensively here: ignore filters indexing, never loading, so adding a regex to silence a tracking error cannot work.

Two gates fixed

dist_install_docs_test.sh had no assertion on the install coordinate at all — it only named it in a comment and scanned two files. It now asserts the coordinate across every doc that hands the reader an OCI chart reference, without false-positiving on controller-image references.

dist_artifacthub_release_test.sh: the ignore-behaviour block became an absence assertion, and the ordering check was reworked from a whole-file grep -n 'oras push' | head -1 to step-graph resolution. That grep was genuinely fragile — reproduced on a scratch copy, a comment containing the string oras push inside an earlier step made it red with "oras push must run after DR-FIND-07 guard", a message naming a problem that did not exist. It now resolves the step by name and asserts that step's own run: script invokes oras push, anchored at a line start, because comments inside a YAML block scalar are script text rather than YAML comments.

Composition with #351

Verified: this branch's gates are green against #351's rewritten release.yaml, and #351's gates are green against this branch's. .github/release-notes-install.md needs no edit — it appends /kollect to CHART_OCI, which #351 sets to the new parent path.

Refs: DIST-AH-03, DR-FIND-07

Merge dependencies — both are hard

  1. 👷 ci(release): derive the chart OCI coordinate once and publish it under charts/ #351 (lane/dist-ah-03-release-path) must merge at or before this PR. docs/RELEASE.md:256 states the release output is oci://ghcr.io/platformrelay/charts/kollect and artifacthub-repo.yml names …/charts/kollect:artifacthub.io as the metadata target. Neither is true of main's workflow — only 👷 ci(release): derive the chart OCI coordinate once and publish it under charts/ #351 makes them true. Every gate here is green standalone, so CI cannot catch the wrong order.
  2. Hold until ADR-0709 runbook step 9 — the Artifact Hub control-panel URL edit — not merely step 5/6. The copy alone leaves this branch's carry-over statements still describing something that has not happened.

…ts/kollect

ADR-0709 separates the chart from the controller image: the chart moves to
ghcr.io/platformrelay/charts/kollect, the image stays at ghcr.io/platformrelay/kollect
with its v-prefixed tags because its digest is pinned immutably in already-merged OLM
bundles. Artifact Hub's documented contract is one chart per repository entry, and the
old shared path served both artifact kinds, so every v* image tag was loaded as a chart
and failed.

Move every `oci://` install/upgrade coordinate in the docs, and state on the install
page and in the upgrade guide what an adopter needs: existing installs keep working --
the history was copied, so both paths serve byte-identical manifests at identical
digests -- but only the new path receives new versions, so pinned or automated
references must be repointed. `image.repository` is untouched everywhere.

docs/operator-manual/load-test-runbook.md carried oci://ghcr.io/platformrelay/kollect/charts/kollect,
a path that has never existed; it is corrected to the real coordinate rather than left
to coincide with the migration.

The DR-FIND-07 notes in docs/RELEASE.md are qualified rather than deleted: the bare
chart tags already pushed to the image path stay there forever, so the digest-resolution
hazard they warn about is permanent for released versions.
… gate

The gate named oci://ghcr.io/platformrelay/kollect in a comment and asserted nothing
about it, and scanned only README.md and docs/getting-started/install.md -- so the five
other docs that hand a reader an OCI chart reference could drift to a coordinate that
does not resolve with every gate green.

Assert the ADR-0709 contract in both directions, because the interesting failure is a
blind sed: the chart and the image share the string ghcr.io/platformrelay/kollect, so
every assertion anchors on the `oci://` scheme, which only ever prefixes a chart
reference. Presence of the new coordinate (so absence cannot be satisfied by deleting
the snippet), absence of the old one, and absence of any controller image reference
under charts/ (v-prefixed tags, image.repository), pinned by RELEASE.md still naming
the image at its own path.

Watched red first: README.md missing the new coordinate, then RELEASE.md failing the
image-path assertion under a blind sed, then COMMAND-REFERENCE.md failing presence when
the install line was deleted.
…come back

At ghcr.io/platformrelay/charts/kollect the regex matches nothing: no v* tags are pushed
to the chart path, and charts 0.9.0-0.13.0 are deleted from the registry and must never
be republished -- they hardcode `image.tag: latest`, a tag that was never pushed, so
they cannot install. A regex matching nothing is not a safety net, it reads like one.

repositoryID and owners stay: Verified Publisher requires both, and they sit in the same
edit that removes the ignore key.

The comments replacing it carry the three facts the next reader needs -- this path holds
charts only, the DR-FIND-07 image/chart collision is permanent at the OTHER path, and
`ignore` filters INDEXING and never LOADING, so it structurally cannot silence an
"error preparing package" tracking mail. That last one has been re-learned twice at the
cost of a session each, so the gate now asserts the sentence is present, not just the
key's absence.

Gate rewritten to the new contract (ignore absent, repositoryID still a UUID, owners
still present, comments actually in the file); every workflow step-name, ordering and
continue-on-error assertion is untouched. Watched red first against the unmodified file
on the ignore-key assertion, and again with a re-added `ignore:` block.
…number

The ordering assertion was `grep -n 'oras push' | head -1` compared against the grepped
line number of the DR-FIND-07 guard. A line number is not a step order -- it only
correlates with one until someone writes a sentence. A lane added an explanatory comment
mentioning `oras push` to the chart publishing step, nowhere near the command, and this
gate went red claiming the metadata push ran before the guard: a failure message naming
a problem that did not exist, which costs more than a miss.

Resolve both steps through the parsed step graph instead -- `step_index` by name, the
same helper the assertions below already use -- and compare indices. The guard step name
joins the null-check loop, so the new comparison cannot pass vacuously either.

Add `step_runs`, which asserts the resolved step's own `run:` script actually invokes
`oras push` at the start of a script line. Comments inside a block scalar are script
text rather than YAML comments, so yq hands them to `test()`; the anchor is what keeps a
`#` line from standing in for the command. This also closes the gap left by the
whole-file presence grep near the top.

Record why the whole-file greps that remain are deliberately text-level: they are
presence checks, where a stray mention can only pass for the wrong reason, never fail
for the wrong reason. Positional claims must go through the step graph.

Both new assertions were watched red on a scratch copy: guard step moved after the push
(index 35 vs 33), and `oras push` replaced by `echo` with the words left in a comment.
…not as done

"the same repository ID, stars and Verified Publisher status carried over" asserts a
maintainer console action has already happened. It will be true when this lands -- the
docs repoint is sequenced after the registry and Artifact Hub steps -- but the sentence
does not need to depend on that: repointing a registered URL in place is what keeps the
ID, stars and Verified badge, whenever it happens.
This file is the one in the set whose bytes are published EARLY: the release workflow
`oras push`es it at the release step, well before the maintainer repoints the registered
Artifact Hub URL in the control panel. Two comments were written as accomplished facts --
the URL "was repointed in place", and the old path "is simply no longer tracked" -- so
the published artifact carried claims that are false at the moment of publication and
stay false until a human clicks something.

Rewritten as mechanism: editing a registered URL in place keeps the repository ID, stars
and Verified Publisher status (Manager.Update keys on repository name), and the old path
becomes inert once the registration points at charts/. A "mind the tense in this file"
note records why this file in particular cannot describe Artifact Hub's state as settled.

Also record the cross-lane dependency the gates cannot see: the charts/kollect coordinate
named at the top is produced by the release workflow's chart-path wiring, which ships in
a separate lane. On an unmodified main this file still goes to the old path, and every
gate here is green either way, so the ordering has to be written down rather than
enforced.

Two clarifications while here: the bare tags kept at the old path (0.14.0+) are kept
because they are installable and may be pinned, which is why deleting 0.9.0-0.13.0 is not
in tension with it; and only 0.14.0-0.19.0 carry over to the new path -- 0.9.0-0.13.0
exist on neither.
…imed

Both assertions described protection they did not provide, which is worse than silence:
the comment is the stated justification for the design.

Anti-blind-sed check. It required `image.repository` to be followed by `=` or `:`, but
the docs state it in prose -- upgrading.md reads "`image.repository` stays
`ghcr.io/platformrelay/kollect`". A sed over upgrading.md alone, or index.md alone, passed
green while corrupting the controller image into a path that holds no images; only a sed
that also hit RELEASE.md was caught, by the `:v` backstop. The key/value match is now a
bounded proximity match, and a general backstop is added: every doc that names the
controller image as its own repository must still name it. That does not depend on
guessing which shape a rewrite leaves behind -- a blind sed rewrites every occurrence, so
it reds even where no v-tag or image.repository sits near the corrupted string.
load-test-runbook.md is deliberately not in that list: it references the chart only.

Presence check. "Deleting the install snippet is not a way to satisfy 'the old coordinate
is gone'" held only for the four files that name the coordinate once. install.md,
operator-manual/index.md and upgrading.md name it twice -- a command and a prose mention
of the move -- so deleting the runnable command left the gate green. Presence is now
anchored to `helm install`/`helm upgrade` for the five files that carry a command, with
README.md and RELEASE.md split into a mention-only list, since their install-paths
sentence and published-outputs table row legitimately have no snippet to run.

Every mutation above was re-run against the tightened gate and reds.
@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

… not to main

The cross-lane note was written as transient state -- "until that lands, `main`'s
workflow still pushes this file to the pre-ADR-0709 path" -- in the one file whose own
preamble forbids exactly that. The release-workflow change is runbook step 2 and lands
before this file does, so the sentence would be false on arrival in `main`, and then
`oras push`ed verbatim into a public registry blob. It also named a branch that is
deleted on merge.

Now stated as a fact about the migration: the coordinate is correct once the release
workflow publishes the chart under charts/ (ADR-0709 runbook step 2), which is a separate
change and precedes this one. The dependency is still recorded; it no longer expires.
@sonarqubecloud

sonarqubecloud Bot commented Sep 1, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant