ROST implementation methodCompass authoring guideInstall the ROST implementation SkillROST implementation evidence and groundingAICOS chat guideResponsibility Graph playbookCharter design playbookCharter authoring deep-diveAgent staffing playbookAdd agents to your Responsibility GraphDesign a custom agentAgent builder guideAgent definition import guideHow agents workTool access and vaultAvailable tools guideCLI and MCP installation guideSkill builder guideAgent Skill authoring guideAgent Skill setup guideAgent reference mapCascade guideSignal guideFriction guideSteward queue guideBilling and pricing guideConfirmations and human gates guideGoverned command capability matrixSettings guideMembers and invites guideNotifications guideLocal runner guideStock agents guideTroubleshooting guideAI model data handling guideSecurity model guideSync rhythm playbookMigration and legal notes
Docs

Responsibility Graph playbook

How to build a functions-first graph with seats, owners, Stewards, vacancies, and clean authority.

graph designstaffing

On this page

  • Design rules
  • Single-root chart and parent resolution
  • Forge Developer Team seats are pinned
  • Add an agent from the graph
  • Read the graph in the app
  • An agent seat's profile
  • Review an agent seat's delivered work
  • Planned teammates show their name, never access
  • Read a human seat's page
  • First-pass structure
  • Common setup mistakes
  • Operate the graph from CLI or MCP
  • Decommission a seat
  • When to stop for confirmation
  • Agent guidance

The Responsibility Graph is the company's operating structure. It answers who owns what, where authority sits, and how work flows when people and agents share the company.

Design rules

  • Build functions before names.
  • Give every active seat one accountable owner or one clear vacancy.
  • Keep reporting and accountability clean. Avoid shared ownership for the same outcome.
  • Let one human occupy multiple seats when the company is still small.
  • Show vacant seats instead of hiding gaps.
  • Give every agent seat a human Steward chain.
  • Attach goals, measurables, and tasks to seats, not directly to people.

Single-root chart and parent resolution

The graph always resolves to a single canonical root seat (Founder & CEO in the standard shape) so the web canvas, CLI rost graph show, and MCP graph.get all agree on the same structure. In an onboarding setup plan, the first seat (seats[0]) must be that single parentless root seat, and its name must match the provisioned root seat's name after whitespace/case normalization. The parent of each seat is derived deterministically:

1. An explicit parent seat id, when it names a live seat in the same chart. 2. The seat at the ltree parent path, when one exists. 3. The steward seat, when the seat is not AICOS and the steward is a live non-self seat. 4. Otherwise the seat has no parent.

AICOS always stays a peer of the root (never a child of its steward) and never appears as an orphan in the unassigned set — this is intentional and not a data-quality issue.

Seats that do not reach the single root through the resolved parent chain are listed as unassigned (with unassigned: true and no incoming edge). Each graph.get node carries an unassigned boolean, and the CLI rost graph show output prints unassigned seats under a separate Unassigned section so operators can see which parts of the chart need attention. The web canvas parks unassigned seats at the bottom of the chart instead of inventing fake root edges, and when any exist a floating Unassigned seats — needs attention panel lists them by name; selecting one flies the canvas to that seat so the gap is one click from a fix, not just visible in the baseline row.

Forge Developer Team seats are pinned

Seats under forge.developer_team are resolved by Forge build dispatch using their exact path, so they cannot be reparented or merged from the graph, CLI, or MCP — moving a seat (or an ancestor whose subtree holds them) would eject them from dispatch, and no command can restore the path. To change who is accountable for one of these seats, update its steward with agent_setup.update; the reporting path stays fixed. To stand the team down, use the governed Forge team teardown flow, not a merge or decommission. The web canvas surfaces this pin visibly: a lock badge on the seat card (Responsibility Chart and Cascade views) and in the seat inspector panel, with a tooltip explaining the seat can't be moved, merged, or reparented — so the restriction is visible before a user hits the guard, not only as an error after the fact.

Add an agent from the graph

Agent creation is a first-class graph action. From a seat in the Responsibility Graph you can open the agent setup wizard with the seat already chosen as the parent:

  • Hover or focus a seat to reveal the Add agent control next to Open charter and Edit seat.
  • Open a seat's side panel and use Add agent beside Add child seat.
  • Use the graph toolbar Add agent action, or Add first agent on an empty or small graph.

Each entry opens the same conservative setup flow — seat placement, Steward, draft Charter, manifest sign-off, sandbox dry run, and human go-live — with the graph seat prefilled as the parent and its Steward chain offered as the default Steward. In the public read-only demo the control is omitted; it never starts a write you cannot finish.

Read the graph in the app

The graph canvas fits the whole structure into the frame when it opens and refits whenever the frame changes — opening a side panel, resizing the window, or rotating a phone. Zoom moves between three altitudes: a constellation of seat dots when zoomed out, seat cards at the working zoom, and charter detail when zoomed in. Seat cards stay legible on small screens, and the canvas is the one always-dark surface in the otherwise light app. Search the toolbar to fly to any seat by name.

Seat cards name their active occupants. When a seat has more than one occupant, the card shows the human/agent breakdown instead of only a count, and mixed human-plus-agent staffing is labelled. Use the occupants control on that card to open the detail panel, where each occupant is listed as either the human accountable for the seat or the agent executor, with the Steward chain shown for agent accountability.

The graph is also where you land after onboarding — it is the mission control for the company, not a separate dashboard. Switch lenses from the toolbar to recolour the same structure four ways:

  • Structure — seat type and reporting lines.
  • Cascade — whether each seat's goal branch is on track.
  • Signal — the worst measurable state per seat.
  • Scoreboard — direct work and direct cost on each seat, plus a separate team/subtree rollup for manager seats. The tenant summary counts direct agent work once, so a parent seat's team cost does not double-count the same run again. A seat whose direct cost is a clear outlier above the rest of the fleet is flagged as cost drift (labelled, not colour-only). Human seats and seats with no direct or team runs read calmly rather than showing a bare zero. For a small fleet the Scoreboard also leads with a two-tile summary — total work and total cost — framed as the single question that matters: is it earning its keep.

Switching into Cascade never re-runs the chart layout — seat positions scale in place to fit taller goal-summary cards, and the connector layer scales to match, so nothing rearranges under you. A company-objectives card anchors above the root seat with the active cycle's objectives; selecting one traces and emphasizes its branch down through the connectors while the rest of the chart recedes. Selecting a seat's goal opens the same goal detail panel /cascade uses, as a right-hand drawer — breadcrumb ancestry and child-goal rows let you walk the branch without leaving the graph, and an Open in Cascade link round-trips the same cycle, branch, and goal selection to the /cascade page. Lens, objective, goal, seat, and cycle are all URL state, so a reload or a shared link reopens the same view.

The graph also carries a mission-control panel. It pulls the same operational state visible on the agent and setup-health surfaces: held actions that need steward decisions, failed runs, open Friction, pending Signal readings, stale agents, and setup recommendations. Each item can focus the affected seat on the canvas and links to the route where the operator can act.

An agent seat's profile

A staffed non-AICOS agent's seat page uses one profile shell with eight URL-addressable tabs: Overview, Charter, Tools & connections, Skills, Autonomy, Signals, Activity, and Settings. The hero shows status, Charter purpose, Steward, seat path, lane, model, and last run. The sidebar keeps access, connection, tool/Skill/Signal/escalation/Charter counters, and schedule facts visible while the tabs organize the existing read models and controls. Legacy links such as #agent-ops, #recent-runs, and #run-<id> select the matching Settings or Activity tab. Human seats and the AICOS foundation seat keep their dedicated pages. Members without sensitive-data access see the same shell with explicit unavailable states for run, tool-call, cost, connection-status, and escalation facts; the page never broadens Trust Card access or turns an unavailable read into a confident empty/disconnected claim.

The Charter tab renders the accepted Charter as a document — purpose, responsibilities, decision authority — with its version chip and signer, plus a structured edit drawer for quick purpose/responsibilities/decision-authority changes. The drawer prefills from the active Charter (or an open amendment draft, if one exists) and stages the edited slice through the same audited commands as any other Charter change; sensitive fields (permission manifest, budget, measurables, escalation rules) never round-trip through the client, and a save fails closed with an explicit conflict message if the Charter changed underneath the drawer since it opened. An Amend action stays next to the drawer for changes it does not cover, opening the same draft-and-confirm flow as the Charter Builder.

An owner or Steward manages the agent's capabilities in context from the Tools & connections and Skills tabs, no separate editor page. On Skills, assign or revoke a Skill directly; each change stages a confirmation envelope for the human to approve in /approvals — never a silent write. On Tools & connections, capability setup uses the production access language: Off, Read, and Read & act. Deterministic suggestions from the template or Charter are labelled, unavailable provider scopes are disabled instead of hidden, and human overrides stay visible until saved. Saving a capability change stages the governed Charter-manifest amendment (charter.set) supersession path; selection alone never grants a tool call. The activation review then builds one receipt from the current scope digest, budget, lane, cadence, capabilities, and always-human boundaries. Signing Ask-first or creating a bounded Trusted grant uses that digest, so widening scopes or changing budget requires rebuilding and re-signing. A missing provider links straight to Settings connections with a return link back to this tab. Viewers without manage authority see the same tabs with an explanation instead of controls; every write still re-asserts seat authority server-side regardless of what the client shows.

Agent creation at /agents/new begins with four doors: Describe the job opens the existing in-app builder, Start from a template opens the stock-template picker, Build manually opens the custom setup path, and Import opens an in-app format explainer. Definition-file import is roadmap-only and never opens a bare file picker; operators can instead continue to the existing-agent pairing flow. Setup is the detail page filling in: creating a seat from any door hands off to that agent's detail page in draft mode (/seats/{seatId}) — there is no separate wizard shell or tab vocabulary. Draft mode renders the exact same eight tabs the live seat uses; Overview and Activity stay locked until the first run has something to show, and the other six own the editable draft (Charter, Tools & connections, Skills, Autonomy, Outcomes & Signals, Settings). The shared GateRail review rail (sign manifest → sandbox dry run → go-live) and the server's next_action stay the sole lifecycle truth throughout, unaffected by which door you entered through. The door only changes how the one canonical form gets filled in: manual is the blank form, template pre-populates it, chat opens an AICOS setup assistant beside the form that proposes typed field changes grouped by section for review before anything durable saves, and import maps a definition file into the same fields and reports what did not map — never credentials. Existing ?mode=template|custom|existing links open the matching door, and a ?seat= resume link redirects straight to the draft detail page.

Review an agent seat's delivered work

Agent seat pages show the operator-facing output trail, not just low-level run telemetry. The delivered work area combines explicit agent_deliverables, successful work.log evidence, and recent successful run summaries into one readable list — an output trail, not a completion claim. Rows whose completion is not attested carry a marker saying so — most read Not attested, meaning something was produced but nothing attests the work finished. A row whose producing step did declare completion carries no marker; the absence of a marker is what "attested" looks like. Each item shows what was delivered, when it happened, what kind of work it was, and safe evidence links labelled as internal, Linear, GitHub, or external. Secret-shaped values are redacted before display, and run or task context is shown only when it belongs to the same seat. Forge artifact batches can also carry a metadata-only integrity verdict so duplicate hashes, zero-byte files, size outliers, and manifest count mismatches are visible without exposing file contents. Each recorded deliverable also carries a status badge — awaiting decision, accepted, or rejected — and its accepted USD value once one is recorded; a still-undecided deliverable links through to /approvals to accept or reject it there, since this tab is read-only status, not the decision surface. Run-derived (not yet explicitly recorded) items always read as awaiting decision and never link to /approvals, since there is no deliverable there yet to decide on.

The Activity tab layers a curated business-activity narrative above the Trust Card's forensic execution trace: period-scoped counter tiles (today, this week, or 30 days) summarise the seat's work.record activity by kind — a "held for your approval" tile is always shown, and an operator can pick which other kinds appear via a per-seat, browser-local tile picker. Below the tiles, a run-grouped activity feed lists each work.list record — verb, object, outcome, evidence link, and time — with a drill-down for entity refs, the template_ref used for external comms when one was recorded, and the raw structured details. A sessions browser lists the seat's runs and, for the selected one, its persisted transcript (session_transcripts) and artifacts rail: binary artifacts (Supabase Storage) get a freshly minted 60-second signed download link at render time, pointer artifacts (Gmail draft, Drive doc, PR, or an internal reference) link out when an external URL is known. The task queue and Trust Card below are unchanged. All of this sits behind the same sensitive-data access gate as the Trust Card; a restricted viewer sees an explicit unavailable state, never a guessed empty feed. The /agents fleet page mirrors the same row grammar in a tenant-wide Work view — every seat's activity in one filterable stream, each row linking back to that seat's Activity tab with the originating session focused.

Planned teammates show their name, never access

A seat can carry a planned teammate — a named future human recorded as planned staffing (for example by composite onboarding or seat create-complete). The name is display-only and renders consistently on every surface: the graph seat card shows a hollow Planned: <name> badge, the human seat page shows the same badge on every tab and lists the name under Seat facts on the Access tab, and the read models carry it as planned_occupants — graph.get per node and seat.get per seat (the CLI prints planned=<name> on seat list and planned=<name> — no invite, no access on seat get). A planned teammate is not an occupant: no account, no invite, no occupancy, and no authority — the seat's Occupancy fact still reads Vacant until a real occupancy exists, with the planned name carried separately from the Occupancy fact — a hollow Planned badge (the clause rides on hover) or a Planned fact row that shows the clause inline. The governed path that retires the planned row when the real person arrives ships separately — until it lands, hiring the named person leaves the planned label in place alongside the real occupancy.

Read a human seat's page

A human seat's page opens on one computed answer line — for example "On track — 4 of 5 measurables on target · 1 held draft awaiting review" — instead of a wall of always-shown sections. Below it:

  • Exceptions are fully visible: off-target measurables, escalations addressed to this seat as Steward (a held draft awaiting the Steward's decision), and open Friction filed by or owned by this seat all render as rows up top, each with a one-click way to act (log a reading, review, or resolve).
  • Healthy content collapses to a count: on-target measurables and measurables with no reading yet fold into one expandable "N measurables on target" row so the calm majority does not compete with the exceptions for attention.
  • Three lens tabs — Overview, Activity, Access — are views of the same seat, not separate sub-pages: Overview holds the answer line, exceptions, Purpose and accountabilities, and the Cascade goal summary; Activity is the event feed and the seat's task queue; Access is occupancy, Charter status, decision authority, and the permission manifest.
  • One Manage drawer replaces the inline staffing panel: it opens to Occupancy (staffing controls, when this seat is eligible to be staffed, and Let go), Charter (a link to the Charter Builder), and Measurables (a link to log a reading in Signal). Opening the drawer calls the exact same commands as before — nothing moved out of it changed behavior.

Agent seat pages keep their own dedicated Overview/Charter/Access layout with an always-visible fact sheet; see "Review an agent seat's delivered work" above for the agent-specific completed-work view.

First-pass structure

Start with the operating root, then major functions, then the few seats that own the most important recurring work. Do not over-model. A graph with eight clear seats is better than a graph with thirty vague boxes.

Each seat needs:

  • Name
  • Purpose
  • Seat type: human, agent, or hybrid
  • Parent seat
  • Occupancy or vacancy
  • Steward, when the seat has an agent
  • Initial Charter status

Common setup mistakes

  • Starting with employee titles instead of functions.
  • Creating shared seats where nobody is finally accountable.
  • Hiding work under a leader instead of creating the real operational seat.
  • Staffing an agent before a Charter defines authority and escalation.
  • Treating vacant seats as failure instead of useful structure.

Operate the graph from CLI or MCP

Read before you write. Load the whole graph first so seat ids, parents, and occupancy are known.

  • CLI: rost command graph.get --json '{}' (scope: tenant). Returns seats, edges, root, occupants, display-only planned occupants, status rollups, and unassigned-seat flags. The output includes a single root_seat_id, exactly one is_root: true node, and unassigned seats listed under their own section with a data-quality note.
  • MCP tool: rost_get_responsibility_graph with {}; or read the resource rost://graph (tenant-admin token).
  • One seat: rost command seat.get --json '{"seat_id":"<seat-id>"}' or rost_get_seat_detail.

Then mutate with the smallest change. Create returns the new seat_id:

rost command seat.create --json '{"name":"Finance","seat_type":"human"}'

Rename, reparent, and set-type take an existing seat_id. The MCP aliases are rost_create_seat, rost_rename_seat, rost_reparent_seat, rost_set_seat_type.

Decommission a seat

Retiring a seat is a single audited action. In the app it is the Let go control on the seat page; on the CLI/MCP path it is the seat.decommission command:

rost command seat.decommission --json '{"seat_id":"<seat-id>"}'

It ends every occupancy, archives the seat's active Charter, revokes the seat's MCP tokens and credentials, cancels any agent schedules, and marks the agent and seat decommissioned with a tombstone event — one transaction, one audit row. It is human_required and no-orphan guarded: an interactive human runs it directly; an agent or non-interactive caller is deferred to a human confirmation, and if retiring the seat would leave another live agent without a human Steward chain, the whole change rolls back. To retire only the agent and keep the seat available for re-staffing, use agent.decommission (the seat-page agent operations panel) instead.

When to stop for confirmation

seat.reparent, seat.set_type, and seat.decommission are human_required; seat.create and seat.rename are none, so an agent can add and rename seats directly. The structural commands return a pending confirmation with an approve link over MCP instead of mutating; the human approves with confirmation.approve. Never approve your own structural change from an agent session — surface the pending confirmation to a human. When a seat-targeted command does execute, its audit row is scoped to that seat (queryable by seat_id); on the deferred MCP path the executed audit is recorded against the human's confirmation.approve. See the confirmations guide.

Agent guidance

When operating through CLI or MCP, create fewer seats first and ask for confirmation when the structure would change authority. Prefer draft seats and draft Charters until a human approves the setup.

Version

2026-07-31.2

Used by

  • human
  • cli
  • mcp
  • in app agent

API

/api/reference/files/responsibility-graph-playbook