0019 — Vibey is installable wherever its users already are¶
Status: superseded in part by ADR-0037 · Date: 2026-09-15 · Extends: ADR-0017, ADR-0018
Canon: sub-doctrine 2.b — installable wherever its users already are, filed under doctrine 2 — Audience channels (ADR-0020). It is law from the operator's ratifying merge of the change that carries it.
The decision and the channel plan stand, and get simpler. ADR-0037 supersedes only this record's opening premise: "Ten distributions come out of this tree" is now one. Every target below — Homebrew, winget, apt, the single-file artifact — now has one artifact to carry rather than ten, which is the same decision with less work in it.
Context¶
Ten distributions come out of this tree and every one of them reaches exactly one
audience: people who already have Python and reach for pip. That is the wrong
shape for what these are. vibey, the five *loop runners and vibey-gh are
command-line applications. Someone installing a CLI runs brew install,
winget install, apt install — the fact that it happens to be written in
Python is an implementation detail they should never have to care about, and
pip install asks them to care.
The evidence that this is already felt: a Homebrew tap already exists —
adammatthewsteinberger/homebrew-tap, tapped as brew tap adammatthewsteinberger/tap
— with Formula/ and Casks/ directories, and both are empty.
Decision¶
Publish to every registry that can carry these projects, and treat a distribution channel as part of shipping rather than as a follow-up.
A release is not finished when PyPI has the wheel. It is finished when the channels that carry it have it.
What the targets actually are¶
Taking the list literally would produce an unactionable plan, because it names four different kinds of thing. Grouped by what publishing to each one means:
1. Registries we can publish to ourselves, today. These accept a submission from the author with no gatekeeper, which makes them the whole near-term plan.
| macOS / Linux | Homebrew (our own tap exists and is empty), MacPorts, pkgsrc, Nixpkgs |
| Linux, self-served | Arch AUR, Fedora COPR, Ubuntu PPA, openSUSE OBS, Alpine aports |
| Linux, sandboxed | Snap (Snapcraft), Flatpak (Flathub) |
| Windows | winget, Chocolatey, Scoop |
| FreeBSD | ports |
| Python-adjacent | conda-forge |
2. Official distribution repositories, which need a human. Debian, Fedora,
Arch extra, openSUSE and Ubuntu's own archive all require a package maintainer
and a review process; nobody self-publishes into them. They are a goal reached
through group 1 — a package that has lived in AUR/COPR/PPA with users is the
normal path to a maintainer picking it up. Planning them as tasks would be
planning someone else's decision.
3. Formats and tools, not registries. dpkg, rpm and apk-tools are how a
.deb, .rpm or .apk is built and installed, not places to publish. We
produce those artifacts — and attaching them to a GitHub Release is genuinely
useful — but "publish to dpkg" has no meaning, and the work it stands for is
already covered by group 1.
podman is a container runtime, not a package manager. What it actually wants is
an OCI image, and this repository already builds one (deploy/docker/,
multi-arch amd64+arm64, gated by the Image contract - … steps of CI's image job). release-surfaces.yml
already pushes to ghcr.io on every release, but what it pushes is the wheel and
sdist as an OCI artifact (ghcr.io/<repository>/python), not the runnable container
image. Publishing the image is a small, real task, and it serves Docker, podman, Kubernetes and
anything else that speaks OCI at once.
4. Registries for other languages' libraries. npm, yarn, Maven, Gradle,
Cargo, NuGet, Composer, RubyGems, sbt, vcpkg, Deno and PEAR carry JavaScript,
Java, Rust, .NET, PHP, Ruby, Scala and C++ packages. None can carry a Python
library. What they can carry is a thin wrapper that downloads the CLI — which
is a real, common pattern, and a different promise: npm install vibey would
give you the command, never an importable library, and the package must say so.
So these are judged individually on whether the audience is real rather than
adopted as a set. npm is worth it — a very large population of developers
installs tooling that way and never touches Python. The rest are not: a Maven
artifact that shells out to a Python CLI serves nobody, and publishing one is
noise in someone else's ecosystem. PEAR is superseded by Composer; Fink is
dormant; wpkg is dead; par names no package manager we could identify.
Revisit any of them when a real user asks.
How it is done, per the doctrines this extends¶
Every packaging definition lives in this repository (ADR-0018). A Homebrew formula, a PKGBUILD, a snapcraft.yaml, a nuspec, a winget manifest — all of them are code, reviewed in a pull request, and rendered or published by automation. A recipe that exists only in a tap somebody edits by hand is exactly the clicked state that ADR forbids.
vibey-gh conducts it (ADR-0017). Releasing to N channels is release
automation, and this family already has release automation. The capability
belongs there — beside report-superseded, which already knows about indexes —
and not in a pile of per-repository workflow YAML.
One artifact, many wrappers. Most of group 1 needs a self-contained executable rather than a Python package, so a single-file build (shiv, pex or PyInstaller) becomes a release artifact that the majority of these channels then just point at. That one piece of work unblocks most of the list, which is why it comes first.
Consequences¶
Sequenced by reach per unit of effort, not by list order:
- OCI image to
ghcr.io. Already built and contract-tested; only publishing is missing. Serves podman, Docker and Kubernetes at once. - A single-file executable as a release artifact. Unblocks most of what follows.
- Homebrew. The tap exists and is empty; the largest macOS/Linux developer audience per line of effort.
- winget, Scoop, Chocolatey. Manifest-only, and the only reasonable way a Windows user installs a CLI.
- AUR, COPR, PPA, OBS, Alpine. Self-served Linux, and the route toward group 2.
- Snap and Flatpak. Higher effort; both want a confinement story, and a worker that spawns engine subprocesses and writes git worktrees is not obviously confinable. Decide the confinement level before starting.
- conda-forge, Nixpkgs, MacPorts, pkgsrc, FreeBSD ports. Each has its own review culture; steady rather than urgent.
- npm wrapper. Only after the single-file artifact exists, and it must document that it installs a command, not a library.
Every channel is a support surface. A stale formula is worse than no formula, because it installs an old version silently. Nothing is added here without being published by the same automation as everything else — which is the real reason this is one ADR rather than thirty tickets.
A caveat worth stating plainly: vibey needs PostgreSQL and at least one
*loop engine on PATH to do anything. Several of these channels imply "install
and it works". The packaging has to be honest about that — a post-install note,
and vibey doctor already reports what is missing.