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

# Topics

> CRUD, governance, relations, and the topic graph.

<Note>
  The canonical path is `/topics`. `/watchers` still works as a deprecated alias for old CLIs and is removed in a later release.
</Note>

## Core CRUD

| Method   | Path                              | Purpose                                                                                                                                                        |
| -------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET`    | `/workspaces/:slug/topics`        | List topics (visible to the caller), relevance-ranked (drifted-first). `?limit=&offset=` bounds the page; archived topics are hidden unless `?status=archived` |
| `POST`   | `/workspaces/:slug/topics`        | Create a topic (a Note, or `status: proposed` to put it up for review)                                                                                         |
| `GET`    | `/workspaces/:slug/topics/:topic` | Get topic detail                                                                                                                                               |
| `PATCH`  | `/workspaces/:slug/topics/:topic` | Update a topic                                                                                                                                                 |
| `DELETE` | `/workspaces/:slug/topics/:topic` | Delete a topic                                                                                                                                                 |

The read response is the canonical context. It includes a flat `trust` verdict (`reviewed` | `proposed` | `draft`) plus `classification.status` and a `governance` block: the trust signal an agent consumes. Key on `trust` directly:

```json theme={"theme":"github-light"}
{
  "trust": "reviewed",
  "classification": { "status": "reviewed" },
  "governance": { "authoritative": true, "approved_by": "u_cto", "approved_at": "..." }
}
```

## Search & Matching

| Method | Path                                   | Purpose                                                                                                                                                                                                                |
| ------ | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET`  | `/workspaces/:slug/topics/search`      | Full-text search, relevance-ranked. `?tags=a,b` scopes to topics carrying ANY of those tags; `?limit=` caps the result set (default 50); `?stale=true\|false` filters by freshness; archived topics are never returned |
| `POST` | `/workspaces/:slug/topics/match-files` | Match files to topics                                                                                                                                                                                                  |

`GET /workspaces/:slug/topics` also accepts `?tags=a,b` (comma-separated, OR semantics). Tag names are normalized server-side (lowercase, whitespace→dashes).

## Tags

The workspace tag registry: tags as first-class objects so they can be pre-created with a description before any topic uses them. Attaching an unregistered tag via a topic write auto-registers it.

| Method   | Path                           | Purpose                                                                                                                         |
| -------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `GET`    | `/workspaces/:slug/tags`       | List with per-tag topic counts, paginated (`?limit=&offset=`, default 50, most-used first), returns `{ tags, total, has_more }` |
| `POST`   | `/workspaces/:slug/tags`       | Create `{ name, description? }`, idempotent (existing tag merges the description)                                               |
| `PATCH`  | `/workspaces/:slug/tags/:name` | Rename (`{ name }`, rewrites every topic carrying the tag; owner/admin) and/or describe (`{ description }`)                     |
| `DELETE` | `/workspaces/:slug/tags/:name` | Delete + detach from every topic (owner/admin)                                                                                  |

## Health & Graph

| Method | Path                              | Purpose              |
| ------ | --------------------------------- | -------------------- |
| `GET`  | `/workspaces/:slug/topics/audit`  | Context health audit |
| `GET`  | `/workspaces/:slug/topics/events` | Topic event timeline |
| `GET`  | `/workspaces/:slug/topics/graph`  | Topic graph          |

## Governance

A topic becomes Knowledge only once an owner/admin merges it in. See [Governance](/concepts/governance). `approve` / `reject` and Suggested-edit `merge` / `reject` require owner/admin authority. They succeed for an owner/admin principal on any surface (dashboard, owned CLI key, or an OAuth/MCP token the owner/admin authorized), and the merge is stamped `approved_via` (`human` or `agent`). A faceless or non-owner principal is rejected.

| Method | Path                                                   | Purpose                                      |
| ------ | ------------------------------------------------------ | -------------------------------------------- |
| `POST` | `/workspaces/:slug/topics/:topic/propose`              | `draft → proposed`                           |
| `POST` | `/workspaces/:slug/topics/:topic/approve`              | `→ reviewed` (reviewed)                      |
| `POST` | `/workspaces/:slug/topics/:topic/reject`               | `proposed → draft`                           |
| `POST` | `/workspaces/:slug/topics/:topic/archive`              | `→ archived`                                 |
| `GET`  | `/workspaces/:slug/topics/:topic/proposals`            | List Suggested edits                         |
| `POST` | `/workspaces/:slug/topics/:topic/proposals`            | Open a Suggested edit (`{ summary, patch }`) |
| `POST` | `/workspaces/:slug/topics/:topic/proposals/:id/merge`  | Merge a Suggested edit                       |
| `POST` | `/workspaces/:slug/topics/:topic/proposals/:id/reject` | Close a Suggested edit                       |

## Relations

| Method   | Path                                                    | Purpose              |
| -------- | ------------------------------------------------------- | -------------------- |
| `POST`   | `/workspaces/:slug/topics/:topic/relations`             | Add a typed relation |
| `GET`    | `/workspaces/:slug/topics/:topic/relations`             | List relations       |
| `DELETE` | `/workspaces/:slug/topics/:topic/relations/:relationId` | Delete a relation    |

<Note>
  `POST /topics` and `PATCH /topics/:topic` responses may include `anchor_validation`: per-pattern match counts against the repo's default branch (`ok` / `overbroad` / `zero`, with samples and warnings). Advisory only: it never blocks the write, and it's omitted when no repo is linked. `POST …/relations` is reachable by OAuth (MCP) principals with `topics:write`; deleting relations stays human-only.
</Note>

## Share

| Method   | Path                                    | Purpose                        |
| -------- | --------------------------------------- | ------------------------------ |
| `POST`   | `/workspaces/:slug/topics/:topic/share` | Create a public read-only link |
| `DELETE` | `/workspaces/:slug/topics/:topic/share` | Revoke the link                |
| `GET`    | `/s/:token`                             | Public page (no auth)          |
| `GET`    | `/s/:token/raw`                         | Public markdown (no auth)      |
