# Data model

Collections, bookmarks, chunks, and the index lifecycle.

## Collections

A collection is a flat, named group of bookmarks — `id`, `name`, `description`,
`created_at`, `updated_at`. There is no nesting; the extension's tree view shows
collections with their bookmarks expanded, not sub-collections.

Deleting a collection deletes its bookmarks, their chunks, and the backing
Chroma collection.

## Bookmarks

A bookmark belongs to one collection: `url`, `title`, `favicon_url`, `added_at`,
`indexed_at`, `index_status`, `error_message`. The daemon also keeps the page's
raw HTML so a re-index can fall back to it when a re-fetch fails.

## Chunks

Indexing splits a page's extracted text into chunks. Each chunk is stored twice:

- a **row in SQLite** (text + its Chroma id), and
- a **vector in Chroma**, id `"<bookmark_id>-<n>"`, with metadata
  `{url, title, bookmark_id, injection_risk, injection_signals}`.

Because Chroma ids are positional, a re-index deletes the bookmark's existing
vectors before writing new ones — otherwise a shorter re-scrape would leave
stale chunks behind that still answer searches.

## Index lifecycle

```
pending ──▶ indexing ──▶ done
                    └───▶ error   (error_message set; retry from the row menu)
```

A daemon that stops mid-index leaves a bookmark in `indexing`.
[`vacuum`](/docs/reference/cli/) resets those to `error` so you can retry them.
