omarchy-pool
v0.0.186
Sign in

Governance

Two roles, one file, decisions by pull request. Anyone who signs in with GitHub is a contributor: requests packages, runs workers on their own machines, follows their builds — nothing to ask, nothing spent by the project. The logins listed in factory/MAINTAINERS.toml are the maintainers — one list, no areas: every maintainer reviews everything. Nobody is above that — no owner, no superuser, no API that grants a role: the project belongs to its maintainers and contributors, the pool reads the file on main every ten minutes and applies it, and every change is a role line in the journal. This is a community pool: nothing in it is official Omarchy, and no package here is endorsed by the Omarchy project.

The maintainers

Read live from the pool, which read factory/MAINTAINERS.toml on main .

MaintainerSince

We do not use what you built, we learn from it

A contributor uses exactly the tools a maintainer uses — the same signed worker image, the same PKGBUILD conventions, namcap, the same build — to produce a package that respects the packaging practices, is checked for quality and is safer for users. An AI agent may help: nobody knows better than the author how their software should be compiled and packaged, and an agent turns that knowledge into a recipe faster. The agent's key is the contributor's, on their machine; the project runs no agent for them.

Nothing the contributor built is ever used — not the package, not the recipe. The maintainer does not trust it and must not. What they have in front of them is not "some software, go package it" — it is a recipe that already built, its log, its manifest, the gate's transcript, the second agent's audit, the corrections made along the way. Evidence. A maintainer (never the owner) reads it and has the project build the package again: on a worker the project trusts, with the project's agent, which gets the request and that evidence as the lesson and writes the project's own recipe from the project's sources — through the same gate, staged like any build, installed by a real pacman in the lab (the trial), its evidence on the record. Then a maintainer approves the project's build, and only that goes into the pool, signed. The pool enforces the line: a contributor's build cannot be approved (the API says so), a worker refuses to start from a staged artifact, and the project's build carries review:<task> — where it learned, never what it copied.

Zero trust between people, shared knowledge between them. Users get a package at least two different people stood behind — the contributor who made it work, the maintainer who had it built again and attested it — built twice, on two workers, by two agents, and never the first one.

The second agent. The contributor's agent, if any, wrote the recipe; the maintainer's side has one too. When a build is staged the pool queues an audit — a job a review worker takes only if its owner set an agent key. It reads the same evidence the maintainer will — the PKGBUILD, the build log, the .PKGINFO — asks its model for a structured review (supply chain, security, packaging practice, correctness against the log, licence) and attaches audit.json and audit.md to the evidence. Review shows the verdict next to the build: ok, warn (approve with the findings in mind), block (do not approve as is). Evidence, never a decision: nothing in the pool acts on it, the maintainer does. The builder cannot write those two files, the audit cannot write anything else, and a build decided before the audit ran cancels it. No review worker with a key, no audit: the column says waiting.

What each role does

Categories, not groups

There are no groups: no package belongs to an area whose maintainers own it, and no maintainer reviews only a part of the pool. What a package is about — for a person browsing — is its category, one of a fixed list: terminal, editors, development, browsers, communication, media, graphics, office, games, system, networking, security, fonts, themes, libraries, other.

The project's agent proposes it

When it audits a staged build it names a category in its report, from the description, the upstream project and what the package installs. The registration takes the proposal only while nobody settled one (a category line in the journal says so).

A maintainer settles it

On the Review page, under the package name, or with POST /api/v1/factory/packages/<name>/category — at review, or any time after; the change is a category line in the journal with who and from what. A settled category is never overwritten by a later audit.

It travels with the package

The registry, the package page (who stands behind it), the profile's package list and the seal carry it. It says where to look, never who may approve. The repository holds no package recipes: every package is a request on the record, built by the pool — since 2026-09-17 nothing about a package goes through a pull request.

Becoming a maintainer

1. Contribute first

Every maintainer was a contributor: packages registered, builds staged, reviews taken part in. Sign in, and the record of what you did is public on the Factory page and your profile.

2. A maintainer proposes you

A pull request adding your login to factory/MAINTAINERS.toml, saying why. It is a decision people make, not a database write.

3. Another maintainer approves

main takes pull requests only — green checks, squash, and one approval that GitHub never lets be the author's own — so at least one other maintainer approves, and the file (and CODEOWNERS, generated from it) asks for a code owner's: every maintainer is one. A maintainer reviews and merges what another opened; nothing is auto-merged. The merge is the promotion: within ten minutes the pool applies it and the next sign-in shows the role. A maintainer stepping down is the same pull request with the same review; factory/bin/check-governance --write regenerates CODEOWNERS, and CI fails when the two disagree.

Bootstrap, and the one door left

While the project had a single maintainer there was nobody else to approve the pull request that adds the second one: that maintainer merged it alone, and GitHub recorded the bypassed review (2026-09-17). The exception never extended to packages — a sole maintainer's own packages waited. What remains is the repository's admin, who can merge a pull request alone: GitHub writes bypassed on that pull request for everyone to see, and the project's rule is that it never happens to this file.

Workers, compute and agents

One image, one command, for everyone

ghcr.io/firemanxbr/omarchy-worker. There is no technical difference between a contributor's container and a maintainer's; the registration behind the token decides. Community trust (every registration starts here) builds the owner's packages and never sees a package in review; project trust — two maintainers' word on the registration, never its owner's — runs the pool's jobs and the rebuild of approved packages. A maintainer who also contributes registers a second, untrusted worker. Run a worker →

The project's workers, in three roles

Machines two maintainers vouched for — one proposes, another confirms, the trust a signed record, one maintainer enough to take it back. They only do what a maintainer would: a pool worker takes the pool's jobs (sync, promote, health, security, the trial, gc) and nothing else; a review worker takes the maintainers' work and nothing else — the build of the recipes maintainers merge and the audit of every staged build; a shared community worker builds contributors' packages and drafts package requests with an agent key its owner brought. They never build from a contributor's staged artifact, and never pull a new package that has no evidence and no review yet — that is a contributor's worker's job. The Review page names the worker behind every build.

Yours — or everyone's, if you say so

A registered worker builds its owner's packages; started with WORKER_SHARED=1 it also takes the shared queue — every request lands there the moment its record is written, and the best idle shared worker of the architecture builds it first. Sharing is the owner's word alone: their machine, their agent's key, strangers' recipes in a fresh container each time, evidence only — nothing a shared worker builds reaches the pool without the project's own build and a maintainer's decision. Nobody's laptop is shared by accident.

Ready is not online

A worker is ready for the work it declares when it is alive and what that work needs answers: a build or an audit needs an agent that replies. A key set is not an agent that works — no credit, a revoked token, a dead endpoint, a retired model — so the worker probes its agent at start and every thirty minutes, and says so with every claim. The pool hands a draft or an audit only to a worker whose agent answered; the pool's own jobs need no agent.

Agent keys stay with the worker's owner — and out of the build

A worker that drafts or corrects PKGBUILDs with an agent (community trust), or audits staged builds for the maintainers (project trust), gets the owner's key — ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, XAI_API_KEY or a Claude subscription's CLAUDE_CODE_OAUTH_TOKEN — on the broker, the one process on the host that holds credentials and runs no build; the builder is born with nothing and speaks to it. The worker reports which agent really answers so the Workers page can show it. The pool holds no agent key and GitHub runs no agent — nothing of the pipeline runs there. A build is somebody else's code and its log is public: the build sees nothing the log cannot show, and the pool refuses a log that carries what looks like a secret.

Package requests

Made on the dashboard (the request page: the project's URL, a description, the licence, the checklist — written once to the public record). The build starts by itself, in the shared queue: the best idle shared worker of the architecture takes it first — anyone's, with its owner's agent — and the contributor's own worker at once. No ready worker, no draft: the request waits in the queue, visibly, with its place, on the contributor's page.

Bumps and packages nobody builds

A new upstream release of an approved package is built the way the first version was — on the owner's worker, as evidence a maintainer reviews. Once a day the pool queues that build (bump:<task>@<tag>: the contributor's staged PKGBUILD with pkgver moved to the tag; evidence again, never the product). The owner's worker has 14 days; after that any shared worker may build it. 30 days without a build and the package is unmaintained: no more bumps until its owner builds again — or someone else requests the name and takes it over, the package still served until their build is decided; a maintainer who removes the registration takes the package out of every ring with it, on the record. There is no other path: nothing about a package goes through a pull request.

Blocking

The brake. It is on the Review page, The brake, and in the API; it takes a maintainer and a reason, and the reason is what the record and the contributor see.

A contributor

POST /api/v1/factory/contributors/<login>/block. Nothing more in: no package request, no build, no worker registration — the pool answers 403 with the reason. Their workers are revoked at once, their queued and running tasks cancelled, their registrations rejected and their packages pulled from every ring. Their projects and source URLs stay closed: a new account asking for the same project gets 403 requested by <login>, who is blocked — a fresh login does not open the door again. A maintainer cannot block themself or another maintainer; the latter is a governance pull request removing the name from the file.

A package

POST /api/v1/factory/packages/<name>/block. Out of every ring the same way, its tasks cancelled, its registration rejected; the project URL answers 403 to any new request until the block is lifted.

Lifted by another maintainer

…/unblock, a reason again — never the one who blocked, the same two-person rule as the approval. Lifting restores nothing: workers register again, packages are requested again, and everything goes through the gate and the review as if for the first time. Every block and every lift is a signed record in the public bucket with who, when and why; GET /api/v1/factory/blocks lists what is in force.

The record and the score

Role changes are role lines in the journal, approvals are rows a maintainer signed with their login, trust decisions are trust lines, blocks and their lifting are signed records in the public bucket. The file's history on GitHub is the history of who decided what.

Track record. A profile sums that record, so it says how much work a person has done here — not who they are. As a contributor: distinct packages a maintainer let in, builds that produced evidence, of which bumps, builds their workers did for other people, rejections. As a maintainer: approvals, rejections, and approvals whose project build then failed. One number, so that the formula is public and dull: 3·let in + staged + bumps + for others − 2·rejected + 2·approvals + rejections − 3·builds failed. No rank, no badge, no threshold; becoming a maintainer is still a pull request another maintainer approves, with this record as one thing they look at.

WhenWhat