---
name: dorsal
description: Current field evidence from AI builders, repositories, docs and research, read over HTTP from the Dorsal graph. Use when the user starts a message with the word "dorsal", asks to check a technical decision against current evidence, or asks what builders report about a library, model, tool, MCP server, agent framework, bug or recent change.
---

# Dorsal

Dorsal is a live graph of what builders ship, break and fix: dated events with source links, named
objects (products, models, repos, methods, problems), and documentation passages. You call it with the
bundled script. You do the reasoning; Dorsal only returns records.

## Setup

- The script reads the key from `DORSAL_API_KEY` or from `~/.dorsal/api-key`. If it reports `setup_error`,
  pass on its message. Never ask for the key in the chat and never print or read the key file.
- `DORSAL_API_URL` is optional. The default is `https://api.dorsal.us`.
- The script is `scripts/dorsal.sh` in this skill's directory. Call it by its full path.

## Privacy

Everything you send leaves the machine. Send only generalized technical searches: public products,
models, libraries, methods, error patterns and questions. Never send code, file paths, repository
names that are private, credentials, customer data, internal names or proprietary requirements.
Translate "our billing service on Postgres 16 times out under PgBouncer" into
"PgBouncer transaction pooling timeouts with Postgres 16".

## Routing

- Message starts with "dorsal": run `dorsal.sh protocol dorsal investigate` (use `improve` for
  "dorsal improve …") and follow the contract it returns.
- User asks to verify or check a decision: run `dorsal.sh protocol decision-verification` and follow it.
- Any other question: use the default method below.

Contracts name MCP tools. Map them: getSummaries → `summaries`, getSet → `set`,
getNeighbors → `neighbors`. Arguments are identical.

## Default method

1. Search with 2 or 3 complementary queries, each with `"total": 10`:
   current guidance, results and failures in practice, and the strongest case against the likely answer.

   ```bash
   S=<this skill's directory>
   "$S/scripts/dorsal.sh" summaries '{"query": "PgBouncer transaction pooling prepared statements", "total": 10}'
   ```

   Each call returns `results` with `kind` = `event`, `object` or `documentation_chunk`, plus `id`,
   `description`, `url` and `timestamp`. Filters: `event_types` (use `["capability_observed"]` for measured
   model results), `object_types`, `sources` (use `["docs"]` for documented product behavior),
   `since` / `until` (ISO dates). For a long result, pass `page_size` and follow `next_cursor`.
   Ids are labels for fetching records. Read an event's type from its `event_type` field, never from its id.

2. Fetch the records that decide the answer, usually 3 to 10 ids, at most 25 per call:

   ```bash
   "$S/scripts/dorsal.sh" set '{"ids": ["<id>", "<id>"]}'
   ```

3. Only when relationships matter (makers, alternatives, dependencies, a model's other results), traverse
   one named object. Set `include_events` to list its source-linked events:

   ```bash
   "$S/scripts/dorsal.sh" neighbors '{"query": "Claude Code", "include_events": true, "total": 20}'
   ```

   `{"error": "no object matched"}` means the name is unknown: take the exact name or id from a
   `summaries` result.

For a body with quotes, pass it on stdin instead of as an argument:

```bash
"$S/scripts/dorsal.sh" summaries <<'JSON'
{"query": "agent can't resume after context compaction", "total": 10}
JSON
```

## Reporting

- Lead with the answer. Support each claim with records you fetched, cited by source URL and date.
- Objects identify named things. Prove behavior with events or documentation passages.
- Say when evidence is thin, old or one-sided, and show the counterevidence you found.

## Errors

Non-200 responses print `{"error": {"type", "message"}}` on stderr and the script exits non-zero.
When you pipe the output into `jq`, the error still shows; read it before retrying.

- `invalid_request_error` (400): the message names the field and the fix. Fix the body and retry once.
- `authentication_error` (401): the key is missing, wrong or expired. Tell the user to get a new one at
  https://godorsal.com/docs/skill; do not retry.
- `rate_limit_error` (429) or `overloaded_error` (503): the script already retried twice. Wait a minute or
  report it.

Full field reference: [references/api.md](references/api.md).
