# Session handoff — 2026-06-18 (74)

Large session. Continues from handoff-73 (Ctrl-G demo alias). This one ran
the **road to public availability** end to end: a post-merge doc
reconciliation, then versioning, installers, crates.io/binstall, the
`cargo fmt` gate, and an actual **`v0.2.0` release that is now live on
crates.io**. Three new main-sequence ADRs (0054/0055/0056), one CI-ADR
amendment, issue **#35 closed**.

## §1. State

**Branch `main`.** **2509 pass / 0 fail / 1 ignored** (the long-standing
`friendly` doctest); **clippy clean**; **`cargo fmt --check` clean** (the
tree is now stock-rustfmt formatted, and CI gates it). `rdbms-playground
--version` → `rdbms-playground 0.2.0`.

**Released:** **`v0.2.0`** — Gitea release with all six D1 targets
(Linux/Windows via `release.yaml` on the tag; macOS via the dispatched
`release-macos.yaml`, **ad-hoc-signed**). **Published to crates.io**
(`cargo install rdbms-playground` and `cargo binstall rdbms-playground`
both user-verified).

**Push state:** earlier commits were pushed (they triggered CI/releases).
The **most recent commits are unpushed** and matter:
- `3c87dbb` macOS nix-prune fix (takes effect next macOS dispatch).
- `d3af1c4` + `8ebe213` the manual `publish.yaml` workflow — ADR-0056 in
  the first, the **workflow file itself in the second** (`git commit -am`
  had skipped the new untracked file).
- this handoff.
Push `main` to land them. (Push is the user's step.)

## §2. What shipped (commits `628b250`→`d3af1c4`)

- **`628b250` doc reconciliation** after the CI + website branch merges:
  rewrote CLAUDE.md's stale repo-layout tree; added a Website subproject
  note; fixed the CI note; **gitignored `.wrangler/` + `.vscode/`** and
  removed a tracked `website/.vscode/`; updated requirements (D1 macOS
  runtime-verified, DOC1 canonical-docs-on-website) + ADR-ci-003.
- **`c30a611` ADR-0054 — version surfaces.** `--version`/`-V` + an in-app
  **`version`** command, both reading `CARGO_PKG_VERSION` via one
  `cli::version_text()`. A **release-CI guard** fails the release unless
  the `v*` tag equals `v<Cargo.toml version>`.
- **`ef99e6c` ADR-0055 — `scripts/install.sh`** (curl|sh, POSIX,
  shellcheck-clean, checksum-verified, `~/.local/bin`). Verified
  end-to-end against the live release. **`install.ps1`** (Windows
  `irm|iex`) added later (`e9606b5`) — **written but untested here** (no
  PowerShell on this box; validate on Windows).
- **`e9606b5` ADR-0056 — crates.io + binstall prep.** Publish-ready
  Cargo.toml (dropped `publish=false`; homepage/keywords/categories/
  `exclude`); `README.md`; `LICENSE-MIT`/`LICENSE-APACHE` (dual, © Lazy
  Evaluation Ltd) + `CONTRIBUTING.md` (inbound=outbound); the
  `[package.metadata.binstall]` block with per-target overrides
  (linux-gnu→musl, windows-msvc→gnu/gnullvm; macOS direct).
- **`41b7e9a` + `ec3c7c3` — #35 fmt gate.** One mechanical `cargo fmt`
  (stock defaults, 102 files, behaviour-preserving) recorded in
  `.git-blame-ignore-revs`; `ci.yaml` now gates `fmt --check` (ADR-ci-002
  Amendment 1). **Closes #35.**
- **`88830ed`+`bd5be5e` — v0.2.0 bump + the guard bug.** The first
  `release.yaml` run **failed** at the version guard: it piped `nix
  develop -c cargo metadata` to node, but the **flake devShell prints a
  banner to stdout**, corrupting the JSON. Fixed to a toolchain-free
  `grep -m1 '^version = ' Cargo.toml`. The `v0.2.0` tag was re-pointed
  (Option A) to the fix commit; re-run went green.
- **`3c87dbb` — macOS nix-prune fix.** The prune step's profile dir
  (`~/.cache/rdbms-ci`) didn't exist, so `nix develop --profile` errored
  (swallowed by `|| true`) → the gc-root was never created → the whole
  toolchain (~3.8 GiB) was deleted **and re-downloaded every run**. Added
  `mkdir -p` + dropped the `|| true`. Diagnosed from the run-74 log via
  `tea actions runs logs 74`.
- **`d3af1c4` — manual `publish.yaml`.** `workflow_dispatch` + `tag`
  input (mirrors `release-macos.yaml`). Idempotent `crates-io` job
  (crates.io API pre-check + `cargo publish` backstop), independent jobs
  so Scoop/Homebrew/winget slot in later. ADR-0056 Amendment 1.

## §3. Live vs manual vs parked

- **Automated on a `v*` tag:** `release.yaml` builds + publishes the four
  Linux/Windows targets (+ fmt/clippy/test gate).
- **Manual `workflow_dispatch`:** `release-macos.yaml` (mac binaries —
  intermittent runner) and `publish.yaml` (crates.io now; more registries
  later). Run them once the tag's build is up.
- **Parked (user decisions):**
  - **macOS Developer-ID signing.** The pipeline **ad-hoc-signs**
    (`codesign --sign -`). The user's `Apple Development` cert is the
    **wrong type** — distribution needs **`Developer ID Application`** +
    **notarization** (App Store Connect API key recommended). Fine for
    `curl|sh` (no quarantine); matters for browser downloads. Details in
    `docs/plans/20260616-public-availability.md`.
  - **Remaining D3:** Scoop (`lazyeval` bucket), Homebrew (`lazyeval`
    tap), winget (komac on Linux CI, or manual PR) — each a sibling job
    in `publish.yaml` + a manifest repo.

## §4. Immediate next steps

1. **Push `main`** (lands `3c87dbb` + `d3af1c4`).
2. **Add the `CARGO_REGISTRY_TOKEN` secret** (crate-scoped,
   `publish-update`) so `publish.yaml` works: `tea actions secrets create
   CARGO_REGISTRY_TOKEN` (paste at prompt) or the Gitea UI.
3. **Smoke-test `publish.yaml`:** dispatch it for `v0.2.0` — it should
   **idempotently skip** ("already on crates.io"), exercising the path
   risk-free.
4. The release ritual going forward (ADR-0054): bump `Cargo.toml` →
   commit → tag `v<x.y.z>` → push tag (Linux/Windows release builds) →
   dispatch `release-macos` → dispatch `publish`.

## §5. Gotchas learned (don't relearn the hard way)

- **The flake devShell prints a banner to stdout** — never pipe `nix
  develop -c <cmd>` into a parser. Read Cargo.toml directly, etc.
- **Workflow-file source differs by trigger:** a **tag**-triggered run
  (`release.yaml`) uses the workflow **at the tagged commit**; a
  **`workflow_dispatch`** run (`release-macos`/`publish`) uses the
  **default branch** (`main`). So fixing a dispatched workflow only needs
  a `main` push; fixing a tag-triggered one needs the tag re-pointed.
- **Version vs tag:** `Cargo.toml` is bare `0.2.0`; the git tag is
  `v0.2.0`; the guard checks `tag == "v" + version`; binstall `pkg-url`
  spells `v{ version }`.
- **CI logs are reachable** via `tea actions runs logs <id>` (and `tea
  actions runs list --output tsv`). Use it instead of guessing from a
  step name.
- **crates.io API needs a descriptive User-Agent** (403 without one).

## §6. How to take over

1. Read handoffs 72 → 73 → 74, `CLAUDE.md`, `docs/requirements.md`, and
   **`docs/plans/20260616-public-availability.md`** (the GA roadmap with
   all decisions + parked items).
2. Confirm green: `cargo test` (**2509 / 1 ignored**), `cargo clippy
   --all-targets`, `cargo fmt --check`.
3. ADRs for this arc: **0054** (versioning), **0055** (installer),
   **0056** (crates.io/binstall + the publish workflow); CI side
   **ADR-ci-002 Amendment 1** (fmt gate), **ADR-ci-003** (release matrix
   + macOS).
4. Workflow unchanged: phased, test-first, `/runda` + DA before commits,
   ADR amendment + README index-upkeep for decided-area changes, confirm
   commit messages, never push.
5. Consider a `cargo sweep` at this milestone (`target/` grows).
