How nfltr Works

Draft

This page is a draft for review.

nfltr runs Claude Code agents on machines you own and lets one Claude session, the hub, coordinate them. The machines meet on a relay: the hosted one at nfltr.xyz, or your own relay (beta). This page explains the parts, the flow of one goal, what each machine controls, what the relay can and cannot see, which reliability guarantees hold and how they are tested, and the limits today.


The parts

The parts of nfltr At the top, the hub: your terminal or your own Claude Code session, which decides. Below it, the relay, nfltr.xyz or your own, which carries messages and runs no model. The hub and two nodes connect out to the relay. The first node, a laptop, runs two Claude Code agents. The second node, a build server, runs one agent and keeps a repository mirror. Agents clone through their node and push their branches to your git host at the bottom. Hub your terminal or Claude Code: decides connects out Relay nfltr.xyz or your own: carries, no model connect out Node: laptop Agent (Claude Code) Agent (Claude Code) Node: build server Agent (Claude Code) Repository mirror clone, push Your git host
The hub and the nodes connect out to the relay. Agents run on nodes and clone and push to your git host directly; code does not go through the relay.

The flow of one goal

  1. Join. Each machine joins once: nfltr node join --max-agents 4, with the repositories and tools you allow (Nodes guide).
  2. The hub sees the machines. When you give the hub a goal, it lists your nodes with their facts: free agent slots, CPU cores, load and memory, the repositories each allows, and the description and resources you gave the machine. nfltr orch nodes list shows you the same list.
  3. The hub spawns agents where the data and tools are. It chooses how many agents, on which machine, with which model and which instructions. A node starts an agent process only then.
  4. Agents work. An agent clones through its node's local mirror of the repository (refreshed from your git host before it serves, so it never sees stale branches), works in its own directory, and pushes its branch to your git host itself.
  5. Results come back. Each agent's answer, branch and commit reach the hub as a completion, once.
  6. The hub decides what is next: continue an agent with a follow-up, start more, stop one, check the work, or finish and answer you.

Provide, don't decide. nfltr provides the machines, their facts, the messages and the results. It never decides for the hub: it does not pick a machine, a model or an effort when the hub leaves one out, it does not retry a failed agent, and it does not merge or land code. Those choices belong to the hub, which is Claude, and through it to you.

What each machine controls

A node offers only what its owner turns on when it joins. The hub cannot widen it.

ControlHow
How many agents--max-agents (required): the most agent processes it runs at once.
Tool permissionsRestricted by default: agents only edit files. --allow-all-tools lets them run commands (shell, tests, pushes) without approval.
Tool rules--tool-policy-file: deny rules checked before every tool call (for example, no force push).
Approvals signed by the ownerA rule marked "unless approved" is lifted only by a grant you sign on your own device, bound to this node and one prompt, and expiring. The node holds only your public key (--approval-public-key, from nfltr orch hub approval-key).
Repositories--allow-repo patterns (with --allow-all-tools): only these get a mirror and git credentials that answer for them alone. A spawn naming another repository goes elsewhere.
Which hubs it serves--serve-hubs: agents only for the listed hub ids. It narrows which of your hubs use the machine; it is not a security boundary between machines of one account.
A clean Claude configBy default agents run without your Claude Code settings, hooks, memory, plugins or MCP servers, and isolated from your other Claude sessions. --inherit-host-claude-config opts in.
Git identityThe node passes on the commit identity you configured in git. If you configured none, it sets none; it never invents one.
Your account keyAgents never get the node's account key unless you pass --agent-relay-access.

What the relay can and cannot see

Always visible to the relay: your account, machine names, labels and capabilities, which machine connects to which and when, and the size and timing of traffic. Never sent to it: your git credentials and Claude tokens (they stay on your machines) and your approval signing key. It stores your API keys only as hashes.

FeatureWhat the relay sees
Hub runs (agents, turns, results)Nothing: the hub sends the relay no summary or status of its runs and refuses the relay's own requests for them, so the dashboard shows none. They stay on the hub's machine (nfltr orch hub runs, nfltr orch hub show); the relay sees only whether the hub is online.
Hub ↔ agent messages (assignments, prompts, results)Encrypted end to end between the hub, nodes and agents by default. With the same pairing key on every machine (--e2ee-key-file), a relay that swaps keys is refused.
Answers from your phone (remote messages)Encrypted end to end between your paired device and the hub; the relay stores and forwards ciphertext. Approvals also need your passkey.
nfltr p2p files, chat and callsEncrypted end to end on every path, including when the data falls back through the relay or a TURN server. The relay sees the two machines, the kind of session, direct-connection addresses, and sizes and timing; not file names, contents, chat or call setup. Both machines print a session fingerprint: if they match, nothing in between swapped the keys. With a pairing key, a swapped session is refused.
nfltr wg (private LAN)WireGuard is end to end between the client and the exit; the relay forwards sealed packets. Against a relay that substitutes keys it holds only with a pairing key (--e2ee-key-file).
nfltr http (tunnels and their share links)Encrypted end to end by default: TLS ends on your machine. Readable at the relay only in inspectable mode (--mode inspectable), which features that read requests at the relay need, such as routes.
nfltr tcp (raw TCP tunnels)Readable at the relay, unless the protocol inside is encrypted (SSH is).

Reliability guarantees and how they are tested

Each guarantee below is checked automatically. The checks run against real relays, nodes and hub processes; most use a scripted stand-in for Claude Code so they can run often at no model cost.

GuaranteeHow it is tested
If the hub process dies or your terminal closes, starting it again with the same hub id delivers every result it missed, exactly once.Fault injection: soak runs and a Kubernetes chaos lab kill the hub mid-run and reattach it. A production canary checks exactly-once delivery against nfltr.xyz.
A turn the hub sent runs once and has at most one accepted result. A send that could not be confirmed is never sent again; the hub asks the machine instead.Linearizability checks of the task stores under concurrent owners, crashes and lease expiry; an audit of every recorded event history after each soak and chaos run.
A relay restart or deploy does not end running agents. Everyone reconnects; agents keep working and deliver their results when the relay is back.Fault injection: soaks and the chaos lab stop and kill the relay at random points of a turn.
Stopping a node gracefully (Ctrl-C or SIGTERM) reports its running agents as lost to the hub right away. A killed node is reported within about half a minute.Fault injection soaks that stop, kill, freeze and rejoin nodes; every turn must end within a bound.
Continuing a finished agent keeps its work: it restarts on the same machine with its directory, uncommitted files included, until the hub archives it. A node restart clears those directories, so only pushed work survives that.End-to-end tests of continuations on the same and on another process.
An agent process that is leaving never takes a new turn and never loses one: the turn is refused before it starts and the hub places it elsewhere.A test against a real relay of a dispatch racing the exit, and a load test that fails on any lost turn.
Every turn ends: completed, failed, cancelled, or reported lost.Long soaks with random faults; the history audit checks a liveness bound.

Where it runs

Limits today

Next