Skip to content

About

Hive contributor appliance: upstream Hive's contributor runtime packaged as an isolated distroless image, driven by OMP

Resources

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

hive-contribute — Contributor Appliance

Upstream Hive's contributor runtime packaged as an isolated, distroless container, driven by OMP.

This appliance packages Hive's contributor runtime (contributor-agent.sh + contributor-relay.js) with OMP as the agent CLI, so a contributor needs no agent toolchain of their own. Hive owns task selection, assignment, prompts, leases, and output capture; OMP owns agent execution, model choice, thinking effort, and tool boundaries. This repository owns the isolation boundary, the credentials that cross it, and the single configuration file.

The Hive runtime inside is tracked directly from upstream's v5 branch and is never pinned to a static commit in this repository. Every image build resolves the branch to a commit, stamps it into /usr/share/hive/contribute/HIVE_COMMIT, records it in the image labels (io.hivecommons.contribute.hive.ref) and SBOM, and registration clones that same branch, so setup and runtime follow one release line. They are not pinned to the same commit: setup reads v5 live while the image carries the SHA resolved when it was last built, so they can differ. The daily rebuild is meant to bound that gap, not to guarantee it.

Workflow

# Run the worker in the foreground (Ctrl-C stops it)
hive-contribute

# Or through just from a checkout
just contribute

Supported Platforms

hive-contribute requires a Linux host environment. Both isolation tiers (KVM microVMs via krun and standard Podman containers) rely on Linux kernel facilities (/dev/kvm and unprivileged user namespaces). macOS and Windows hosts are supported by running inside a Linux virtual machine.

Host Support Provisioning Command
Linux Native Direct execution (requires Podman; /dev/kvm recommended for krun hardware isolation)
macOS Linux VM via Lima limactl start (or install via brew install lima && limactl start), then run inside the VM
Windows Linux VM via WSL2 wsl --install (e.g., Ubuntu distro), then run inside the WSL2 distro

On macOS and Windows, provision the Linux VM, install Podman and the required prerequisites inside the guest, and run hive-contribute from within that environment. Native execution directly on macOS or Windows command prompts is not supported.

Installation

Install hive-contribute onto your PATH or run directly from a checkout.

From a repository checkout:

git clone https://github.com/projectbluefin/contribute.git
cd contribute

The launcher executable is bin/hive-contribute. You can symlink or copy it to ~/.local/bin/hive-contribute (or anywhere on your PATH).

Commands

The launcher is bin/hive-contribute:

Command Description
hive-contribute / hive-contribute run Launch the worker in the foreground (Ctrl-C stops it)
hive-contribute hives Pick which hives to contribute to (interactive; applies to a running worker immediately)
hive-contribute switch [name] Pick which followed hive the worker asks first (applies immediately)
hive-contribute doctor Read-only preflight diagnostics; starts no agent
hive-contribute setup Register this machine with a hive through upstream's own setup
hive-contribute config Print the resolved appliance configuration

From a checkout, just provides thin wrappers: just contribute, just hives, just switch, just doctor, just setup, just config, and just contribute-build.

Contributing to several hives

Run hive-contribute hives. It lists the hives you already follow (ticked), the hives Hive knows your GitHub account by, and every online hive in the Commons registry. Tick a hive with x (or Tab) — not space — and press Enter; it registers the newly ticked ones and drops the ones you untick. A dropped hive's token cannot be recovered, so it asks first. A self-hosted hive that is in no list is the last row: tick it and type its address once, e.g. reef.tunaos.org (a full wss:// URL also works); it is checked to answer as a Hive hub before anything registers, and it is an ordinary tick from then on. With more than one hive it also asks which one the worker asks first and how it chooses between them (ranked, spread, or neediest). hive-contribute switch changes only the first hive. If any choice does not take effect, it says which and exits non-zero.

Nothing needs editing by hand, and a running worker picks every change up without a restart. Every change goes through upstream's hivectl hives: the profiles live in ~/.config/hive/profiles.yml, and contributor.env is generated from them. The launcher fetches hivectl from Hive's newest v5 release image through upstream's own bootstrap the first time you use it. hive-contribute hives <args> passes any other hivectl hives subcommand straight through, for example hive-contribute hives list or hive-contribute hives rename <old> <new>. The pickers use gum when it is installed and plain numbered prompts otherwise.

Configuration

All site configuration lives in one file: ${XDG_CONFIG_HOME:-~/.config}/hive-contribute.yml

The launcher creates it on first run, seeding hub from an existing ~/.config/hive/contributor.env if present. You can point HIVE_CONTRIBUTE_CONFIG at another path to run a second configuration.

The configuration has nine flat keys:

# hive-contribute — the whole appliance configuration.
#
# hub          the hive this machine contributes to (wss://<host>/contribute)
# registration Hive's own credential file, written by its contribute-setup
# image        contributor runtime image to run
# backend      agent CLI Hive drives inside the container
# memory       RAM ceiling for the worker (also the microVM's size); none = no limit
# cpus         CPU ceiling for the worker (also the microVM's vCPUs); none = no limit
# llmman       OpenAI-compatible base URL of YOUR llmman daemon; empty = cloud only
# llmman_token file holding that daemon's API key (0600); empty = unauthenticated
# llmman_model model the daemon must serve; 'doctor' checks it is loaded there
hub: wss://hive.example.org/contribute
registration: ~/.config/hive/contributor.env
image: ghcr.io/projectbluefin/contribute:stable
backend: omp
memory: 4g
cpus: 2
llmman:
llmman_token:
llmman_model:
Key Meaning Default
hub The hive WebSocket endpoint to join (wss://<host>/contribute) Seeded from registration or set via setup
registration Path to Hive's credential file ~/.config/hive/contributor.env
image Contributor runtime image reference (registry location) ghcr.io/projectbluefin/contribute:stable
backend Agent CLI Hive drives inside the container omp
memory RAM ceiling, swap pinned to it; none removes it 4g (upstream's contributor envelope)
cpus CPU ceiling; none removes it 2 (upstream's contributor envelope)
llmman OpenAI-compatible base URL of your own llmman daemon empty — the worker uses cloud providers only
llmman_token File holding that daemon's API key empty — the endpoint is contacted unauthenticated
llmman_model Model the daemon must serve, verified by doctor empty — doctor lists what is served instead

memory and cpus are enforced on Podman runs, where they size the microVM.

Warning

WSL2 credential-mode hazard: When running under WSL2, keep registration: on the Linux filesystem (e.g., ~/.config/hive/contributor.env), never on a Windows drive mount (such as /mnt/c/...). Windows DrvFs mounts do not preserve Linux file modes (0600) without explicit metadata configuration, silently exposing the contributor registration credential.

Isolation Model

Every worker invocation runs inside an isolated container:

  • libkrun microVM preferred: When Podman, krun, and /dev/kvm are available, the launcher starts a hardware-isolated KVM microVM (podman run --runtime=krun). When KVM is unavailable, it runs standard Podman containers.
  • Read-only credential mount: Each worker gets a private copy of Hive's 0600 registration in a launcher-owned directory under $XDG_RUNTIME_DIR, mounted read-only at /home/hive/.config/hive. hive-contribute hives and switch replace that copy and signal the worker, whose relay reloads its hive list; the copy is removed when the worker stops. In WSL2 environments, keep the registration on the Linux filesystem rather than a /mnt/c mount to preserve the 0600 permission mode.
  • No host home mount: The user's host $HOME is never mounted. The container runs as unprivileged user hive (uid/gid 65532) with its own isolated home volume.
  • Foreground attach: The container remains attached to the terminal in the foreground. Detached runs are unsupported; Ctrl-C stops the invocation cleanly.

Credential Model

  • GitHub identity: Passed by environment as GH_TOKEN (resolved from $GH_TOKEN, $GITHUB_TOKEN, or gh auth token). Host ~/.config/gh is never mounted into the container.
  • The hives lookup uses your token off-GitHub: hive-contribute hives (and switch, for labeling) asks the Hive Commons directory at https://hive.hivecommons.dev/api/saas/my-hives which hives know your GitHub account, authenticating that one request with your github.com token as a bearer header — the same lookup upstream's contribute-setup picker performs. The token rides stdin, never the command line, and the flow says so before it happens. If you do not want your token sent there, skip hives and type the hive's address directly.
  • gh is Hive's, not raw: Inside the container, gh is upstream's gh-wrapper.sh with the real binary at /opt/hive/bin/gh-real, and contributor mode is a root-owned marker file the agent cannot forge. An assigned task cannot run gh auth, cannot issue a mutating gh api, and cannot reach any subcommand outside Hive's allowlist; read-only lookups stay available, and created issues and PRs are labelled contributor/<login> and cli/omp.
  • Provider keys: Only allowlisted provider environment variables (COPILOT_GITHUB_TOKEN, ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY, AWS_BEARER_TOKEN_BEDROCK, etc.) are forwarded.
  • Credential validity is Hive's: The hub issues and rotates registration tokens, and its relay is what authenticates one. This launcher mounts the credential and nothing more — it does not validate, reissue, or relaunch on a rejected token. Repair a rejected registration with upstream's contribute-move.

Local Inference (Bluefin Agent Mode / llmman)

Bluefin's Agent Mode runs llmman as a rootless user service bound to the host's loopback address, which an isolated container cannot reach by default. The appliance can run its assigned work against that daemon — but only when you explicitly select it.

Local inference is off until you select it. With llmman empty, the launch is byte-for-byte what it was: whatever cloud provider keys you have configured, and nothing else. Writing an endpoint into the config file is the selection:

llmman: http://127.0.0.1:17434/v1
llmman_token: ~/.config/llmman/api.key   # optional; 0600
llmman_model: qwen3-coder-30b            # optional; verified by doctor and selected in OMP

Then check it before you run a worker:

hive-contribute doctor

doctor reports the endpoint and the transport, reads the key, and makes one read-only GET of the OpenAI-compatible model list — so reachability, authentication, and whether llmman_model is actually loaded are all answered before an assignment arrives, not after one fails.

What crosses the isolation boundary when local inference is selected:

  • The transport: For a loopback endpoint, the run adds --network slirp4netns:allow_host_loopback=true, which makes the host loopback reachable from the container at 10.0.2.2. Important: allow_host_loopback=true exposes the entire host loopback interface (127.0.0.1) to the worker at 10.0.2.2, not just the llmman port. Operators should consider what other services are listening on 127.0.0.1. A routable network endpoint is passed through unchanged with no custom network mode. Either way, the appliance publishes no ports of its own and starts no listeners.
  • OPENAI_BASE_URL, by value — it is an address, not a secret, and a recorded one is how you prove afterwards which endpoint the worker used.
  • OPENAI_API_KEY, by name, holding the contents of llmman_token. It is never written into the image, never placed on a command line, and never read from a mounted host home. With no llmman_token, the appliance sends its own placeholder rather than your cloud OpenAI key — an endpoint of your own does not get a credential minted for someone else.
  • Model selection: When llmman_model is configured, it is passed into the appliance and configured as OMP's default model selection (openai/<model> and llmman/<model>). The OpenAI provider slot is repurposed for the local endpoint, while other configured cloud providers (Anthropic, Gemini, Copilot, Bedrock, OpenRouter) remain available.

Donating worker capacity is not llmman peer aggregation

Two different things share the word "local", and this appliance does exactly one of them:

  • Donating worker capacity (this repository): you run the contributor appliance, Hive assigns it work, and with llmman set that work is inferred on your own machine instead of a cloud provider. The appliance is a client of the endpoint you named.
  • llmman peer aggregation (llmman's own feature): one machine consumes another machine's llmman daemon over the network. That is configured in llmman with llmman config set, it is not something this launcher does, and nothing here advertises your daemon as a peer or opens it to the LAN.

If you want your workstation's GPU to serve your laptop, that is llmman's aggregation, configured in llmman. If you want Hive's assigned work to run on hardware you own, that is the llmman key above.

Upstream Tracking (Never Pinned)

The Hive contributor runtime inside the image is never pinned to a static commit. The build resolves the upstream v5 tracking branch, packages the resolved runtime assets, and stamps the commit into:

  1. /usr/share/hive/contribute/HIVE_COMMIT inside the image
  2. The OCI image label io.hivecommons.contribute.hive.ref
  3. The image SBOM at /usr/share/hive/contribute/sbom.spdx.json

hive-contribute setup clones that same upstream tracking branch during registration, ensuring registration protocol and container runtime stay synchronized.

Third-party release binaries (OMP, Node.js, GitHub CLI, tmux) remain digest-pinned and tracked via Renovate.

Quick Start

hive-contribute

That is the whole flow. On a machine with nothing configured it writes its config, hands off to upstream Hive's contribute-setup to pick a hive and register, records the hub it registered against, and starts the worker. Choose provider, model, and reasoning effort inside OMP.

First run needs a host toolchain, because registration is upstream's and runs on the host: just, gh, git, curl, jq, and node. The launcher names any that are missing before it touches the network or a credential. Log in to GitHub first, since upstream's setup reads that identity:

gh auth login --web --hostname github.com --scopes repo,read:org

Once a registration exists, the setup tools (just, git, curl, jq, node) are needed only to register again; hive-contribute hives uses gh, git, curl, and jq. Every run still needs a container runtime — Podman with krun — and a GitHub token, either from gh or exported as GH_TOKEN.

If something is wrong

hive-contribute doctor     # read-only preflight; starts no agent
hive-contribute setup      # re-run registration through upstream on its own
hive-contribute config     # print the resolved configuration

Image Reference

The default contributor runtime image is published to GitHub Container Registry at ghcr.io/projectbluefin/contribute:stable (used here as a container registry location). Build locally with:

just contribute-build

Running directly with Podman

To run the container directly with podman (preserving host access to the 0600 registration file):

podman run --rm -it \
  --userns keep-id:uid=65532,gid=65532 \
  -v ~/.config/hive/contributor.env:/home/hive/.config/hive/contributor.env:ro,z \
  -v hive-home:/home/hive:rw \
  -e GH_TOKEN \
  ghcr.io/projectbluefin/contribute:stable

A direct run reads the registration once: after hive-contribute hives or switch, restart it. Only launcher-started workers get the staged copy that changes live.

Running with Docker

For environments using Docker, map your host user ID and bind-mount a dedicated host-owned directory for /home/hive so the container process can read the 0600 registration file and write to its home and workspace:

mkdir -p ~/.local/state/hive-contribute/home/{.config/hive,workspace}

docker run --rm -it \
  --user "$(id -u):$(id -g)" \
  -v "${HOME}/.local/state/hive-contribute/home:/home/hive" \
  -v "${HOME}/.config/hive/contributor.env:/home/hive/.config/hive/contributor.env:ro" \
  -w /home/hive/workspace \
  -e GH_TOKEN \
  ghcr.io/projectbluefin/contribute:stable

Guides

Licensed under Apache 2.0.

About

Hive contributor appliance: upstream Hive's contributor runtime packaged as an isolated distroless image, driven by OMP

Resources

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages