# Harness Client

> Attach to a running basicly supervisor as a second session — observe live status, present its pending decisions to a human conversationally, and record the answers. Use when a supervisor is already running (or may be) and you are not the one driving it, to check what the factory is doing, unblock a lane that waits on a judgment, or answer a queued decision.

- Skill: `niksavis/harness-client` (Agent Skill)
- Install (CLI): `npx skillmds@latest add niksavis/harness-client`
- Raw SKILL.md: https://api.skillmd.com/api/skills/niksavis/harness-client/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: niksavis (https://skillmd.com/u/niksavis)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/niksavis/harness-client

---

<!-- Generated by `basicly skills-build` from skill.yaml. Do not edit; edit the source. -->

# Harness Client

## Scope

Owns being the **client** of a running supervisor: attach, observe, answer.

It is not for driving work yourself — `harness-loop` owns single-track work
(`basicly loop run`), and the supervisor itself owns fan-out over lanes
(`basicly loop supervise <root>`). Reach for this skill when a supervisor is
already running, or may be, and you are a *second* session looking in.

Every command here is either a pure read or a write to one decision item, and
none of them touches a worktree, a branch, or a gate. The one exception is the
board's default action route, below: it can approve a checkpoint or kill a lane.

## Attach: one command, no lock

```sh
basicly loop session <root-issue>            # live status of the session
basicly loop session <root-issue> --json     # same, machine-readable
```

It reads the tracker and the supervisor's lockfile and writes nothing, so it
never contends with the supervisor and any number of clients may attach at
once. It answers four things:

- **supervisor** — who holds the repo's singleton lock, and how old their
  heartbeat is. `(none running)` means the root is unsupervised; a *stale*
  heartbeat means the holder crashed.
- **lane** — each in-flight lane, its worktree and branch, whether that
  worktree still exists, and what the lane last ran (agent, outcome, tokens).
- **decisions** — how many judgments the session is waiting on.
- **grant** — the autonomy level in force and the tokens spent against its
  budget.

A root nobody is supervising is a valid attach, not an error. Exit status is 0
either way — use `basicly loop decisions` when you want an exit code that
means "blocked on a human".

## A wall display attaches the same way

For a screen in the room rather than a terminal:

```sh
basicly board serve                  # http://127.0.0.1:8787
basicly board serve --port 0         # take an ephemeral port and print it
```

It takes no lock and writes no file, but by default it registers one POST route
that runs the basicly command an operator submits — a closed table of three
(answer a decision, approve a checkpoint, kill a lane), the last two behind a
typed confirm code. Pass `--no-actions` for an unattended wall, where a POST is
405 and nobody can drive a lane from a screen anyone in the room can touch, and
leave `--bind` unset so it stays on the loopback.
While the supervisor's heartbeat is fresh it serves the snapshot that
supervisor already wrote and folds nothing; with no live holder it folds for
itself every `--refresh` seconds. Every panel carries the snapshot's age, so a
frozen screen reads as frozen rather than as calm.

`GET /snapshot.json` is the same `harness-board/v1` document, byte for byte,
for any other consumer. Ctrl-C reports how many refreshes it managed.

## Never take the lock from a live holder

The lock is a repo singleton because two supervisors would land to the same
base checkout concurrently. So while `loop session` reports a fresh heartbeat:
do not start a second `loop supervise`, do not run `basicly loop advance` on
one of its lanes, and never delete or edit the lockfile under
`.basicly/usage/`. Answer the decision the session is waiting on instead —
that is what unblocks it, and the supervisor picks the answer up on its next
pass.

A *stale* heartbeat is the one case where taking over is right, and the way to
take over is to start a supervisor:

```sh
basicly loop supervise <root-issue>   # claims a stale lock atomically
```

Deleting the file by hand instead races a contender that may already be
mid-takeover.

## Answering a pending decision

```sh
basicly loop decisions <root-issue>            # the queue; exits 1 when any pend
basicly loop watch <root-issue>                # stream newly pending items
basicly loop answer <decision-id> "<answer>"   # record one answer
```

Present each item to the human as itself: the bead it blocks, its kind, the
question, and the detail the lane recorded as evidence. Then record the
human's answer **verbatim** — it becomes durable evidence on the bead and the
lane's next dispatch is assembled from it, so a paraphrase becomes the
instruction the agent follows.

IMPORTANT: never answer a decision on the human's behalf. Every queued item is
there because the engine determined the fact is not derivable from recorded
state, so inventing one lands a wrong answer carrying human attribution. If
nobody is available, either leave it pending or delegate it explicitly:

```sh
basicly loop decide <decision-id> --root <root-issue>
```

That invokes the decider agent under a confined tool surface, bounded to the
session's intake corpus. It abstains back to the human when the answer is not
in the corpus — an abstention is the correct outcome, not something to retry
around.

Attribute a non-human answerer so the trail stays readable:

```sh
basicly loop answer <decision-id> "<answer>" --by "<who-decided>"
```

## Poll no tighter than the heartbeat

`loop watch --interval` defaults to the supervisor's heartbeat cadence, and
each pass walks the whole session tree in the tracker. Polling faster buys no
fresher state and competes with the supervisor for the tracker.

```sh
basicly loop watch <root-issue> --once        # one pass for a script, then exit
```

## What a client does not do

Answering is the client's only write. Approving a checkpoint, granting
autonomy, landing a lane, and closing a bead all stay with whoever drives the
loop, under the confirm-code and grant rules `harness-loop` describes — a
client that approves a checkpoint has approved it on the supervisor's behalf,
which is precisely the human judgment the checkpoint exists to require.

