← The specification

Repo: homebrew-tap

Rendered from spec at76d46f3 (2026-10-25) · its source · Edit this page

Status: Accepted

The Homebrew formulae. Ruby, Hippocratic 3.0. Generated — humans rarely touch it.

Implements: the Homebrew path of E2 and roadmap M10.


Why this is a separate repo

Not a choice — a Homebrew requirement. brew tap lemonfiber/tap resolves to a repository named homebrew-tap. This is the floor that made the org multi-repo regardless of other considerations (ADR-0004).

What’s in it

homebrew-tap/
├── Formula/
│   └── lemonfiber.rb        a placeholder until release CI generates it
├── scripts/check_formula.py `brew style` and `ruby -c` over the formula
├── justfile
└── README.md

A single formula, and it is generated output, never hand-written (REPO-R24). Generation is a cargo-dist publish job that lands with 1.0.0 (L1-R3) and needs a token that can push here; until then the committed formula is a placeholder and brew is not an install path. Once it is on, each lemonfiber release produces the version, the per-platform bottle URLs and their checksums.

The formula

class Lemonfiber < Formula
  desc "Self-hosted media automation stack, run in slices"
  homepage "https://github.com/lemonfiber/lemonfiber"
  version "0.4.0"
  license "Hippocratic-3.0"      # license-file in Cargo; see below

  on_macos do
    on_arm do
      url "https://github.com/lemonfiber/lemonfiber/releases/download/v0.4.0/lemonfiber-aarch64-apple-darwin.tar.xz"
      sha256 "…"
    end
    # x86_64 …
  end
  on_linux do
    # gnu / musl …
  end

  def install
    bin.install "lemonfiber"
  end

  test do
    assert_match "0.4.0", shell_output("#{bin}/lemonfiber --version")
  end
end

The Hippocratic wrinkle

Hippocratic 3.0 is not an SPDX identifier (licence rationale). Two consequences land specifically here:

  1. homebrew-core requires OSI-approved licences, so lemonfiber can never be in core — only in this tap. That’s exactly why the tap exists, so it isn’t a limitation in practice.
  2. Once generated, the formula’s license line is a non-standard string; the committed placeholder has none. brew audit --strict will warn, which is acceptable in a tap that is ours; brew style and ruby -c run here, through the formula check.

The crates are publish = false and the release ships one binary rather than a crates.io package, so cargo install lemonfiber is not an install path either. Building from the repository is (cargo install --git).

E2’s boundary

When lemonfiber was installed via Homebrew, lemonfiber update self defers (E2-R1): it prints brew upgrade lemonfiber rather than replacing its own binary. A binary that overwrites itself out from under the package manager that owns it produces a brew installation that disagrees with what’s on disk (E2-R2).

Detecting the install method is lemonfiber’s job; this repo simply must exist and stay current for the deferral to have somewhere to point.

Maintenance

Effectively none by hand. Once the publish job is on, the release workflow in lemonfiber opens a PR here (or pushes directly) with the regenerated formula. The only human involvement is if the generation itself needs changing — and that change, like any other, cites a spec identifier (GOV-R2).

Because it’s generated, this repo is exempt from the code-review depth the others get — there’s nothing hand-written to review. It is not exempt from governance: a change to the generator is a lemonfiber change and follows the normal lifecycle.

Requirements

ID Requirement
REPO-R24 The formula MUST be generated by release CI, not maintained by hand.
REPO-R25 The formula MUST carry per-platform URLs and checksums for every released target.
REPO-R26 The formula’s test block MUST assert the installed binary reports the expected version.
REPO-R27 The tap MUST stay current so lemonfiber update self’s Homebrew deferral has a valid target.
REPO-R28 A change to the formula generator MUST follow the normal change lifecycle in lemonfiber.