A hosted member, an outside tool on the team whose roster entry declares a webhook trigger, is now rung when work lands for it. The daemon POSTs a pointer to the row (its id, destination, sender and summary, never its body) to the member's declared webhook, taking credentials only from secret refs. Credentials in the URL are sent as a Basic Authorization header, and no credential appears in any recorded result or posted finding. An accepted ring is recorded as accepted, not as picked up, on the wake that rang. A daemon restart doesn't ring that same accepted wake again, while a new wake for the row, such as an unblock or a resolve decision, still rings, and a failed ring is retried. A member whose entry declares no trigger stays unroutable, so its person is told, as before. `rig queue create --verify` says the trigger accepted the ring, not that the member picked it up. 14 files, +608 -75, of which 316 are test lines.
5.7 KiB
Find specialists with rosters
A roster records who to involve for a purpose and why. The same seat can appear in several
rosters with different capabilities and engagement. Membership is a recommendation, not an
assignment or a grant of authority. Contact someone with the existing rig send or rig queue commands.
Put JSON files in <workspace.root>/rosters/; the included starter and factory leads write
their team's <rig>.json there at first start and never replace an existing one. Read workspace.root with
rig config get workspace.root, or use --folder to read another folder in place.
rig roster list
rig roster show production --json
rig roster find 'colour grading'
rig roster find 'editor@studio' --folder ./rosters --json
list reads authored purposes and curators without contacting daemons. show and find read the
configured daemon and registered HTTP hosts through rig ps. Each command reads current node
listings once per route, not once per member. find matches part of a capability tag or seat
address, ignoring case. A seat in two rosters produces two recommendations with their own reasons.
{
"version": 1,
"id": "production",
"name": "Production",
"purpose": "Make a film",
"curator": { "seat": "lead@studio", "host": "host-a" },
"updated_at": "2026-10-01",
"members": [{
"seat": "editor@studio",
"host": "host-a",
"capabilities": ["colour grading"],
"engagement": ["consult", "review"],
"use_when": "Choose a look or review a grade",
"why": "Knows the footage and the delivery requirements",
"caveat": "Ask about availability first"
}]
}
Use the serving daemon's hostSelfId and the exact seat address from rig ps --nodes -A --json.
A caller's local host alias is not necessarily that identity. Other hosts must already be
registered; the roster command does not register them or dispatch work. Existing HTTP fan-out
reports SSH-only hosts as unsupported. JSON retains per-host failures and partial-read warnings.
Authored files contain recommendations, not runtime facts. Extra fields are ignored, including
any authored runtime, model or activity. At read time the command joins by exact host self-id
and seat. Unmatched or conflicting observations are unknown; a seat not reported running is
stale, with current runtime/model unknown. The configured model is the registry declaration.
Daemon node listings, rig ps --nodes --full and roster members also carry the full
modelObservation: status, model, source, observedAt, generation and reason.
Compact JSON uses the smaller shape described below. The configured model stays separate; roster's
live.observedModel is the observation's model or null. Human output says last observed.
Claude (claude-assistant-response) and Pi (pi-assistant-response) name response evidence;
Codex (codex-turn-context or codex-world-state) names recorded turn configuration, not a
verified backend response. The timestamp is the native record's time, never file mtime or inventory
read time. None promises the model that will answer the next turn.
The daemon reuses the current-occupant record selectors and bounded readers used by divergence monitoring, sharing a process census. Reporting does not need a configured model or comparator. A changed or unverified occupant, a record predating its tenure, missing or invalid record time, unreadable or ambiguous records, unsupported runtimes and older daemons report UNKNOWN with a reason, never the configured value as a fallback. An older record from the same verified occupant remains labelled last observed at its original time; this is not a freshness guarantee. No record contents, transcript paths or credentials are returned. Activity includes its own sample time; activity and running status do not promise that someone is available for new work.
The JSON observations.readAt is when the inventory read completed, not a native observation
timestamp. Rosters are never rewritten by these commands. Malformed files produce warnings while
valid rosters remain usable; duplicate IDs make show report ambiguity instead of selecting one.
Non-regular file targets, such as FIFOs and directories, are skipped with a warning; links to
regular files remain readable. Inventory uses ps --no-cleanup to preserve even stale local
daemon state files. Ordinary rig ps keeps its existing cleanup behavior unless given that flag.
The daemon reuses model facts only while the selected record's identity, size and modification time and the occupant generation remain unchanged. Inventory reads share two bulk pane snapshots and one process census; identity is checked after the final snapshot. A different observation from duplicate host routes makes only that observation UNKNOWN, preserving agreed registry fields.
rig ps --nodes --json keeps an observed model compact as
modelObservation: ["literal-model-id", "evidence-source", "native-record-time"].
UNKNOWN is { "status": "unknown", "reason": "..." }; older daemons may yield
null. --full and --fields modelObservation retain the full object, including
its status and occupant generation. Human output and roster reports use the full
labelled observation.
A member marked "hosted": true is a hosted member: a tool outside the terminal that reaches the team over MCP, with no node or pane.
rig_team lists it with its capabilities and caveat, no pane and activity unknown, unless its seat is one of the rig's nodes.
show and find say it's hosted rather than unmatched. See Hosted members.
Its entry can declare wake.webhook, the secret names for a trigger OpenRig rings when work lands for it
(see Ring it when work lands).