omarchy-pool
v0.0.186
Sign in

How it works

Packages come from the projects that build them, are verified against those projects' keys, stored once, and served in rings that only move forward on evidence. Nothing is rebuilt or re-signed; what changes is when a package reaches you and what was checked before it did. The pool verifies and validates — it does not choose whom to believe: no source, not Arch, not Omarchy, not the pool's own factory, reaches rc or stable on its name.

Arch Linux · x86_64core · extra · multilibarchlinux-keyringOmarchy (OPR) · bothpackages · the edge channelOmarchy's keychaotic-aur · optionalchaoticchaotic-keyringArch Linux ARM · aarch64core · extra · alarm · aurarchlinuxarm-keyringOmarchy for Apple Siliconasahi · aarch64 · the forkthe fork's keyAsahi Linux · aarch64asahi-alarmasahi-alarm-keyringVerifythe project's signatureagainst its keyringPoolstored once, immutable<source>/<arch>/<file>≤ 3 hedgefor CI, developersrcfor testersstablewhat you runa failed health check after a promotionpoints the ring back — automaticThe evidenceafter the sync that changed edge · every 3 ha real pacman -Sy + signed downloads, both archesthe ELF-level ABI check · no security regressiongreen on both architectures, or nothing movesminutes afterthe checks passtwo green checksin a row · ≈ 6 hFactorya contributor asks and buildsaudit · the project builds it againThe laba real pacman installs it — the trialnothing promised, nothing promotedA maintainer approvesnever their own packagewhat installed, not what compiledapproved→ edgethe fast lane: the trial installed it → stable with edge

Where every package comes from

Every three hours a sync reads each source's database, downloads what is new and verifies its signature against that project's keyring — a package that does not verify never enters. It is stored once, in the source's own directory (<source>/<architecture>/<file>): two projects' builds of the same file name are two objects in two directories, and the order of the sections in your pacman.conf decides which one you get, exactly as with any set of mirrors.

SourceProjectArchitectureSigned withEntersNote
coreArch Linux core — mirror.omarchy.orgx86_64archlinux-keyringedgethe released repositories; [testing] is not an input
extraArch Linux extra — mirror.omarchy.orgx86_64archlinux-keyringedgethe released repositories; [testing] is not an input
multilibArch Linux multilib — mirror.omarchy.orgx86_64archlinux-keyringedgethe released repositories; [testing] is not an input
packagesOmarchy (OPR), the edge channel — pkgs.omarchy.orgx86_64Omarchy's keyedgethe OPR's edge channel only; its rc and stable channels are not an input — the OPR earns rc and stable here like every other source
chaotic optionalchaotic-aur: prebuilt AUR packages (only names no other source provides) — builds.garudalinux.orgx86_64chaotic-keyringedgeon a machine only with --with chaotic
coreArch Linux ARM core — os.archlinuxarm.orgaarch64archlinuxarm-keyringedge
extraArch Linux ARM extra — os.archlinuxarm.orgaarch64archlinuxarm-keyringedge
alarmArch Linux ARM alarm — os.archlinuxarm.orgaarch64archlinuxarm-keyringedge
packagesOmarchy (OPR), the edge channel — pkgs.omarchy.orgaarch64Omarchy's keyedgethe OPR's edge channel only; its rc and stable channels are not an input — the OPR earns rc and stable here like every other source
asahiOmarchy for Apple Silicon: the fork's newest stable snapshot — github.com/maralcbr/omarchy-pkgsaarch64the fork's keyedgeabove the OPR in the include: on a Mac, its builds win
asahi-alarmAsahi Linux for Arch Linux ARM: kernel, graphics, firmware — github.com/asahi-alarm/asahi-alarmaarch64asahi-alarm-keyringedgeabove everything else, on a Mac
aur optionalArch Linux ARM's prebuilt AUR selection (only names no other source provides) — os.archlinuxarm.orgaarch64archlinuxarm-keyringedgeon a machine only with --with aur
factoryBuilt by the factory from contributors' recipes, built again by the project and decided by a maintainer (Factory)x86_64the pool's keythe lab, then edge on a maintainer's approvalpackages nobody ships yet
factoryBuilt by the factory from contributors' recipes, built again by the project and decided by a maintainer (Factory)aarch64the pool's keythe lab, then edge on a maintainer's approvalpackages nobody ships yet

What happens to a package

Five stages. Click one — the picture lights it up.

1. Sync — every three hours

The upstream database is read and compared with the index by sha256; only what is missing is downloaded. Each file is checked against the upstream checksum and signature, its .PKGINFO, dependencies, provides, file list and the sonames its binaries load are extracted, and the archive plus its .sig are stored in the pool under <source>/<arch>/<file>. A file is never stored twice and never modified.

2. Pin — edge

A sync that changed something makes a new edge release: an immutable list of exactly which objects the ring serves, one row per source, name and architecture. Releases are append-only; every ring has a history it can be pointed back to. Edge is what the sources published in the last three hours, signature-verified and nothing else — for CI and developers.

3. Promote — on evidence, never on a calendar

The sync that changed edge queues the evidence: a real pacman -Sy of the ring in a clean container on x86_64 and on aarch64, a signed download of a sample of every repository, the ELF-level ABI check of every upgrade the ring would apply to a reference system (on x86_64, an Omarchy installation), and the security layer's look for a regression. Green on both architectures, and edge is rc within minutes. rc is checked again every three hours; the second green check in a row makes it stable — about six hours after rc. Both architectures move together (one alone only by a maintainer's hand, when the other is red).

4. Render, verify, and roll back on your own

The ring's pacman databases (omarchy-<source>-<ring>.db and .files) are generated from the index, signed with the pool's database key and placed beside the packages. A promotion is followed by the same health check on the target ring; if it fails, the ring is pointed back at its previous release and re-rendered before you notice. A ring is a pinned selection: going back is an index write, no bytes move.

The lab and the trial

Beside the three rings there is a fourth, the lab, where nothing is promised: no sync targets it, no promotion comes from it or goes into it. It is where the factory's builds are tried before anyone decides — a real pacman installs them in a clean container from the lab above edge, and the transcript sits beside the audit — and where any package of the pool can be pinned to be tried in a combination. --ring lab on a machine puts the lab's sections above edge's.

The fast lane

A fix should not wait for a soak. A factory build the trial installed, and a security fix the security layer has confidence in, go to rc and stable with edge in the same step — recorded as a fast-track in the journal, with the reason. The fast lane is the evidence's, not anyone's to grant.

What protects you

Signatures, twice

Every package keeps its project's signature, and the pool verified it against that project's keyring when it entered. The pool signs the databases it renders with a key that never leaves the Worker; your pacman.conf trusts that key for the databases and the projects' keys for the packages. The pool cannot alter a package without breaking its signature.

A real pacman, before you

Every promotion is preceded by an actual pacman -Sy and signed downloads on both architectures in a clean container. The most common breakage — a database that does not sync, a package that does not verify — never reaches rc.

The ABI check

Every upgrade a ring would apply is checked at the ELF level against a reference system: a library that would leave a binary without the symbol version it needs blocks the promotion. omarchy-cli check runs the same check on your machine before an out-of-band install.

The security layer

The Arch and Debian security trackers, OSV, CISA KEV and EPSS, matched every three hours against what each ring serves; because the index knows what every binary loads, an advisory on a library also marks what uses it. A promotion that would replace a clean package with a vulnerable one is blocked; a confident fix is pulled forward. The Security page shows the ring, the package page the chain.

Immutable releases, automatic rollback

A ring never edits a release; it points at one. A failed health check after a promotion points it back — and the next pacman -Syu sees the restored release.

One rule between sources

Two projects' builds of one name both stay in the pool; the include's order — Asahi's above the OPR's above Arch's — is the only thing that decides, and it is written in your pacman.conf where you can read it.

Nothing skips the gates

Not the OPR, not the factory, not a maintainer's own package. The evidence is on the Pipeline page and in the journal, for anyone.

What a build can never touch

A build is somebody else's code — the recipe and the upstream's build system — and its log is public, on the API while it is in staging and on the record once it is staged. The rule, kept the same way on the project's host, a contributor's and a maintainer's: the build sees nothing the log cannot show — the public log is the proof, not the risk.

The broker

One process per host holds the credentials — the worker's token, the agent's key, a GitHub token — and only receives, processes and answers: the pool's calls for the one task it claimed, the agent, GitHub read-only. It runs no build. The project's review builds reach the agent the same way, through a proxy. What the broker holds →

The builder

Born with nothing but the broker's address, builds one task and dies. Inside it the build user starts from an empty environment; a variable set on it by mistake is dropped at start and said so. env in a PKGBUILD prints PATH and HOME. Run a worker →

The pool's check

For the worker the pool does not run: every log, recipe and report uploaded is read for what looks like a secret — the pool's tokens, agents' keys, GitHub's, a private key, a credential in a URL — and refused at the door with the kind and the line, never the match. The record never receives one. the security model →

Two words on a worker, a tombstone on a record

A worker becomes the project's on two maintainers' word, never its owner's alone; the Review page names the worker and host behind every build. A record is written once and can be withdrawn by a maintainer with a reason — a signed tombstone takes its place. The signing key itself lives inside the pool's Worker; no worker, runner or repository holds it. Workers →

What the pool does for the people who bring packages in, and the people who decide

for contributors

  • Ask for a package, on the record. A request is a signed record; the project's agent drafts a recipe from the project's sources.
  • Build it at home with the same tools. The same signed worker image, the same conventions, namcap, the same build — on your machine, with your compute. Your build is evidence, never the product: nothing you built is served to anyone.
  • A second pair of eyes before a human's. When your build is staged, the pool's agent audits the recipe, the log and the metadata and attaches a report beside it.
  • Watch it happen. Your workspace, your packages, your workers and every step of every build on the Factory and Review pages; the journal keeps the record.

for maintainers

  • The evidence in front of you. The contributor's build, the gate's verdict, the audit, the log and the recipe on one row — and Build by the project one press away. What the gate checks and what the agents are told is one page: What we test.
  • The project builds it again. A trusted worker with the project's own agent writes the project's recipe from the project's sources, learning from the contributor's evidence; the same gate runs; its own audit is queued.
  • The trial installs it before you decide. A real pacman installs the project's build from the lab in a clean container; the transcript sits beside the audit. You approve what installed, not what compiled.
  • Nobody decides on their own package — not even the only maintainer. A build the trial installed goes to stable with edge; one it did not waits for the gates like everything else.
  • A rollback is one job away, and so is every pipeline step by hand (pkg-repo job …), with a per-job token that can do that and nothing else.

How far behind upstream

RingBehind the sourceBecause
edge≤ 3 hoursthe sync's interval
rcminutes after edge's checks passthe health and ABI checks on both architectures, and the security layer
stable≈ 6 hours after rctwo green health checks in a row, three hours apart
a fast-tracked fixnoneit goes to stable with edge

Why one host is enough

Today an Omarchy machine talks to several repositories, each with its own mirror, cadence and failure modes. Here they are one set of databases per ring, generated from the same index, on both architectures — one section per source, in the order that decides.

before
[omarchy]
Server = https://pkgs.omarchy.org/$repo/$arch

[core]
Include = /etc/pacman.d/mirrorlist
[extra]
Include = /etc/pacman.d/mirrorlist
[multilib]
Include = /etc/pacman.d/mirrorlist
with the pool
[omarchy-packages-stable]
Server = https://pool.omarchy-pool.org/packages/$arch
[omarchy-core-stable]
Server = https://pool.omarchy-pool.org/core/$arch
[omarchy-extra-stable]
Server = https://pool.omarchy-pool.org/extra/$arch
[omarchy-multilib-stable]
Server = https://pool.omarchy-pool.org/multilib/$arch
# one host, a directory per source, both architectures;
# change "stable" to "rc" or "edge" to change rings;
# a section appears when the ring serves that source —
# the exact list for your ring and architecture is on Get started

What you trust

Two things, and only two.

The projects' own keys — unchanged

Packages are the exact files Arch, Arch Linux ARM, Omarchy and the Asahi projects built and signed. pacman verifies each package with the keyring you already have (archlinux-keyring, archlinuxarm-keyring, Omarchy's key, the Asahi keyrings on a Mac).

The pool's database key — one import

The pacman databases are generated here, so they are signed here — inside the pool's own service, by a key that never leaves it: no build worker, runner or repository holds it. That key signs the databases and the packages the factory builds, nothing else; its public part is in the repository, at the pool root and at /api/v1/signing-key, and with SigLevel = Required DatabaseRequired pacman refuses a database it did not sign.

The seal: where every package came from, with proof

A package from the AUR is a recipe someone maintains; a package from a distribution is a file its build farm signed. A package from the pool carries its provenance with it, and every package page shows it.

Imported

A synced package names its upstream project and repository, and the keyring its signature was verified against the moment it entered the pool — served as built and signed there, never rebuilt.

Built by the Omarchy Pool

A factory package carries the whole chain: the contributor's build that was the evidence (its worker, its agent, its log), the second agent's audit and verdict, the trial's transcript, the maintainer who approved it, the recipe the project built on a trusted worker. The chain is also written next to the object in the pool as an attestation — an in-toto statement about that exact file — with the pool's detached signature beside it, so anyone can verify it with the pool's public key and never trust this page.

On your machine

omarchy-cli info <package> prints the seal; omarchy-cli provenance prints one line per package, and as a pacman hook it says, after every install, where what you just installed came from. pacman -Qi shows it too: Packager: omarchy-pool factory, repository omarchy-factory-<ring>.

The pieces

All of it is open source (MIT), released when a maintainer dispatches a release, and shows its version in the header. The code's own documentation — architecture, runbook, testing — is in the repository, for people working on the pool itself.

PieceWhat it is
PoolA Cloudflare R2 bucket with a custom domain. pacman reads packages and databases from it as plain static files; nothing runs in front of them.
IndexA D1 (SQLite) database: one row per package object with its manifest, dependency edges, sonames; releases and ring heads; every event the pipeline records.
API + this siteOne Cloudflare Worker serving /api/v1 and these pages.
PipelineJobs the pool queues on its own clock and project workers pull: sync (every 3 h, one release per ring), the evidence and the promotion it earns (after every sync that changed edge; rc checked every 3 h), health, security (every 3 h), the trial of every review build, GC (weekly); a metrics snapshot every 30 min and the daily cost estimate by the pool itself. GitHub only releases the code, when a maintainer dispatches it.
FactoryThe build queue lives in the index (requests, tasks, leases); workers are containers anywhere — a contributor's laptop for their own packages, machines the project trusts for what maintainers approved — that claim a task, build it in a fresh Arch container and report; the pool signs what a project worker publishes. A lease that expires goes back to the queue.
Toolspkg-repo (the publisher: sync, promote, gate, trial, render, security, gc), pkg-extract (manifests), pkg-check (the ABI check), omarchy-cli (the thin client) — Rust, built for both architectures on every release.