What it writes
Straw Boss keeps its state in files in the state directory, starting with the sb server’s own files, and in Herdr tokens on panes, tabs, and workspaces. The list names each file or token and what writes it.
Details
-
The sb server’s files (
server.json,server.lock,start-error.json,server.log,server.sock) in the state directory, orservers/<hash>/for another Herdr’s slot, and its intercom identitysb-server-<8 hex>(The sb server). -
Herdr pane token
sb_duty(a main’s kind:coordinator,integrator, orstanding;nullfor every other role, cleared at shutdown), written withsb_role(main,memberortower; a tower tab is also marked right after it is created; a tab opened for a request is created with the environment variableSTRAW_BOSS_ROLE=main, which makes its pi promote itself) and workspace tokentower(the tower’s intercom session id), both refreshed every 4 minutes with a 10 minute TTL, written again at once when a new Herdr server takes over (see A new Herdr server), and cleared at shutdown (a tower that quits then closes its own tab if it holds only that pane). -
Herdr pane tokens
sb_opened_by(the sender’s intercom session id, on a pane a tower opened for a request;link:<device id>for a teammate’s device, andinteg:<project>on the integrator a tower opened as its own main; refreshed by its main and cleared at shutdown, so the open limits count only live opened mains) andsb_open_main(a one-time mark the opener sets, consumed by the first pi that promotes itself from it). -
On a tower’s standing pane, Herdr’s
pane.report_agentandpane.release_agent(sourcestraw-boss, agenttower, idle, the state as the message, no resume command or session) while the tower prompt runs there, and that prompt’s command typed into the pane’s idle shell (The standing pane). -
Pane tokens
sb_order(a sort key),sb_mark(a role label) and, on subagents,sb_indent(a tree branch) andsb_name(the subagent’s name), and on a trainsb_step(its current step) next tosb_role, and the subagent ones on the panes of the subagents the session launched, with the same refresh, TTL and takeover rewrite; they feed the sidebar net view and the optional rows below (see Sidebar net view). -
roles/<hash>.jsonin the state directory, one record per tower, main, or train by pi session file: its role, pane, tab, and workspace, so a Herdr restore gives the role back; the record claims, and for a tower and a train the tab Herdr lists proves (see A Herdr restore). -
A pi session entry
straw-boss(tower) so a tower resumed in its tower tab keeps its role, and{ duty, dutyFrom, dutyWhy, dutyAt }for each change of a main’s kind (the last one wins at restore). Members write no entry for their role: every session joins at start, so entries saved by 0.4.0 (asked,joined) are ignored. The other entries carrynudged, a subagent run that was asked to report, orclosing,unclosed,resumed,continuedandgaveUp(a restored subagent run that was closed, found still open after all, handed to the launcher for resuming, told that its turn was cut, or given up on), andseenwithterminal(the terminal a running child’s pane was in) (see Subagents a Herdr restore brought back plain). -
When a team is set up: the files under
<pi agent dir>/straw-boss/link/and the intercom channelstraw-boss/link(not owner-eligible), registered by the sb server and by every tower (the link holder). -
The control channel
straw-boss/control(not owner-eligible, so it has no owner): registered by every tower and by a main a tower opened, and used for theclose-mainask and its answer (Closing an opened main). -
Every message it sends through intercom (
boss_broadcast,call_tower,tower_send, the nudge, the request handed to an opened main) has a message id with a nonce of the current process: pi-intercom refuses an id it saw from a session again with other content, and a restarted pi keeps its session id. -
One
events.subscribeconnection to Herdr’s socket per joined session or tower, which carries no events of interest and is read only for its closing (see A new Herdr server). -
A tower keeps one more
events.subscribeconnection to watch the head workspace (workspace.created,closed,moved,reordered), whether or not it has a UI; it reconnects like the one above and closes with the session (Talking between towers). -
A tower with a UI keeps one more
events.subscribeconnection for its dashboard (panes, tabs, and workspaces changing, see Tower dashboard); it reconnects like the one above, and closes with the dashboard. -
While remote access is on, one
tailscale serveentry (HTTPS 8443, proxying to the GUI server’s remote listener), removed when it goes off or the server stops;paired.json(the identity the devices were paired under, whether remote is wanted on, and the paired devices as cookie hashes with name, paired, last-seen, and expiry times) is written at each change and deleted only when there is nothing to keep: no device and remote not wanted (the last unpair after remote off, or remote off with no device), or no remembered identity.Remote off alone keeps the devices; unpairing the last device while remote is wanted keeps the wish; a different Tailscale identity turning remote on drops the devices; a stop, a takeover, a
/reload, and the end of the session never touch it; an expired device is dropped when it is next used or when the file is read. -
While Wi-Fi access is wanted or was used:
lan.json(the wish, the port, the SHA-256 of the GUI token the devices were allowed under, and the allowed devices as cookie hashes with a name and times; mode 600; removed only when it holds no device, Wi-Fi access is not wanted, and the port is the default8445),lan-ca.json(the certificate and its private key, mode 600, owner-only, kept out of Time Machine on macOS; replaced bylan reset, never made by a resume), andlan-ca-files/(the public.mobileconfigand.crt, written on demand and removed with the certificate) in the primary slot’s state directory;lan-*lines inserver.logthat never hold a code, cookie, token, or key.On Windows the two secret files sit under the folder’s owner-and-SYSTEM ACL and
lan-ca.jsonis on the read-back list. A secondary slot writes none of them. -
One intercom extension channel per tab,
straw-boss/tab/<hex of the tab id>, registered by every joined session and tower; the channel’s owner (the first to join) only records the main, and it is not the main by that. Tab ids over 24 characters are refused. -
trust/<uuid>.json,<uuid>.answer.json, and<uuid>.result.jsonin the state directory (a 700 directory, files 600, each written by rename): the project trust question of a pi that has not joined the net yet, the server’s answer, and which side answered (Project trust). The asking pi removes its request and answer when it is decided or when it ends; the server removes a request whose process is gone, results after 2 minutes, and anything left half-written.gui.jsoncarriestrust: 1: the sb server reads them. -
The dialog channel
straw-boss/gui/<sha256 prefix of the server's session id>: registered owner-eligible only by the sb server (its intercom id isgui.json’sownerSession), and joined by every session (subagents included) whilegui.jsonnames a server whose process is alive; each session checksgui.jsononce every 2 s from its start. Besides dialogs it carries the session’s document list (pi-herdr-doc-review’s ids, paths, display names, reasons, revisions; the bridge asks the owner for the list again when it starts, so a session that reloads lists what is open) and form answers addressed to one document and once per answer id, and the key pad’s editor check: the server asks a session’s bridge what Enter would submit, and the bridge answers with a class (empty, text, another slash or!command, or unknown) and at most the name of a command that ends or replaces the session, never the draft, and only to the servergui.jsonnames now whose process is alive.
The tower tab is labelled with the radio tower glyph (U+F043B) alone and its Herdr agent is named tower-<workspace id> in lowercase (Herdr agent names are unique per server).