Report and triage friction
A friction record says what made the work harder than it should have been: a confusing error, a missing flag, a stale instruction, or a tool that failed in a way you had to work around. It is a ledger entry in one workspace, not a task. File the work itself as a task; record the friction so the cause can be found, counted, and fixed instead of being worked around again in silence.
Your agent records friction for you when it hits it. The commands below are the same surface from a terminal, and the dashboard’s Knowledge view is the same ledger in the browser.
When to record
Section titled “When to record”Record friction when:
- a command, tool, or error cost you time and the next person or agent would hit the same thing;
- documentation, help text, or a skill instruction was missing, stale, or wrong, and you had to derive the real behavior;
- a policy, sandbox, or lifecycle rule surprised you and the surprise was not documented where you looked;
- the same annoyance has happened before. A second record is evidence, not noise: rates only show up when each hit is counted.
Do not record:
- the work itself. A bug to fix or a feature to build is a task. Link the friction to that task instead (see Task linkage);
- a one-off failure you cannot describe. Write what happened, what you expected, and what you did instead, or wait until you can;
- secrets, tokens, or private output. The body is stored Markdown in the workspace. Name the credential or file; do not paste its value.
Record it when it happens. One record per cause, with the evidence still in front of you, beats one summary at the end of the day.
Record it
Section titled “Record it”orbit friction add \ --body "What happened, what you expected, and what you did instead." \ --model claude| Option | Effect |
|---|---|
--body |
Required. Markdown describing what happened and why it caused friction. |
--model |
Required. The agent family to attribute the record to: codex, claude, gemini, grok, or muse. |
--title |
One-line handle, at most 120 characters. When you omit it, Orbit derives one from the body. |
--tag |
Taxonomy tag. Repeat the flag or comma-separate several. See Taxonomy. |
--during-task |
The task you were working on. An ID that names no task is refused. See Task linkage. |
orbit friction add \ --title "Help text gives a 2h maximum the runtime does not enforce" \ --body "The --help output and the enforced limit disagree, so the published maximum is wrong for values between them. Evidence: the two values, where each is printed, and a command that shows which one wins." \ --tag docs,tooling \ --model claude \ --during-task <task-id>The new record starts as open. The command prints its ID, in the form
FYYYY-MM-NNN. Keep that ID: show, update, resolve, and rehome all
take it.
Attribution is by agent family only. There is no free-form agent name: the
older agent field is retired, and naming a person or a session does not
change the rate the record counts toward.
Taxonomy
Section titled “Taxonomy”Tags say what kind of friction it was, so stats can split rates by kind.
List the tags configured for the active workspace before you guess:
orbit friction tagsThe shipped defaults are:
| Tag | Covers |
|---|---|
automation |
Scheduler, auto-task, or delivery-automation friction. |
build |
Make, format, lint, CI, or test friction. |
docs |
Stale or missing documentation or design docs. |
history-diverged |
A rewritten branch history orphaned recorded automation state. |
lifecycle |
Task lifecycle confusion or transition issues. |
naming |
Naming drift or duplicated sources of truth. |
other |
Fallback when nothing else fits. |
policy |
Filesystem-profile or sandboxing surprises. |
skill-guidance |
Misleading or incorrect skill instructions. |
tooling |
Tool, CLI, or MCP failures. |
A workspace can extend this list, so orbit is the authority
for the workspace you are in, not this table. A few familiar spellings are
accepted and stored as the canonical tag: ci, test, tests, and
testing become build; cli, mcp, and tool become tooling;
auto-task, auto-tasks, scheduler, and routine become automation;
skill and prompt become skill-guidance. The command reports any such
substitution. A tag the workspace does not configure is refused.
Model and task context
Section titled “Model and task context”Every record carries three pieces of context beside its body:
- Model. The agent family from
--model. Rates instatsare per family, so attribute the record to the family that hit the friction. - Workspace. The record lives in the active workspace. Select another
with the global
--workspace(a registered name,<SELECTOR> ws_*ID, or checkout path) or--root. A record filed in the wrong workspace is not lost; rehome it.<DIR> - Task. The optional
--during-tasklink described next.
Task linkage
Section titled “Task linkage”--during-task records which task you were working on when the
friction occurred:
orbit friction add \ --body "The reservation help and the enforced limit disagree." \ --model claude \ --tag docs \ --during-task <task-id>The link is context, in both directions:
- The dashboard shows
duringon the record and links the detail panel to that task.<task-id> orbitandfriction list --q <task-id> orbitfind the record by the task it names.search
The link changes nothing else. A friction record is not a task status, and finishing the task does not close the record. When a task does fix the cause, resolve the friction yourself once the fix lands, so the ledger says when the cause stopped costing time:
orbit friction resolve <friction-id>Find records
Section titled “Find records”orbit friction listorbit friction show <friction-id>list shows open and triaged records, newest first. Narrow it:
| Option | Effect |
|---|---|
--status |
open, triaged, or resolved; comma-separate several, or all for every status. |
--model |
Only this agent family. |
--tag |
Only records carrying this tag. |
--q |
Case-insensitive match over ID, model, tags, status, task, and body. |
--month |
Only records reported in that month. |
--from / --to |
Bounds on when records were reported. |
--limit / --offset |
Page through the result. |
--order |
Creation-time order. Default newest. |
orbit friction list --status open --tag toolingorbit friction list --status all --q "reservation" --order oldestorbit friction list --month 2026-10 --model claude --jsonAdd --json, --format , or --format to any orbit
command when a script reads the output. On a terminal the default is a
table; piped, it is plain text.
orbit covers the same ledger together with tasks. Friction matches
a case-insensitive substring, and search shows open frictions by
default:
orbit search "reservation limit" --kind frictionorbit search "sandbox" --kind friction --all # add triaged and resolvedorbit search "sandbox" --kind friction --status friction:resolvedorbit search "sandbox" --kind friction --all-workspaces # every workspace on this machineUse list to work one workspace’s queue with exact filters. Use search
when you do not yet know whether the record is a task or a friction, or
which workspace holds it.
Triage: open, triaged, resolved
Section titled “Triage: open, triaged, resolved”Every record moves through the same three states:
open— reported, not yet looked at. Every new record starts here.triaged— looked at and classified: the tags are right, the cause is understood, and someone has decided whether it earns a task. Triaging changes no behavior; it says the record has been read.resolved— the cause is fixed, or the record no longer applies. Resolve only when you can say what changed. A record resolved because its fix task landed should say so in that task’s summary or in an updated body.
Triage a record with update. Pass only the fields you change:
orbit friction update <friction-id> --status triagedorbit friction update <friction-id> --status triaged --tag tooling,docsorbit friction update <friction-id> --title "Shorter handle" --body "Updated evidence."orbit friction resolve <friction-id>| Option | Effect |
|---|---|
--status |
open, triaged, or resolved. |
--tag |
Replacement tag set. Repeat or comma-separate; this replaces the stored tags, it does not add to them. |
--body |
Replacement Markdown body. |
--title |
Replacement title, at most 120 characters. An empty value restores the derived title. |
--rehome-to |
Move the record to the registered workspace that owns it. See Rehome. |
resolve is the shortcut for --status . It takes no other
options. There is no delete: a record you filed by mistake is resolved,
with its body updated to say why, so the count stays honest.
Read the rates
Section titled “Read the rates”orbit friction statsorbit friction stats --jsonstats reads the active workspace’s friction and task stores and prints:
- totals:
total,open,triaged,resolved, andresolved_this_month; by_family: per agent family, its friction count, itstasks_done, andfrictions_per_10_tasks;by_tag: the same rates split by tag within each family.
A rate is frictions per 10 done tasks, so families and tags with more work
behind them compare fairly against quieter ones. A high rate on a small
tasks_done is a small sample; read the counts beside the rate before you
act on it. These numbers cover one workspace. Run the command with
--workspace for another.
Rehome a record filed in the wrong workspace
Section titled “Rehome a record filed in the wrong workspace”A record belongs to the workspace whose work caused it. When one lands in the wrong workspace, move it instead of copying it by hand:
orbit friction rehome <friction-id> --to-workspace <workspace><workspace> is a registered name or ws_* ID on this machine. The owning
workspace gets a copy with the original title, reporter, creation time,
task, status, and body, under a new ID. This record is resolved with a
pointer to the copy, and the command returns the copy as rehomed_as. Tags
the target workspace does not configure are dropped and named in the
result.
The same move is available while you triage:
orbit friction update <friction-id> --rehome-to <workspace>orbit friction update <friction-id> --rehome-to <workspace> --status triagedWhen the owning workspace is not registered on this machine, record the disposition without moving anything, and clear it later with an empty value:
orbit friction update <friction-id> --rehome-to <workspace> --move falseorbit friction update <friction-id> --rehome-to ""--move applies only with a non-empty --rehome-to. Rehoming does not
merge workspaces and does not move tasks; it moves one friction record and
leaves the resolved pointer behind so old references still resolve.
In the dashboard
Section titled “In the dashboard”Knowledge → Frictions shows the same queue for the selected workspace:
counts of open and triaged records and how many were resolved this
month, a search box, a Show filter (Active, Open, Triaged,
Resolved, All), and a detail panel where you set the status, edit the
tag set, and resolve the record. See
Use the dashboard.
Related
Section titled “Related”- Use the dashboard: triage the same records in the browser.
- CLI commands: every
orbitverb in one table.friction - Concepts: where the friction ledger sits among Orbit’s layers.