Your runs stay on your machine

A run is what a hub does with a goal: the agents it starts, each agent's turns, their answers, branches and events. Since v1.0.689 and v1.0.690 the dashboard on nfltr.xyz no longer shows runs. Its Runs view is now 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.

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, started with nfltr orch or added to Claude Code with 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 with nfltr orch --hub-id <id>, and any completions it missed arrive exactly once.

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 orch --hub-id 'docs-pass'), 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>

--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, runs a real nfltr orch "<goal>" session with two agents, lets it exit, and then reads both agents back with the two commands.
  • 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.

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.

← All posts