• 0.1.0 6ff90f04ea

    0.1.0 Stable

    github-actions[bot] released this 2026-07-19 18:03:35 +00:00 | 211 commits to main since this release

    Fixed

    • The release suite accepts the ceremony's own tree (#44) —
      test/release.sh demanded a literal ## Unreleased heading in the real
      CHANGELOG.md, extracting non-empty and containing #32. All three are
      false by construction on the release: X.Y.Z tree the ceremony's own PR
      produces (it stamps that heading into ## X.Y.Z — date), so the first
      real release PR turned CI red and the flow blocked itself — invisible to
      both fork rehearsals, which tag a branch (release.yml runs; ci.yml
      never does). The guard now asserts what it was for: whatever the TOP
      ## section is — Unreleased between releases, the stamped version on
      and right after one — the exact changelog_section the workflow runs
      extracts it non-empty. The rotting issue-number grep is gone.

    • The installer survives an environment with no $HOME (#39) —
      cloud-init's runcmd runs install.sh with no $HOME set, and under
      set -u the first expansion died with a bash unbound-variable stack
      instead of an install — found live by box#88's template seed, which
      pins HOME=/root as its own scar. The installer now derives the home
      from getent for the effective user (root included) before any path
      is built from $HOME, and when getent has no answer either it refuses
      by name. Driven with a shim getent both ways: the derived-home install
      lands, the no-answer refusal is pinned. (#41 — merged without its
      entry; restored here at the release gate.)

    • Headless credential prompts refuse loudly instead of dying silently
      (#42) — the interactive credential prompts (TS_AUTHKEY in bootstrap,
      RUNNER_TOKEN in runner install, RUNNER_REMOVE_TOKEN in
      runner remove, and both tokens in runner repoint — a site the new
      no-bare-read test caught after the issue counted three) were bare
      read -rsp: with stdin not a tty (CI,
      box exec, any script), read fails, set -e ends the run, and the
      log just stops — exit 1, no last word, measured live in the
      2026-07-19 release drill. Each prompt now checks for a tty first and
      dies naming the variable that unblocks an unattended run (runner remove also names --local), and every read is || die-guarded so
      EOF at a real prompt gets the same courtesy. db.sh already held the
      line here; now all of rig does.

    Added

    • Merging a release-labeled PR IS the release — and the release re-arms
      main itself
      (#47) — the rig twin of heavy-duty/box#96, born of the
      ceremony retro: the tag was a separate, manual, silent-when-forgotten
      step, and a forgotten tag produces no red X. release.yml now fires on
      pushes to main (fork-sourced ceremony PRs get a read-only token on
      pull_request events), reading the transition from the push itself:
      event.before to the pushed head. A decide step answers four states —
      release-flow work merged under the release label (-dev endstates,
      the post-release window) no-ops green with a NOTICE; the two genuinely
      ambiguous bare states refuse loudly; a true transition then requires a
      merged, release-labeled PR behind the commit (read via the API — the
      label is the operator's declared intent). Then, in the same job, it
      API-creates the tag at the merge commit, publishes with the extracted
      notes — and bumps main to X.Y.(Z+1)-dev itself, direct push with a
      loud open-a-PR fallback, so no follow-up bump PR exists on the paved
      road. A GITHUB_TOKEN-created tag never fires the tag-push trigger, so
      the paths cannot double-publish — and that tag-push path survives intact
      as the documented manual fallback and backfill.

    • Tagged releases, and an installer that installs them (#32) — the rig
      half of the flow designed in heavy-duty/box#83, near-verbatim. A release
      is a PR, then a tag: the release: X.Y.Z PR bumps VERSION and stamps
      this file's Unreleased section with version + date; the merge commit is
      tagged bare X.Y.Z (box's tag scheme — no v prefix). release.yml
      turns the tag into the GitHub release — after asserting tag == VERSION
      (mismatch fails loudly and creates nothing) — with that version's section
      of this file as the body, extracted by the same changelog_section the
      test harness drives. No assets: for a pure-bash tree, GitHub's source
      tarball for the tag IS the package. install.sh now defaults to the
      latest release: the tag is resolved by following the
      releases/latest redirect and reading the Location header — no API, no
      token — and the download is archive/refs/tags/<tag>.tar.gz. RIG_REF
      picks the other two channels: a tag pins (refs/tags outranks a
      same-named branch), a branch (RIG_REF=main) tracks the development
      tree. Until 0.1.0 is cut the default channel has nothing to resolve and
      dies saying exactly that, naming RIG_REF=main as the way to install
      today — it never falls back to main silently, because "I installed the
      latest release" must not quietly mean "I installed whatever main was that
      second". Step 5 of #32 — pinning BOX_REF in the host-installs-box path
      — stays open until box cuts its next tagged release.

    Downloads