**Class:** unstated · **Severity:** cosmetic
**Flow:** arch-f220a644d654 · **Step:** scale
**Question:** None · **Frequency:** n/a

## Finding

No stated corpus ceiling. `context` loads every active embedding into memory per call and `lint --deep` is O(n²) over them; neither is paginated, capped or benchmarked.

## What happens today

repositories.py:309-320 selects all active vectors; similarity_lint.py:36-40 compares every pair.

## Impact

Fine at the 'thousands of documents' scale the id-entropy comment assumes (identifiers.py:23-25). That assumption is stated in a comment about ids and nowhere else.

## Proposed default

State the supported corpus size in the README.

## Resolution

FIXED 2026-07-29 properly, at the maintainer's direction, who expects much larger corpora than the "thousands of documents" the original assumption allowed for. Pagination is real, not documented-away. `query` and `search` take `--limit`/`--offset`, and `tag list` — which had no window at all — now pages too. `query`'s window is a SQL LIMIT/OFFSET applied *in* the statement: it previously fetched every match and sliced in Python, so the cost of a page grew with the corpus behind it. `DocumentFilter` carries the window, and `limit=None` still means "everything" for the maintenance paths, which genuinely need every row. TWO PREDICATES CANNOT USE A SQL WINDOW, and both would have been silently wrong: `--stale` derives from the clock and the type's cadence, and `search`'s status filter runs after FTS5 (which cannot see a status). A SQL OFFSET on either would count *rows scanned* rather than rows returned — the same class of ordering bug issue-b4f441c7210f fixed once for `--limit`. Both page over the filtered set instead, and the stale path is pinned by a fixture that interleaves overdue and fresh documents, which a naive window mis-pages. NO TOTAL IN THE RESPONSE: it is a bare JSON array with nowhere to put one, and a wrapper would break every caller. A page shorter than `--limit` means the end; stated in the CLI help, the guide and the README. STILL UNBOUNDED, and stated rather than hidden: `context` loads every current embedding per call, which is what sets the practical corpus ceiling — capping it would break the semantic recall that adr-ab9c454b760c exists for. `lint --deep` remains O(n²) over those vectors. Both are now named in the README's "Scope and limits" instead of living in a comment about id entropy.

## Actors affected

- AI coding agent
- repository maintainer

## Evidence

- `src/docir/platform/persistence/repositories.py:309-320`
- `src/docir/modules/documents/domain/services/similarity_lint.py:33-53`

---

Migrated from the discovery gap register (GAP-039); the register itself now lives in this store.