Skip to content

release: v0.1.0 post-release follow-ups (latest badge, notes, version flag, docs) #501

Description

@EricAndrechek

The first tagged release (v0.1.0 + clients/ts/v0.1.0, 2026-08-19) shipped successfully — every artifact publishes, verifies, and runs. This tracks the rough edges found while verifying it end-to-end.

Nothing here is a release blocker. The release is good; these are follow-ups.

What was verified working

Recorded so nobody re-audits it:

  • Binaries — 8 archives (linux/darwin/windows/freebsd × amd64/arm64), matching the goreleaser matrix; .zip on Windows, .tar.gz elsewhere; checksums.txt verifies.
  • -X ldflags — the released binary reports version=0.1.0 build_time=2026-08-19T16:54:06Z git_commit=9d4cef9. The BuildTime initializer fix (ci(release): make every version tag-driven and fix the dev channel #485) works in production.
  • go install …@v0.1.0 — works off the module proxy, and reports exactly what development.md claims: version=0.1.0, build_time/git_commit = unknown. The buildInfoFallback() doc claim is empirically correct.
  • GHCR — :v0.1.0 and :latest resolve to the same digest sha256:dda9194b533e2ae8e56dbdb5498e216e975e76c24420fe10cf56ecca2c5f2f24.
  • Sigstore provenance — binary and image verify under strict --signer-workflow. Negative control passes too: pointing --signer-workflow at ci.yml is rejected (exit 1), so the check discriminates rather than passing vacuously.
  • npm — @wavehouse/sdk@0.1.0 under latest; npm audit signatures reports verified registry signatures and verified attestations (SLSA v1).
  • npm: the dev channel's versions don't order by recency, so a range resolves to a two-month-old build #475 fixed in production — the dev dist-tag (0.0.1-dev.20260819163639.h62b2f85f436a) is now the semver-highest of all 14 published versions, ^dev resolves forward, and a dev build cannot satisfy ^0.1.0.
  • Quickstart against the released image — getting-started.md steps 1–5 run clean on ghcr.io/wave-rf/wavehouse:v0.1.0: table create, ingest ({"ok":true}), query (both rows), SSE (: connected + live event), and wavehouse health exits 0.

1. The SDK release stole the "Latest release" badge

https://github.com/Wave-RF/WaveHouse/releases/latest resolves to clients/ts/v0.1.0, which has 0 assets.

gh release create defaults --latest to automatic, and the SDK release was created at 17:06 vs the server's 17:01 — newest non-prerelease wins. Consequences:

  • the repo sidebar advertises the SDK as the headline artifact;
  • gh release download --repo Wave-RF/WaveHouse with no tag picks a release containing no binaries;
  • any "grab the latest release" automation gets the wrong thing.

Fix, two parts:

gh release edit v0.1.0 --latest     # reclaim it now

and in .github/workflows/publish-npm.yml (~line 339), so future SDK releases never take it again:

+          # The server release owns the repo's "Latest" badge — a client
+          # release must never take it (it carries no binaries).
+          flags+=(--latest=false)
           gh release create "$tag" "${flags[@]}"

2. The SDK release body is a single fallback sentence

clients/ts/v0.1.0's entire body:

First release of @wavehouse/sdk. See the repository releases for the full change list.

That's the intended first-release fallback (no earlier clients/ts/v* to diff from), so it is working as designed and is self-correcting — the next SDK release generates real notes anchored at clients/ts/v0.1.0.

Two things still worth doing:

3. Auto-generated notes undersell the release

Category counts for v0.1.0 (142 entries):

Category Count
📚 Documentation 56
🔧 CI & build 42
📦 Dependencies 24
🧹 Other changes 14
✨ Features 1
⚠️ Breaking changes 1
🐛 Bug fixes absent

The taxonomy did its job — Dependabot routing is clean, zero bumps leaked into CI/Docs. The problem is upstream of it: GitHub groups by label, documentation/github_actions are auto-applied by actions/labeler, and enhancement/bug are applied by hand and mostly weren't. So a release that contains the entire product reads as a docs-and-CI release.

Options, roughly in cost order:

  1. Accept it for v0.1.0 and treat CHANGELOG.md as the narrative (it already is — development.md says the changelog "is not the source of the release body; it is the longer-form record").
  2. Backfill enhancement/bug on the merged PRs that warrant it and regenerate the notes.
  3. Make labeling routine going forward so 0.2.0 doesn't repeat this. GitHub cannot categorise on Conventional-Commit title prefixes, so hand-labeling (or a bot that maps feat:/fix: → labels at merge) is the only lever.

4. wavehouse version silently boots the server

main.go:102 special-cases exactly one subcommand:

if len(os.Args) > 1 && os.Args[1] == "health" {

Everything else falls through to run(). So wavehouse version, --version, and -v all start a full server — binding ports and creating a data/ directory in the caller's cwd — instead of printing a version. version is the first thing most people type after go install.

The version is available (first log line, and /version), so this is ergonomics, not a data bug. The code already anticipates it: "If we ever need more, swap to a real argv router." Worth doing now that the binary is public.

5. standalone.yaml can't run the released image

deployments/compose/standalone.yaml:14 uses build: context: ../.., so the documented quickstart requires cloning the repo — it never consumes ghcr.io/wave-rf/wavehouse. Now that :latest and :v0.1.0 exist, a user should be able to run the stack without the source tree. (Verifying #149's "against the released image" box required a hand-written compose file substituting image:.)

Suggest either switching the service to image: ghcr.io/wave-rf/wavehouse:latest with the build stanza as a documented dev override, or shipping a second standalone-released.yaml.

6. Query silently returns [] for a malformed request

Same server, opposite strictness:

Path Request Response
/v1/ingest {"pge": …} 400 unknown column "pge"
/v1/query {"colums": ["page"]} 200 []
/v1/query {} / {"limit":10} / {"columns":[]} 200 []

A misspelled or omitted columns yields an empty result set that is indistinguishable from "the table has no rows". getting-started.md explicitly promises the strict behaviour for ingest ("Unknown fields, type mismatches, and missing required columns are rejected with a 400"); query does the opposite.

This cost real debugging time during release verification — an empty result was initially read as a broken release. A 400 on "no projection specified" (neither columns nor select_all) would remove the whole failure class.

7. Docs corrections

  • development.md:627 — "A tag carrying a prerelease suffix … never takes the 'Latest release' badge from a shipped stable version." True but incomplete: it only covers prerelease-vs-stable, and misses the case that actually bit us (item 1) — two stable tag families in one repo compete for the badge. Should state that the server release owns "Latest" and client releases are created with --latest=false.
  • development.md:628 — "Both — release notes generated by GitHub…" is inaccurate for the first release in any tag family, which gets the fallback body instead (item 2). Worth one clause.
  • development.md:618 — the Tag naming block documents clients/go/v0.1.0 Go SDK, but there is no clients/go module (only clients/ts). Fine as illustration of the scheme; flagging in case it reads as shipped.
  • npm publishing constraints are undocumented (carried from npm publishing: post-launch follow-ups (provenance, release path, latest tag, docs) #268). The one-trusted-publisher constraint and the Node 24 / npm ≥ 11.5.1 requirement for OIDC publishing exist only as comments in publish-npm.yml. development.md → Cutting a release documents the flow and the dev channel but neither of these. Anyone touching the publish jobs needs both.
  • README — no release or npm-version badge. Both now exist and resolve; a GitHub release + npm version badge alongside the coverage/Go-report/license row would be cheap.

Refs

Closes out verification for #149; overlaps the release-path items in #268.

Activity

  1. added
    documentationImprovements or additions to documentation
    github_actionsPull requests that update GitHub Actions code
    polishImprovements to existing features
    on Aug 19, 2026
  2. EricAndrechek commented on Aug 25, 2026

    @EricAndrechek
    MemberAuthor

    Priority re-anchor + five priority changes — consolidated rationale. Posting here because #149 (the launch tracker that anchored the old rubric) is closed, and this is the live post-release tracker.

    The anchor

    .claude/skills/pm-triage/references/rubric.md defines P0 as "blocks the flip" — the v0.1.0 cut and the repo public-flip. Both shipped 2026-08-19. Since then P0 has been empty and undefinable: there were 0 open P0s and no way to rate a new one, while P2 absorbed 89 of 173 open issues.

    Working anchor from here, applied below (Eric's call, 2026-08-25):

    P0 — live in a shipped, public release and severe enough to cut a patch for.
    P1 — wanted in the next release. P2 — blocks broader adoption. P3 — backlog.

    ⚠️ rubric.md still says the old thing. That edit needs a PR through the normal gate and has not been made — until it is, this comment is the only written record of the anchor.

    The changes

    issue why
    #474 P1 → P0 Verified plain read of denied column values (argMax(*)/argMin(*) on 2-column tables) plus a cardinality oracle at any width. Contradicts access-control.mdx:177, published on the public docs site. Independent urgency: the fix is a breaking query-API change whose cost the issue itself notes "grows after the first tagged release" — that clock is running.
    #460 P1 → P0 A one-character operator typo silently disables row security and /validate returns {"valid":true} — the safety net certifies the breach. Now scoped to that detection half only; see below.
    #461 P2 → P1 Not a new exposure but a reach gap, and it is load-bearing — see the ordering note below.
    #396 P2 → P1 Consolidated with #449. Three failure modes in liveQuery(), a headline documented feature, live in v0.1.0; a first-party consumer has already routed around it.
    #389 P2 → P1 Consolidated with #477. Unbounded memory growth (~70 MB/hour at 100 ev/s) in .subscribe() — the primary documented streaming API — with no cap and no drain.

    #460 is now two issues

    The strict-decoding half is split out as #514 (P2). It is a breaking change to config parsing needing warn-then-reject over a release, and #460 flags that migration risk itself. Left combined, the urgent half — RLS silently off while /validate says it's fine — would have moved at the slow half's pace. #460 now covers rejecting an all-nil Filter, rejecting filter: under insert:, and making /validate stop lying.

    Ordering constraint (not just priority)

    #461 must precede #460. validateRolePerms runs only via Store.Put; the load and Watch paths cache KV policies unvalidated. So every rule #460 adds is inert on any deployment already carrying a policy in KV — which is exactly the population most likely to be carrying the bad policy, including the SCC-2026 pilot. Fixing #460 first produces a fix that does not reach the deployments that need it.

    Suggested sequence: #461 → #460 → #474 → #514 (warn-first).

    Disclosure

    Of the three security items, only #474 clears the bar for a GitHub Security Advisory — a verified read of denied data in a shipped public artifact that contradicts published documentation. #460 requires operator misconfiguration to trigger and #461 is a reach gap on an already-disclosed fix; both are defensible as plain open issues. Still undecided — flagging, not deciding.


    pm-triage routine, 2026-08-25, on Eric's instruction. All claims verified by code-read against b2eee9d.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationgithub_actionsPull requests that update GitHub Actions codepolishImprovements to existing features

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions