Charter authoring deep-dive
The full Charter document contract field by field — decision authority, escalation, measurables, budget, permissions — with worked examples for human, agent, and hybrid seats.
A Charter is a seat's executable operating contract. On the CLI and MCP path you author the full document and submit it directly with charter.update_draft (edit an existing draft) or charter.set (create-or-replace in one call). The server validates the whole document against the Charter schema and stores it; it does not re-synthesize it. Two internal-ish fields (unanswered_boundaries, seat_type_recommendation) are optional — omit them and the server fills them conservatively; everything else you author. Read the exact contract first with command.describe (rost command schema charter.update_draft), which returns the JSON Schema and a validated worked example. The companion charter-design-playbook covers the narrative; this guide covers every field of the document.
Field-by-field
- purpose — one sentence: why this seat exists. Lead with the seat name. Good: "AP intake clerk: draft accounts-payable entries from inbound vendor emails for human review."
- accountabilities (1+) — each
{ title, description }. Outcomes the seat owns, not activities. The test is whether a measurable, an escalation, or a handoff can attach to it. "Draft every inbound invoice within one business day" beats "help with accounting." - decision_authority — the heart of the contract, split three ways:
- autonomous — what the seat may do without asking. Each item is
{ action, condition, rationale, unanswered_boundary }. Only reversible, low-risk, in-scope actions belong here. An autonomous item must haveunanswered_boundary: false— the schema rejects an autonomous item with an unanswered boundary (push it to escalate instead). - approval — the can-do-with-a-yes set: durable, money-moving, external-send, staffing, or policy actions that require explicit human approval. Name the threshold in the
condition(e.g. "before posting or sending," "over $5,000"). - escalate (1+) — the must-ask set: ambiguous authority, irreversible actions, credentials, legal or financial exposure, customer-impacting exceptions. At least one escalate item should carry
unanswered_boundary: trueso unresolved boundaries default conservative. The submit schema does not strictly require it, but the direct submit path (charter.update_draft/charter.set) does not add one for you — it only records the boundaries you flag — so include one whenever a boundary is unresolved. - escalation_rules (1+) — plain-language rules that trigger escalation, beyond the structured authority items. "Escalate any invoice over $5,000 or from a vendor not already in the ledger."
- measurables (1+) — each
{ name, target, cadence, source }. A measurable must measure the accountability, not vanity.cadenceisdaily|weekly|monthly|quarterly;sourceishuman|agent|integration. Agent-sourced readings are unconfirmed until a human confirms them. - permission_manifest — each
{ tool, scope, granted, rationale }. Map each accountability to the narrowest tool scope that performs it. Prefer draft/read scopes; a send or spend scope is a deliberate, justified grant. The manifest is what the tool-guard enforces and what a human signs. - budget —
{ monthly_usd, approval_required_over_usd, notes }.monthly_usdmay benull(no autonomous budget).approval_required_over_usd: 0means any spend needs approval. State the rule innotes. - unanswered_boundaries (optional) — the open questions about this seat's authority you have not resolved. Naming them keeps them conservative instead of silently autonomous. You may omit this field; the server defaults it to
[](and still records any boundary you flag inline viaunanswered_boundary: trueon an authority item). - seat_type_recommendation (optional) —
{ recommendation, rationale, confidence }where recommendation ishuman|agent|hybrid. Reason from the work: high-volume, rule-bound, reviewable work suits an agent under a Steward; judgment-heavy or relationship work stays human; split work is hybrid. You may omit this field; the server defaults conservatively tohumanuntil a human decides otherwise. Supply it when you have a clear recommendation.
The full JSON shape
{
"payload_version": 1,
"purpose": "AP intake clerk: draft accounts-payable invoice entries from inbound vendor emails for human review.",
"accountabilities": [
{ "title": "Draft every inbound invoice", "description": "Convert each inbound vendor invoice into a draft AP entry with correct vendor, amount, and GL coding within one business day." }
],
"decision_authority": {
"autonomous": [
{ "action": "Draft AP entries and propose GL coding", "condition": "Allowed when the vendor is known and the amount is within the standard range.", "rationale": "Drafting is reversible and human-reviewed.", "unanswered_boundary": false }
],
"approval": [
{ "action": "Post an invoice or send a vendor message", "condition": "Require human approval before posting or sending.", "rationale": "Posting and sending are durable, money-moving actions.", "unanswered_boundary": false }
],
"escalate": [
{ "action": "Unknown vendor, payment over the threshold, or suspected duplicate", "condition": "Always escalate to the Steward before acting.", "rationale": "Conservative default for ambiguous or financial exposure.", "unanswered_boundary": true }
]
},
"escalation_rules": [
"Escalate any invoice over $5,000 or from a vendor not already in the ledger."
],
"measurables": [
{ "name": "Invoices drafted within one business day", "target": "100%", "cadence": "weekly", "source": "agent" }
],
"permission_manifest": [
{ "tool": "ap.invoices.read", "scope": "Read inbound invoices and the vendor ledger.", "granted": true, "rationale": "Needed to draft entries from source invoices." }
],
"budget": { "monthly_usd": null, "approval_required_over_usd": 0, "notes": "No autonomous spend; any spend requires Steward approval until a budget is set." }
}This worked document omits unanswered_boundaries and seat_type_recommendation — both are optional. The server fills them conservatively on submit (unanswered_boundaries defaults to [], picking up anything you flagged inline with unanswered_boundary: true; seat_type_recommendation defaults to human). Supply either field when you have a concrete value and it is respected as-is. Everything else is required.
Three worked seats
- Human seat (Head of Sales). Purpose centers on judgment and relationships. Almost everything is autonomous within budget; approval covers discounts past a threshold; escalate covers contract terms outside policy. Measurables are human-sourced (pipeline, close rate). Supply
seat_type_recommendation: { "recommendation": "human", … }, or omit it — the server defaults tohuman. - Agent seat (AP intake clerk). The example above. Tight autonomous scope (draft only), approval for posting/sending, escalation for unknown vendors and large amounts, an explicit draft-only permission manifest, and
approval_required_over_usd: 0. Supplyseat_type_recommendation: { "recommendation": "agent", … }so the seat is recommended as an agent under a human Steward. - Hybrid seat (Customer success). Split the work: the agent drafts renewal summaries and flags at-risk accounts autonomously; the human owns the renewal conversation and any concession. Approval covers anything customer-facing being sent; escalate covers churn risk and credits. Supply
seat_type_recommendationashybridwith a rationale naming the handoff.
Authoring workflow and the human gate
1. charter.draft returns a draft charter_version_id (a conservative stub), or use charter.set to create-and-fill in one call. 2. charter.update_draft submits the full document above; charter.approve with edits can shallow-merge a partial before approving. 3. charter.sign_manifest and charter.approve are human_required. Signing a permission manifest, approving a Charter, or expanding authority is a human act recorded against decided_by. Prepare the draft and surface the approve link; do not approve on a human's behalf. See the confirmations guide.