Your runs stay on your machine

A record of what your agents did, their briefs, answers, branches and events, says a lot about your code and your machines, so where it is kept and who can read it matters. nfltr connects machines through a relay they dial out to, and nfltr orch runs Claude Code agents on your own machines, driven by a hub that is your own Claude Code session. A run is what a hub does with a goal: the agents it starts, each agent's turns, their answers, branches and events. The question was whether the dashboard on nfltr.xyz should show those runs, which means the relay reading them.

What we found and decided: every way of showing runs on the dashboard needed run facts in the relay's hands in plaintext, and the bridge it used made an end-to-end encrypted hub look offline. So since v1.0.689 and v1.0.690 the dashboard no longer shows runs. Its Runs view is a pointer to the hub, which keeps its runs on its own machine and shows them there, and hubs stay strictly end to end encrypted. This post covers how runs were shown before, the design we built first and why we dropped it, the principle behind the decision, where runs are seen now, and what it costs: no run history across machines in the browser.

Runs after the relay split

Since v1.0.682 the relay keeps no task state; the story is in Three programs and a relay with no orchestration inside. Before that, the relay held a digest of every hub's tasks for the dashboard. After it, the dashboard's Runs view read each hub live: the relay's own agent asked every online hub for its rows through a bridge on the relay.

That left two gaps. With no hub running, Runs was empty and did not say why. And a hub's past runs disappeared from the dashboard once the hub exited, although they were still on the hub's machine, in its state file and task store.

A first design: history served by the node

The first fix kept the dashboard as the place to see runs. The Runs view explained why it was empty, and nfltr node served the past runs of its machine's stopped hubs to the dashboard. It did this on a relay connection of its own, with every row passed through the same status-only allow-list the hubs used for the dashboard, and it answered only the relay's own agent. That commit was never released.

The finding: an encrypted hub looked offline

Testing it showed a problem with the live half, not only the history. Hubs talk to their callers over end-to-end encrypted A2A by default, and an encrypted end refuses plaintext requests. The dashboard bridge is plaintext by construction: it is the relay's own agent asking. So a running hub refused it, the relay answered the dashboard with a 502 and the reason AGENT_OFFLINE, and a hub that was connected and working looked offline.

The history server had the same shape. To answer the dashboard, it needed a connection without end-to-end encryption and served run facts, filtered but readable, to the relay. Every way of showing runs on the dashboard came down to the same thing: run facts in the relay's hands, in plaintext.

Two options

OptionWhat it meant
A narrow plaintext read pathAn exception that lets an encrypted hub answer the relay's dashboard reads, limited to an allow-list of status fields, plus the node's history connection. The dashboard keeps a Runs view across machines; the relay sees those facts for every running hub.
Hubs strictly end to end encryptedNo plaintext path to the relay at all. Runs are seen in the hub and on its machine; the dashboard shows none.
Two other ideas were rejected outright: run summaries kept on the relay, and a nfltr orch task that silently falls back to local files when no hub is online.

The principle: data, access and control stay with the user

We chose the second option, on one principle: move as much as possible to the user, meaning the data, the access to it and the control over it. A run is the user's data. The hub that made it runs on the user's machine, so that machine is where the run belongs, readable by the user and not by nfltr.xyz. A narrow plaintext path would have been small, but it would have been a standing exception to the encryption every hub promises, on every running hub.

What changed in v1.0.689 and v1.0.690

  • The dashboard's Runs view is a pointer. It reads no hub content and makes no request to a hub. It says where runs are and lists the commands below. The task list, the task drawer, the event tail, the status badges and the task controls went with it. The dashboard keeps what the relay itself knows: machines, nodes and which agents are connected.
  • The history server is gone, along with its flag and its plaintext relay connection.
  • The hub's dashboard flags are gone. --dashboard-digest, --dashboard-digest-git and --dashboard-commands are removed from nfltr mcp, nfltr orch and nfltr orch hub, with their environment variables and the status-only allow-list they served. There is no compatibility path.
  • A hub refuses every task request from the relay itself, reads and controls alike. This is fail closed: without that check, the relay's bridge would be served as if it were the owner. Your own nfltr orch task requests are unchanged.
  • The hub side gained two commands, nfltr orch hub runs and nfltr orch hub show, which read the hub's own files on its machine.

Where runs are seen now

  • In the hub session, your Claude Code session with the hub MCP (claude mcp add nfltr -- nfltr mcp --toolset hub): ask the hub. Its list_agents tool lists its agents and wait_for_agents returns their outcomes.
  • On the hub's machine, running or stopped: nfltr orch hub runs lists every hub there with its agents, whether it is running, and how to reattach it. nfltr orch hub show --hub-id <id> <agent-id> prints one agent's turns: each message, state, worker and machine, usage, error, branch and sha, the answer and structured result, and the last events of the turn's task. Both only read the hub's state file and task store, so they work when the hub is stopped and need no relay.
  • While the hub runs, from any machine of the account: nfltr orch task list, nfltr orch task status, nfltr orch task events and nfltr orch task result reach the hub through the relay, end to end encrypted.
  • On a paired device: a hub paired with nfltr orch hub pair still shows its owner questions, approvals and live work on the dashboard's Hubs page, sealed end to end and decrypted on that device.

A stopped hub is picked up again by reopening Claude Code in the same project directory, since the default hub id is one per project directory, or by adding the hub MCP with that id (claude mcp add nfltr -- nfltr mcp --toolset hub --hub-id <id>). Any completions it missed arrive exactly once; in a test where a hub was killed mid-run, the new session got both results from its first wait (measured here). When this post was published, the reattach command was nfltr orch --hub-id <id>; that launcher was removed in v2.1.20 (October 22, 2026), and the hub is now your own Claude Code session with the hub MCP.

Here is nfltr orch hub runs on a machine with one stopped hub that ran two agents (the hub id and briefs are made up for this post):

$ nfltr orch hub runs
hub docs-pass stopped (reattach: nfltr mcp --toolset hub --hub-id 'docs-pass' as Claude Code's MCP server), 2 agent(s)
  agent-20261009t101512-3f9a2c41 completed turns=1 machine=build-box task=agent-20261009t101512-3f9a2c41-t1-a1 "Fix the broken links in the docs and push a branch"
  agent-20261009t101513-b07e5d19 completed turns=1 machine=laptop task=agent-20261009t101513-b07e5d19-t1-a1 "Check the changelog against the last release and list anything missing"
  inspect one: nfltr orch hub show --hub-id 'docs-pass' <agent-id>

At publication the first line read hub docs-pass stopped (reattach: nfltr orch --hub-id 'docs-pass'), 2 agent(s); since the launcher's removal it names the hub MCP instead. --hub-id limits the list to one hub, and --json prints the same data for scripts. The observe guide, Observe orchestration, has the full set.

What it costs

  • No run history across machines in the browser. If hubs run on several machines, each machine shows its own. There is no single page on nfltr.xyz that lists them all, and there will not be one that the relay can read.
  • Hubs started with the removed flags fail. A script or MCP config that still passes --dashboard-digest or the other two flags now stops with flag provided but not defined. Removing the flag is the fix.
  • Archived runs are not listed. nfltr orch hub runs lists what is still in a hub's files. A hub drops settled agents from its state as it archives them, and on start it clears finished task rows older than its vacuum window, seven days by default.
  • A hub that runs elsewhere is read there. The two commands read local files only. To see a running hub from another machine, use nfltr orch task; a stopped hub on another machine is read on that machine.

How it was checked

  • A unit test reads a stopped hub from its files: listed with its agents and its reattach command, one agent's turns with state, answer, branch and its task's events, the JSON forms, and unknown agents and missing ids failing closed.
  • The hub end-to-end test, with a scripted stand-in for Claude, ran a real nfltr orch "<goal>" session with two agents, let it exit, and then read both agents back with the two commands. Since the launcher's removal, the same test runs the hub as a plain claude -p session with the hub MCP server and reads its agents back the same way.
  • Hub tests send every task route as the relay's own agent and expect a refusal with no content and no control applied, while the owner is still served. Another test checks the removed flags are unknown.
  • A browser test refreshes the dashboard's Runs view and counts zero requests to any hub; the paired-device Hubs page still decrypts its sealed section.

Evidence: the dashboard reads no hub, and a stopped hub is read from its own files

Setup
Automated tests at v1.0.689 and v1.0.690, October 9, 2026: a scripted stand-in for Claude, a private relay and its nodes, Chromium driving the dashboard on an in-process relay. No production measurement.
Numbers
Zero requests to any hub on a refresh of the Runs view. Both agents of a stopped two-agent hub read back with nfltr orch hub runs and nfltr orch hub show. Every task route sent as the relay's own agent refused with no content and no control applied, while the owner was still served.
Reproduce
(a) With the released binaries: run a hub in Claude Code, let it start an agent, close Claude Code, then run nfltr orch hub runs and nfltr orch hub show --hub-id <id> <agent-id> on that machine with no network. (b) Our check, in the closed nfltr repository, all $0: make test-orch-hub-fake-claude (the two commands' tests and the end-to-end hub that exits and is read back), make test (among the whole suite, TestRelayAgentIsRefused: the relay's own agent refused on every task route), make test-hub-live-detail-browser (Runs is a pointer that reads no hub; decrypted content only on a paired device) and make test-hub-remote-browser (pairing, answers and approvals on the Hubs page, no plaintext at the relay).
Limits
Tests prove the paths exist and fail closed; they say nothing about how long a real hub's history stays readable. The Hubs page was checked with a virtual authenticator, not a real phone.

The relay already kept only what is dynamic on nfltr.xyz, as described in nfltr.xyz now runs on nfltr: sign-in, the dashboard, the API and shares. Now the dashboard part of that list holds nothing of your runs either. They are on the machine that made them.

Is it for you?

Fits if you want the record of your agents' work to stay on the machine that ran the hub, readable by you and not by nfltr.xyz, with live work reachable from your other machines only end to end encrypted.

Not ready for one page that lists every hub's runs across machines: there is none in the browser, and a stopped hub on another machine is read on that machine. Archived agents and finished task rows older than the vacuum window (seven days by default) are not listed. The hosted relay at nfltr.xyz is one VM; running your own relay is a beta without share links, a private LAN or a dashboard (Run the relay on your own network). Agents are Claude Code only. The hub and its commands are closed source; link, the relay SDK and the relay core are public since 2026-10-29 (open source).

Try next: add the hub to Claude Code, give it a goal, then read its runs on that machine:

claude mcp add nfltr -- nfltr mcp --toolset hub
claude -p "<goal>"
nfltr orch hub runs
nfltr orch hub show --hub-id <id> <agent-id>

On a single machine, claude mcp add nfltr -- nfltr orch hub --max-agents 2 brings its own local relay and node. The guides: Observe orchestration and Use nfltr from Claude Code. How the hub and its agents fit together is in How distributed Claude Code is built with nfltr.

← All posts