Problem / Context
README.md carries three badges (README.md:3-5): CI (dynamic), License (static, low-churn), and Status: alpha (static, links to #670). There is no version badge — a reader can't tell from the README which release OpenLinker is on.
The naive fix — writing v0.1.0 into the README — is the wrong move: it would go stale the instant the next release cuts (e.g. #1345 → 0.1.1), and the README is the one place nobody remembers to update. That's the exact drift class we've been closing this session (stale bootstrap-sha, doc-vs-config mismatches). The version now has a single canonical source already — the git tag / GitHub Release that release-please manages (shipped in #1332), which is the same source GET /v1/health reports and the CHANGELOG compare links key off (see ADR-029 § the four version axes). The README badge should read from that source, not duplicate it.
Separately, the prose at README.md:13 (> **Status: alpha, pre-1.0.** First public release is in progress.) is now stale — v0.1.0 is tagged (at e6298374) and its GitHub Release is being published.
Proposed Solution
Two axes, handled differently by churn rate:
-
Version (high-churn) → dynamic badge, never a literal. Add a shields.io badge to the README.md:3-5 badge block. Two acceptable variants — pick one:
[](https://github.com/openlinker-project/openlinker/releases) — reads the latest published GitHub Release. Truest "what's released," same source as /v1/health. Caveat: renders "no releases" until the v0.1.0 GitHub Release is published (a manual step in progress).
[](./CHANGELOG.md) — reads version from the root package.json on main (already 0.1.0). Works immediately, decoupled from Release-publish timing, and stays in lockstep because release-please only bumps that field when a Release PR merges.
- Recommendation:
package-json/v — correct right now regardless of when the v0.1.0 Release is published, and it points readers at the CHANGELOG rather than a possibly-empty Releases page.
-
Maturity (low-churn) → keep the static alpha badge as-is (README.md:5). It changes ~twice in the project's life (alpha → beta → 1.0), maps to the 0.x SemVer convention, and is correctly hardcoded. Do not fold version and maturity into one badge.
-
De-stale the prose at README.md:13: keep it maturity-only and version-agnostic so it can't re-drift, e.g. > **Status: alpha, pre-1.0.** Expect rough edges; report them. (drop "First public release is in progress"). Let the badge carry the number.
Classification
Type: DX (documentation / release presentation)
Layer: Shared / repo root
File(s): README.md (badge block :3-5, prose :13)
Dependencies
Assumptions
- README-only change; no app code, no FE component, no migration.
- The
package-json/v badge is preferred (works immediately); implementer may substitute v/release if the team prefers "published Release" semantics and accepts the empty-until-published window.
- The existing
Status: alpha badge and its #670 link stay untouched.
Acceptance Criteria
Problem / Context
README.mdcarries three badges (README.md:3-5): CI (dynamic), License (static, low-churn), andStatus: alpha(static, links to #670). There is no version badge — a reader can't tell from the README which release OpenLinker is on.The naive fix — writing
v0.1.0into the README — is the wrong move: it would go stale the instant the next release cuts (e.g. #1345 →0.1.1), and the README is the one place nobody remembers to update. That's the exact drift class we've been closing this session (stalebootstrap-sha, doc-vs-config mismatches). The version now has a single canonical source already — the git tag / GitHub Release that release-please manages (shipped in #1332), which is the same sourceGET /v1/healthreports and the CHANGELOG compare links key off (see ADR-029 § the four version axes). The README badge should read from that source, not duplicate it.Separately, the prose at
README.md:13(> **Status: alpha, pre-1.0.** First public release is in progress.) is now stale —v0.1.0is tagged (ate6298374) and its GitHub Release is being published.Proposed Solution
Two axes, handled differently by churn rate:
Version (high-churn) → dynamic badge, never a literal. Add a shields.io badge to the
README.md:3-5badge block. Two acceptable variants — pick one:[](https://github.com/openlinker-project/openlinker/releases)— reads the latest published GitHub Release. Truest "what's released," same source as/v1/health. Caveat: renders "no releases" until thev0.1.0GitHub Release is published (a manual step in progress).[](./CHANGELOG.md)— readsversionfrom the rootpackage.jsononmain(already0.1.0). Works immediately, decoupled from Release-publish timing, and stays in lockstep because release-please only bumps that field when a Release PR merges.package-json/v— correct right now regardless of when the v0.1.0 Release is published, and it points readers at the CHANGELOG rather than a possibly-empty Releases page.Maturity (low-churn) → keep the static
alphabadge as-is (README.md:5). It changes ~twice in the project's life (alpha → beta → 1.0), maps to the 0.x SemVer convention, and is correctly hardcoded. Do not fold version and maturity into one badge.De-stale the prose at
README.md:13: keep it maturity-only and version-agnostic so it can't re-drift, e.g.> **Status: alpha, pre-1.0.** Expect rough edges; report them.(drop "First public release is in progress"). Let the badge carry the number.Classification
Type: DX (documentation / release presentation)
Layer: Shared / repo root
File(s):
README.md(badge block:3-5, prose:13)Dependencies
github/v/releasevariant is chosen, it only renders a number once thev0.1.0GitHub Release is published — but that doesn't block the edit. Thepackage-json/vvariant has no dependency at all.chore: release 0.1.1Release PR), ADR-029.Assumptions
package-json/vbadge is preferred (works immediately); implementer may substitutev/releaseif the team prefers "published Release" semantics and accepts the empty-until-published window.Status: alphabadge and its#670link stay untouched.Acceptance Criteria
:3-5block that resolves to the current version with no hardcoded number in the markdown source (the version appears only inside the shields.io URL slug, not as literal text).0.1.1), the badge shows the new version with zero README edits (verify by confirming the badge URL reads from Releases or rootpackage.json, both of which release-please updates).Status: alphabadge (README.md:5) is unchanged.README.md:13prose no longer claims "First public release is in progress" and carries no literal version number.pnpm lint(incl.check:invariants/scripts/check-repo-urls.mjs) passes — the new shields.io URL uses the canonicalopenlinker-project/openlinkerslug and trips no repo-URL guard.