> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parsaa.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Skills for your agent

> Ready to copy skills that teach Claude Code, Cursor and Codex how to use Orbit

Connecting an editor to Orbit's MCP server gives an agent fifty-odd tools and no account of which one answers which question. It will find `orbit_list_reviews` on its own. It will not guess that a crash group often already carries an analysis somebody paid for, that the reason it writes when dismissing a finding becomes a project rule, that `AGENTS.md` is generated and must not be hand-edited, or that a paid tool has to be priced before it runs.

A skill carries that. Orbit ships one, in three shapes, so an agent does not learn a different Orbit depending on the editor it runs in.

| Editor      | Where it goes                   | Shape                                                   |
| ----------- | ------------------------------- | ------------------------------------------------------- |
| Claude Code | `.claude/skills/orbit/SKILL.md` | A skill file, with `name` and `description` frontmatter |
| Cursor      | `.cursor/rules/orbit.mdc`       | A project rule, applied by its description              |
| Codex       | `AGENTS.md`                     | One `## Orbit` section of a file your repository owns   |

<Note>
  A skill is instructions, not access. What an agent can actually read or change is decided by its credential and its scopes, described in [MCP and agents](/orbit/mcp-and-agents). Installing the skill into a repository that has no token connected changes nothing.
</Note>

## Install them with the CLI

The `orbit` CLI carries all three and copies them in. It makes no network call, so it needs no token.

```bash theme={null}
orbit skills install                                  # all three editors
orbit skills install --editor claude
orbit skills install --editor cursor --editor codex
orbit skills install --dir ../other-checkout --force
```

Every run prints one line per destination:

```
created   .claude/skills/orbit/SKILL.md  claude
created   .cursor/rules/orbit.mdc        cursor
updated   AGENTS.md                      codex: Orbit section rewritten, the rest of the file untouched
3 destinations: 2 created, 1 updated, 0 unchanged, 0 skipped
```

Run it again and it writes nothing: a destination that already holds what the binary ships is reported `unchanged`, and its modification time does not move.

| Flag       | Meaning                                                                           |
| ---------- | --------------------------------------------------------------------------------- |
| `--editor` | `claude`, `cursor` or `codex`. Repeatable. Default: all three                     |
| `--dir`    | Repository to install into (default `.`)                                          |
| `--force`  | Replace a whole file that was edited since it was installed                       |
| `--json`   | One JSON document on stdout, one entry per destination with its action and reason |

### What it will not overwrite

The Claude Code skill and the Cursor rule exist for this and nothing else, so the CLI owns them whole, and it records the digest of what it wrote to each in `.orbit/skills.json`. That is what lets it tell a skill it installed from one you have since rewritten:

| What is on disk                     | What install does                      |
| ----------------------------------- | -------------------------------------- |
| Nothing                             | Writes it, `created`                   |
| Exactly what this version ships     | Nothing, `unchanged`                   |
| Exactly what it installed last time | Writes the newer skill, `updated`      |
| Anything else                       | Leaves it, `skipped`, naming `--force` |

So upgrading the CLI upgrades the skill, and a copy you have tuned yourself survives until you ask for the shipped one back. `.orbit/` is local state, so gitignore it; the skill files themselves are meant to be committed.

`AGENTS.md` is your document, not Orbit's, so the section is written between two HTML comment markers and nothing outside them is touched:

```markdown theme={null}
<!-- orbit:skills:start -->
## Orbit
...
<!-- orbit:skills:end -->
```

A later install rewrites what is between the markers and leaves the rest of the file alone. A file with no markers keeps everything it had and gains the block at the end.

<Warning>
  If `AGENTS.md` was generated by `orbit memory pull` it carries a header saying so, and the next pull overwrites it. Install refuses to write into it, with that as the reason. Put the section in [Orbit Memory](/orbit/mcp-and-agents#memory-instructions) as a memory of kind `instruction` instead, then pull: every agent in every checkout gets it that way, not only the repository you installed into.
</Warning>

## The files

Copy whichever you need, or let `orbit skills install` write them. All three cover the same ground.

<Tabs>
  <Tab title="Claude Code">
    Save as `.claude/skills/orbit/SKILL.md`. Claude Code discovers it by its `description`, so it is loaded when a task is about a review, a crash or the project's own decisions, and not otherwise.

    ````markdown .claude/skills/orbit/SKILL.md theme={null}
    ---
    name: orbit
    description: Read a Parsaa Orbit project through its MCP tools and take the few actions an agent should. Use when the task touches a code review finding, a crash or a hang, a failing test run, a build regression, a screen in the app, an artifact to upload, or what this team already decided.
    ---

    # Orbit

    Orbit holds what this app did in the field and what this team decided about it:
    code reviews with findings, crash groups with symbolicated frames, telemetry
    sessions and vitals, test runs, builds, a map of the app's screens, and the
    project's memory. All of it is reachable over MCP, so read it instead of
    guessing, and read it before proposing a change.

    Two things decide what you can do:

    - **Credential.** A project token names one project, so `project_id` can be
      omitted; it can never spend credits. A sign-in session (`orbit login`) reaches
      every project the person is a member of, so **pass `project_id` on every
      call**, and it can spend their credits.
    - **Scope.** `read` buys the read tools, `write` buys the free actions. A tool
      you are not offered is a scope the token does not carry, not a broken server.

    ## Start with memory, not with the code

    Call `memory_search` before proposing anything, with the question in whole
    sentences rather than keywords: the search reads meaning as well as text. A
    convention or a past decision that already covers the question is the difference
    between a suggestion that fits this codebase and one that reads as generic.

    - `memory_instructions` returns the compiled instruction bundle, the same text
      `orbit memory pull` writes to `AGENTS.md` and `CLAUDE.md`.
    - `memory_get` reads one memory in full, by the slug `memory_search` returned.
    - `orbit_list_learnings` is the reviewer's own rules for this project. Read them
      before arguing with a finding.

    The `recall_before_task` prompt does the first two in one step.

    ## Which tool answers which question

    | Question | Call |
    |---|---|
    | What did the reviewer say about this pull request? | `orbit_list_reviews`, then `orbit_get_review` |
    | Is there already a rule about this? | `orbit_list_learnings`, `memory_search` |
    | What is crashing, and where? | `orbit_list_crash_groups`, then `orbit_get_crash_group` |
    | Why is the app hanging or slow? | `orbit_list_issues`, `orbit_vitals`, `orbit_list_profiles`, `orbit_get_profile` |
    | What happened in one session, or to one person? | `orbit_list_sessions`, `orbit_get_session`, `orbit_list_users`, `orbit_get_user` |
    | Which tests failed, on which commit? | `orbit_list_tests`, then `orbit_test_cases` |
    | Did the build regress? | `orbit_list_builds`, `orbit_get_build` |
    | Which screen is this, and is it covered? | `orbit_atlas_map`, `orbit_atlas_screen` |
    | Anything at all, by file path or symbol | `orbit_search` |
    | What did this team decide? | `memory_search`, `memory_get`, `memory_instructions` |
    | Where does the project stand overall? | `orbit_project_overview` |

    Lists default to 20 rows and cap at 100; timelines page with `next_offset`. No
    answer is larger than 64 KB, so narrow the question rather than asking for
    everything.

    ## Reading a review

    1. `orbit_list_reviews` for the queue: one row per pull request, with its
       merge-confidence score, its zone (`green`, `amber`, `red`) and how many
       findings it raised by severity. Narrow with `prNumber` when you know it.
    2. `orbit_get_review` for the review itself: the walkthrough by layer, the
       checks that ran, and every finding with its file and line, severity,
       rationale and suggested patch. The finding ids it returns are what the
       actions below take.
    3. `orbit_list_learnings` before you disagree with anything. A finding that
       contradicts a rule the team already taught is worth reporting, not fixing.
    4. Work the findings highest severity first. For each one, either change the
       code and say which finding the change answers, or record the decision:

       ```
       orbit_set_finding_state  reviewId, findingId, state, reason
       ```

       `state` is `open`, `accepted`, `dismissed` or `fixed`. `accepted` and
       `dismissed` need a `reason`, and that reason becomes a project rule unless
       you pass `teach: false`, so write it for the next reader rather than for this
       call.

    The `fix_finding` prompt turns one finding into a plan with the file, the patch
    and the test that proves it.

    Two actions reach outside the working tree, and both need a person:

    - `orbit_apply_suggestion` **commits** the finding's patch to the pull request's
      branch through the Orbit GitHub App. It is free and it is a commit in
      someone's repository. Ask first.
    - `orbit_send_finding_to_agent` publishes the finding as a request the Parsaa
      macOS app picks up on its next sync. Nothing runs and nothing is pushed here.

    A review of a pull request that has none yet is paid: `orbit_estimate_review`
    first, show the credits and the model to the person, then `orbit_request_review`
    with `confirm: true`.

    ## Triaging a crash

    1. `orbit_list_crash_groups` with `status` (`new`, `open`, `resolved`,
       `ignored`), `sort` (`last_seen` or `report_count`) or `q` for a substring of
       the title or a symbol. Judge a group by how many reports it has and across
       how many devices and app versions, not by how recent it is.
    2. `orbit_get_crash_group` for the symbolicated leading frames, the breadcrumbs
       before the crash, the screen it happened on, the sessions it appeared in, and
       **any analysis that was already run over it**. Read that before paying for
       another one.
    3. Follow the evidence sideways: `orbit_get_session` for what the person was
       doing, `orbit_atlas_screen` for the screen, `orbit_vitals` and `orbit_fleet`
       for which app version and which devices carry it.
    4. Answer three things before touching code: what the crash is (the throwing
       frame in first-party code, not the top frame in a system library), what
       reproduces it, and which version introduced it.
    5. Then propose the fix and a test that fails without it. Record what you found
       with `memory_write` when it is a gotcha the next person would also hit.

    Unsymbolicated frames mean the build's debug symbols never arrived. Upload them
    rather than reading addresses: `orbit upload MyApp.app.dSYM`.

    Hangs are the same walk with different tools: `orbit_list_issues` for grouped
    hangs and logged errors, `orbit_get_profile` for an Instruments recording's
    main-thread story. The `triage_crash_group` and `explain_hang` prompts write
    both walks out.

    `orbit_analyze_crash` and `orbit_analyze_trace` cost credits. Call
    `orbit_estimate_analysis`, show the number, and only then confirm.

    ## Uploading with orbit upload

    There is one upload command, not one per kind. The kind is inferred from the
    path; pass `--kind` to override.

    ```bash
    orbit upload crash.ips                  # ips
    orbit upload MyApp.app.dSYM             # dsym, the bundle is zipped for you
    orbit upload build.xcresult --wait      # xcresult, waits for parsing
    orbit upload profile.trace --wait       # trace
    orbit upload Build.xcactivitylog        # buildlog
    orbit upload MyApp-linkmap.txt --kind linkmap --build-id <uuid>
    ```

    Kinds: `ips`, `dsym`, `xcresult`, `trace`, `buildlog`, `linkmap`. A compliance
    report goes through `orbit compliance scan --upload` instead.

    An `.xcresult`, an `.xcactivitylog` and a `.trace` carry no git of their own, so
    say which commit they measured or the run links to nothing:

    ```bash
    orbit upload build.xcresult --commit "$(git rev-parse HEAD)" --pr 142
    ```

    In CI the branch, the commit and the pull request are read from the environment
    already. The command prints what it resolved and where each part came from.

    Exit codes: `0` done, `1` usage (bad flag, unknown kind, missing file), `2` auth
    (no token, or it was rejected), `3` the transfer failed, `4` the API refused.
    Never retry a `1`, a `2` or a `4` unchanged: fix the cause.

    ## Keeping memory in sync

    ```bash
    orbit memory pull          # write AGENTS.md, CLAUDE.md and .serena/memories from Orbit
    orbit memory push          # import the markdown this repo already has
    orbit memory push --activate
    ```

    `AGENTS.md` and `CLAUDE.md` are **generated**: they carry a header saying so,
    and the next `pull` overwrites them. Never hand-edit a generated file. Change
    the memory in the console, or write the section in a file that is not generated
    and `push` it. Push is idempotent by slug, so pushing twice updates instead of
    duplicating, and imports land as drafts unless `--activate` is passed.

    Writing memory from here follows the same rules the tools state:

    - **Durable facts only.** Decisions and why they were taken, conventions the
      code follows, gotchas that cost someone an afternoon. Never what you are doing
      this afternoon, what is left on a branch, or which test is currently red.
    - **Never a secret.** A write carrying one is refused.
    - **Cite a source** for every claim: a file, a commit, a review, a run, a crash,
      a session or a URL. A memory nobody can check is a memory nobody can retire.
    - `memory_search` first. If it is already written down, `memory_update` it; if
      this replaces something, pass `supersedesSlug`.
    - At most three memories per task. The `remember_after_task` prompt is that
      step.

    Anything you write arrives in the console marked as agent-authored, with the
    token's name and the tool that made it, for a person to activate or archive.

    ## Rules

    - Every paid tool estimates first and runs only with `confirm: true`. Show the
      price to the person before confirming. With a project token a paid tool
      answers `needs_user` and a console link, which is an answer, not a failure.
    - Ask before anything that leaves the working tree: a commit, a pull request
      comment, a request sent to another agent.
    - Prefer one narrow read over three wide ones. Every tool call counts against
      1,200 requests a minute.
    - Do not paste a project token into a file that gets committed. Set
      `ORBIT_TOKEN`, or sign in with `orbit login`.
    ````
  </Tab>

  <Tab title="Cursor">
    Save as `.cursor/rules/orbit.mdc`. It must be `.mdc`: a plain `.md` file in `.cursor/rules` has no frontmatter to carry the description, so Cursor ignores it. `alwaysApply: false` means the agent reads the description and decides, rather than paying for the rule on every file.

    ````markdown .cursor/rules/orbit.mdc theme={null}
    ---
    description: How to use the Parsaa Orbit MCP tools: read a code review, triage a crash or a hang, upload an artifact with orbit upload, and keep the project's memory in sync. Apply when the task touches a review finding, a crash, a failing test run, a build, a screen, or what this team already decided.
    alwaysApply: false
    ---

    # Orbit

    Orbit holds what this app did in the field and what this team decided about it:
    reviews with findings, crash groups with symbolicated frames, telemetry sessions
    and vitals, test runs, builds, a map of the app's screens, and the project's
    memory. It is reachable over MCP at
    `https://platform.parsaa.app/api/orbit/mcp`. Read it instead of guessing, and
    read it before proposing a change.

    - A **project token** names one project, so `project_id` can be omitted, and it
      can never spend credits. A **sign-in session** (`orbit login`) reaches every
      project the person is a member of, so pass `project_id` on every call.
    - Scopes decide the tool list: `read` for the read tools, `write` for the free
      actions. A missing tool is a missing scope, not a broken server.
    - Lists default to 20 rows and cap at 100, timelines page with `next_offset`,
      and no answer exceeds 64 KB. Ask narrow questions.

    ## Before proposing anything

    - `memory_search` with the question in whole sentences, not keywords. A decision
      or convention that already covers it is what makes a suggestion fit this
      codebase.
    - `memory_instructions` is the compiled instruction bundle, the same text
      `orbit memory pull` writes to `AGENTS.md`.
    - `orbit_list_learnings` is the reviewer's rules for this project. Read them
      before disagreeing with a finding.

    ## Which tool answers which question

    | Question | Call |
    |---|---|
    | What did the reviewer say about this pull request? | `orbit_list_reviews`, then `orbit_get_review` |
    | What is crashing, and where? | `orbit_list_crash_groups`, then `orbit_get_crash_group` |
    | Why is the app hanging or slow? | `orbit_list_issues`, `orbit_vitals`, `orbit_get_profile` |
    | What happened in one session, or to one person? | `orbit_get_session`, `orbit_get_user` |
    | Which tests failed, on which commit? | `orbit_list_tests`, then `orbit_test_cases` |
    | Did the build regress? | `orbit_list_builds`, `orbit_get_build` |
    | Which screen is this, and is it covered? | `orbit_atlas_map`, `orbit_atlas_screen` |
    | Anything at all, by file path or symbol | `orbit_search` |
    | What did this team decide? | `memory_search`, `memory_get` |
    | Where does the project stand? | `orbit_project_overview` |

    ## Reading a review

    1. `orbit_list_reviews` for the queue: merge-confidence score, zone (`green`,
       `amber`, `red`), findings by severity. Narrow with `prNumber`.
    2. `orbit_get_review` for the walkthrough, the checks that ran, and every
       finding with its file and line, severity, rationale and suggested patch. Its
       finding ids are what the actions take.
    3. Work highest severity first. Either change the code and say which finding the
       change answers, or record the decision with `orbit_set_finding_state`
       (`open`, `accepted`, `dismissed`, `fixed`). `accepted` and `dismissed` need a
       `reason`, and the reason becomes a project rule unless `teach: false`, so
       write it for the next reader.
    4. `orbit_apply_suggestion` commits the patch to the pull request's branch
       through the GitHub App, and `orbit_send_finding_to_agent` hands the finding to
       the Parsaa macOS app. Both leave the working tree: ask a person first.

    Requesting a review is paid: `orbit_estimate_review`, show the credits, then
    `orbit_request_review` with `confirm: true`.

    ## Triaging a crash

    1. `orbit_list_crash_groups`, filtered by `status` (`new`, `open`, `resolved`,
       `ignored`), sorted by `report_count` or `last_seen`, or searched with `q`.
       Weigh a group by reports and by how many devices and versions carry it.
    2. `orbit_get_crash_group` for the symbolicated leading frames, the breadcrumbs,
       the screen, the sessions, and any analysis already run over it. Read that
       before paying for another.
    3. Widen with `orbit_get_session`, `orbit_atlas_screen`, `orbit_vitals` and
       `orbit_fleet`.
    4. Answer what the crash is (the first frame in first-party code, not the top
       frame in a system library), what reproduces it, and which version introduced
       it. Then propose the fix with a test that fails without it.

    Unsymbolicated frames mean the debug symbols never arrived: `orbit upload
    MyApp.app.dSYM`. Hangs are the same walk through `orbit_list_issues` and
    `orbit_get_profile`. `orbit_analyze_crash` and `orbit_analyze_trace` cost
    credits: estimate, show the number, then confirm.

    ## Uploading with orbit upload

    One command, not one per kind. The kind is inferred from the path.

    ```bash
    orbit upload crash.ips
    orbit upload MyApp.app.dSYM
    orbit upload build.xcresult --wait
    orbit upload profile.trace --wait
    orbit upload Build.xcactivitylog
    orbit upload MyApp-linkmap.txt --kind linkmap --build-id <uuid>
    ```

    Kinds: `ips`, `dsym`, `xcresult`, `trace`, `buildlog`, `linkmap`. A compliance
    report goes through `orbit compliance scan --upload`.

    An `.xcresult`, an `.xcactivitylog` and a `.trace` carry no git, so name the
    commit or the run links to nothing:
    `orbit upload build.xcresult --commit "$(git rev-parse HEAD)" --pr 142`. CI
    environments are read automatically.

    Exit codes: `0` done, `1` usage, `2` auth, `3` transfer failed, `4` the API
    refused. Fix the cause rather than retrying unchanged.

    ## Keeping memory in sync

    ```bash
    orbit memory pull       # write AGENTS.md, CLAUDE.md and .serena/memories from Orbit
    orbit memory push       # import the markdown this repo already has
    ```

    `AGENTS.md` and `CLAUDE.md` are generated and carry a header saying so; the next
    pull overwrites them, so never hand-edit one. Change the memory in the console,
    or push a file that is not generated. Push is idempotent by slug and lands
    drafts unless `--activate`.

    Writing memory through `memory_write`: durable facts only (decisions and their
    reasoning, conventions, gotchas), never transient task state, never a secret,
    always at least one source, `memory_search` first, `supersedesSlug` when it
    replaces something, and at most three per task.

    ## Rules

    - Paid tools estimate first and run only with `confirm: true`. Show the price
      before confirming. A project token gets `needs_user` and a console link, which
      is an answer rather than a failure.
    - Ask before anything that leaves the working tree.
    - Do not paste a project token into a committed file. Use `ORBIT_TOKEN` or
      `orbit login`.
    ````
  </Tab>

  <Tab title="Codex">
    Paste as a section of `AGENTS.md` at the root of the repository. Keep it to one `## ` heading: `orbit memory push` splits that file on `## ` into one memory per section, so a second top level heading here becomes a second memory.

    ````markdown AGENTS.md theme={null}
    ## Orbit

    This project reports to [Parsaa Orbit](https://platform.parsaa.app): code
    reviews with findings, crash groups with symbolicated frames, telemetry sessions
    and vitals, test runs, builds, a map of the app's screens, and the project's own
    memory. Orbit is reachable over MCP at
    `https://platform.parsaa.app/api/orbit/mcp`, so read it instead of guessing, and
    read it before proposing a change.

    A **project token** names one project, so `project_id` can be omitted, and it can
    never spend credits. A **sign-in session** (`orbit login`) reaches every project
    you are a member of, so pass `project_id` on every call. Scopes decide the tool
    list: `read` for the read tools, `write` for the free actions. Lists default to
    20 rows and cap at 100, timelines page with `next_offset`, and no answer exceeds
    64 KB, so ask narrow questions.

    ### Before proposing anything

    Call `memory_search` with the question in whole sentences rather than keywords: a
    decision or a convention that already covers it is what makes a suggestion fit
    this codebase. `memory_instructions` returns the compiled instruction bundle, and
    `orbit_list_learnings` returns the reviewer's rules for this project, which are
    worth reading before disagreeing with a finding.

    ### Which tool answers which question

    | Question | Call |
    |---|---|
    | What did the reviewer say about this pull request? | `orbit_list_reviews`, then `orbit_get_review` |
    | What is crashing, and where? | `orbit_list_crash_groups`, then `orbit_get_crash_group` |
    | Why is the app hanging or slow? | `orbit_list_issues`, `orbit_vitals`, `orbit_get_profile` |
    | What happened in one session, or to one person? | `orbit_get_session`, `orbit_get_user` |
    | Which tests failed, on which commit? | `orbit_list_tests`, then `orbit_test_cases` |
    | Did the build regress? | `orbit_list_builds`, `orbit_get_build` |
    | Which screen is this, and is it covered? | `orbit_atlas_map`, `orbit_atlas_screen` |
    | Anything at all, by file path or symbol | `orbit_search` |
    | What did this team decide? | `memory_search`, `memory_get` |
    | Where does the project stand? | `orbit_project_overview` |

    ### Reading a review

    `orbit_list_reviews` is the queue: one row per pull request, with its
    merge-confidence score, its zone (`green`, `amber`, `red`) and its findings by
    severity. `orbit_get_review` is the review itself: the walkthrough, the checks
    that ran, and every finding with its file and line, severity, rationale and
    suggested patch.

    Work the findings highest severity first. For each one, either change the code
    and say which finding the change answers, or record the decision with
    `orbit_set_finding_state` (`open`, `accepted`, `dismissed`, `fixed`). `accepted`
    and `dismissed` need a `reason`, and that reason becomes a project rule unless
    `teach: false` is passed, so write it for the next reader.

    `orbit_apply_suggestion` commits the patch to the pull request's branch through
    the GitHub App, and `orbit_send_finding_to_agent` hands the finding to the Parsaa
    macOS app. Both leave the working tree: ask a person first. Requesting a review
    is paid, so `orbit_estimate_review`, show the credits, then
    `orbit_request_review` with `confirm: true`.

    ### Triaging a crash

    1. `orbit_list_crash_groups`, filtered by `status` (`new`, `open`, `resolved`,
       `ignored`), sorted by `report_count` or `last_seen`, or searched with `q`.
       Weigh a group by its reports and by how many devices and app versions carry
       it, not by how recent it is.
    2. `orbit_get_crash_group` for the symbolicated leading frames, the breadcrumbs
       before the crash, the screen, the sessions, and any analysis already run over
       it. Read that before paying for another one.
    3. Widen with `orbit_get_session`, `orbit_atlas_screen`, `orbit_vitals` and
       `orbit_fleet`.
    4. Answer what the crash is (the first frame in first-party code, not the top
       frame in a system library), what reproduces it, and which version introduced
       it. Then propose the fix and a test that fails without it.

    Unsymbolicated frames mean the build's debug symbols never arrived: upload them
    with `orbit upload MyApp.app.dSYM`. Hangs are the same walk through
    `orbit_list_issues` and `orbit_get_profile`. `orbit_analyze_crash` and
    `orbit_analyze_trace` cost credits: estimate, show the number, then confirm.

    ### Uploading with orbit upload

    One command, not one per kind. The kind is inferred from the path.

    ```bash
    orbit upload crash.ips
    orbit upload MyApp.app.dSYM
    orbit upload build.xcresult --wait
    orbit upload profile.trace --wait
    orbit upload Build.xcactivitylog
    orbit upload MyApp-linkmap.txt --kind linkmap --build-id <uuid>
    ```

    Kinds: `ips`, `dsym`, `xcresult`, `trace`, `buildlog`, `linkmap`. A compliance
    report goes through `orbit compliance scan --upload` instead.

    An `.xcresult`, an `.xcactivitylog` and a `.trace` carry no git of their own, so
    name the commit or the run links to nothing:
    `orbit upload build.xcresult --commit "$(git rev-parse HEAD)" --pr 142`. In CI
    the branch, the commit and the pull request are read from the environment.

    Exit codes: `0` done, `1` usage, `2` auth, `3` the transfer failed, `4` the API
    refused. Fix the cause rather than retrying unchanged.

    ### Keeping memory in sync

    ```bash
    orbit memory pull       # write AGENTS.md, CLAUDE.md and .serena/memories from Orbit
    orbit memory push       # import the markdown this repo already has
    ```

    When `AGENTS.md` and `CLAUDE.md` are generated by `orbit memory pull` they carry
    a header saying so, and the next pull overwrites them, so never hand-edit a
    generated file: change the memory in the console, or push a file that is not
    generated. Push is idempotent by slug, so pushing twice updates rather than
    duplicates, and imports land as drafts unless `--activate` is passed.

    Writing memory through `memory_write` means durable facts only (decisions and
    their reasoning, conventions the code follows, gotchas that cost someone an
    afternoon), never transient task state, never a secret, always at least one
    source, `memory_search` first, `supersedesSlug` when it replaces something, and
    at most three memories per task.

    ### Rules

    - Paid tools estimate first and run only with `confirm: true`. Show the price
      before confirming. A project token gets `needs_user` and a console link, which
      is an answer rather than a failure.
    - Ask before anything that leaves the working tree: a commit, a pull request
      comment, a request sent to another agent.
    - Do not paste a project token into a file that gets committed. Set
      `ORBIT_TOKEN`, or sign in with `orbit login`.
    ````
  </Tab>
</Tabs>

## What the skill actually teaches

Five things, in the order an agent needs them.

<AccordionGroup>
  <Accordion title="Read memory before proposing anything">
    `memory_search` with the question in whole sentences rather than keywords, because the search reads meaning as well as text. A decision or a convention that already covers the question is the difference between a suggestion that fits this codebase and one that reads as generic. `memory_instructions` is the compiled instruction bundle, and `orbit_list_learnings` is the reviewer's own rules for the project, worth reading before disagreeing with a finding.
  </Accordion>

  <Accordion title="Which tool answers which question">
    A short table: reviews through `orbit_list_reviews` then `orbit_get_review`, crashes through `orbit_list_crash_groups` then `orbit_get_crash_group`, hangs through `orbit_list_issues` and `orbit_get_profile`, sessions and people, tests and builds, screens through `orbit_atlas_map`, anything at all by file path or symbol through `orbit_search`. Plus the shape of an answer: lists default to 20 rows and cap at 100, timelines page with `next_offset`, and nothing over 64 KB comes back at once.
  </Accordion>

  <Accordion title="How to read a review">
    The queue carries a merge-confidence score and a zone; the review itself carries the walkthrough, the checks that ran, and every finding with its file and line, severity, rationale and suggested patch. Work highest severity first. Either change the code and say which finding the change answers, or record the decision with `orbit_set_finding_state`, remembering that the reason on an `accepted` or `dismissed` finding becomes a project rule unless `teach` is false. And that two actions leave the working tree: `orbit_apply_suggestion` commits to the pull request's branch, `orbit_send_finding_to_agent` hands the finding to the Parsaa app. Both wait for a person.
  </Accordion>

  <Accordion title="How to triage a crash">
    Weigh a group by its reports and by how many devices and app versions carry it, not by how recent it is. Read the group before paying for an analysis, because one may already be there. Then widen: the session for what the person was doing, the screen, the vitals and the fleet for which version and which devices. Answer three things before touching code, which is what the crash is (the first frame in first-party code, not the top frame in a system library), what reproduces it, and which version introduced it. Unsymbolicated frames mean the debug symbols never arrived, so upload the dSYM rather than reading addresses.
  </Accordion>

  <Accordion title="Uploads, and keeping memory in sync">
    There is one `orbit upload` command and the kind is inferred from the path, so an agent stops inventing a subcommand per artifact. An `.xcresult`, an `.xcactivitylog` and a `.trace` carry no git of their own, so the commit has to be named or the run links to nothing. On the memory side: `pull` writes the generated files and `push` imports what the repository has, idempotent by slug, and a write through `memory_write` is durable facts only, never transient task state, never a secret, always with a source.
  </Accordion>
</AccordionGroup>

## Keeping them in step

The skills name tools and orders of operations. They deliberately leave argument shapes to the schemas, because each tool carries its own description and arguments at call time, generated from Orbit's OpenAPI document. So the reference cannot drift from the server, and the skill only has to stay right about the map.

When Orbit ships new copy, `orbit skills install` picks it up: a destination still holding what it installed is upgraded in place, one you have edited is skipped until you pass `--force`, and the `AGENTS.md` section is replaced between its markers with the rest of the file left alone. Running it after every CLI upgrade is safe, and prints nothing but `unchanged` when there is nothing to do.

<CardGroup cols={2}>
  <Card title="MCP and agents" icon="robot" href="/orbit/mcp-and-agents">
    The endpoint, the two credentials, scopes, and every tool group.
  </Card>

  <Card title="The orbit CLI" icon="terminal" href="/orbit/cli">
    `orbit skills install`, uploads, the stdio MCP bridge and memory sync.
  </Card>
</CardGroup>
