sublayer / manual / layout

where things live

the directories, services and ports on the box, and which file to open for what

One machine runs the station. Everything below is a path on it, and the first question when something is wrong is usually "which of these did I forget exists".

The agents

Each long-lived agent is a directory under ~/agents/<name>/, and the directory is the identity: same files, same memory, every day, however many times the process restarts.

pathwhat it is
~/agents/<name>/home/AGENTS.mdthe brief: the whole standing orders for that agent, read at the start of every session
~/agents/<name>/home/crush.jsonthe agent's MCP servers: its own Switchboard endpoint, Cairn, and for zathras the phone
~/agents/<name>/envits credentials, mode 0600: the Switchboard token, the forge token, the Cairn token, its callsign
~/agents/<name>/gitconfigits git identity and the credential helper for the forge, selected with GIT_CONFIG_GLOBAL
~/agents/<name>/data/the crush session database and logs; the agent's memory of what it did

The agents on shift are zathras (the worker; owns the inbox queue, the webhooks and the phone), ivanova (the reviewer; owns the reviews queue and nothing else) and franklin (the pathologist; every CI failure becomes a control and a case). Adding one is a procedure, not an improvisation: the new-agent skill provisions the endpoint, the forge user, the Cairn token, the directory and the supervisor drop-in, and writes the brief first.

The repos

pathwhat it is
~/agents/repos/<name>one persistent clone per repo the station works on, with a gitea remote pointing at the private forge. Repo names lose their hyphens here: the GitHub repo software-observatory is softwareobservatory on gitea
~/agents/worktrees/<repo>/<task>where the actual work happens. A reviewer checks a pull request out here and removes it when the todo closes; a worker branches here rather than dirtying the clone
~/agents/sweeps/the working directory of the scheduled one-shot sweeps, with a CLAUDE.md that is their whole brief
~/agents/cybrahms/the station's GitHub-facing identity: a git config, a GPG key, and the tokens an attended session uses to commit and push as cybrahms

Never clone into /tmp. A clone there has one remote, the public one, and an agent working in it will reach the end of the job and find it has no way to open the pull request.

The supervisor

harness keeps every agent alive and runs the sweeps on a schedule. It is a user service, and it reads one main file plus a drop-in per harness.

pathwhat it is
~/.config/harness/harness.tomlthe daemon's own settings and the drop-in directory
~/.config/harness/harness.d/<name>.tomlone per agent (a crush session, restart always, its workdir and env file) and one per sweep (a claude-code one-shot with a prompt file, a cron schedule, a timeout)
~/.config/harness/prompts/<sweep>.mdthe prompt a sweep runs with; a fresh session every time, so the prompt is the whole brief

Drop-ins are not watched: after adding one, harness reload. To see what is running, harness list; to sit with an agent, harness attach <name>.

The queue, the pastebin, the phone

pathwhat it is
~/.config/switchboard/envthe queue's own settings: address, database, base URL
~/.config/switchboard/vend/the vended credentials: one env per agent endpoint, one record per webhook, written when each was created
~/.config/sbpush/envthe ingest URLs sbpush posts to, one per agent that has a generic webhook
~/.config/tg-bridge/envthe bot token, the paired chat, and the ingest URL the phone delivers to

The tools

Two directories hold the command-line tools; both are on every agent's path.

toolwherewhat for
forge~/.local/bingitea from the command line: pull requests, checks, waiting for a merge. Use it instead of curl against the API
sbpush~/.local/binpost one todo to an agent's inbox from a shell
sbmcp~/.local/bincall one Switchboard MCP tool as a given endpoint; how a person lists a queue or reads a routing rule
tg-bridge~/.local/binthe Telegram poller
crush~/.local/binthe agent runtime the persistent crew runs on
deaddrop, hacklog, knowledge~/.local/binthe shared notebook, the public build log, the fact store
harness, switchboard, cairn~/go/binthe supervisor, the queue and the pastebin themselves

The services

All user services, one launchd plist each under the space.sublayer name.

serviceportwhat it is
gitea3000the forge. Every repo, every pull request, every CI run
act-runnergitea's Actions runner: it runs each repo's suite and its deploy target
switchboard8090the queue
cairn8091the pastebin; bodies in MinIO
minioobject storage for Cairn
postgresql 175432one database server for switchboard and cairn
caddy8443TLS on the tailnet: gitea, switchboard and cairn as <name>.sublayer.space
cert-synckeeps caddy's tailnet certificates fresh
pg-backupthe database backups the health sweep checks for
harnessthe supervisor
tg-bridgethe phone

Nothing on this list is reachable from the public internet. The three public sites, this one, hacklog and medlab, are static directories rsynced onto a separate host by gitea's runner after a green merge to master.

Which file to open

  • An agent did something odd: its brief, then its session database under ~/agents/<name>/data/.
  • A todo went to the wrong agent, or nowhere: the routing rules, read with sbmcp <env> list_webhook_rules.
  • An agent is down: harness list, then its drop-in.
  • A sweep did not fire: the drop-in's schedule, then harness list for the last run.
  • Something needs a credential: the agent's env, the vend directory, and never a chat transcript.