Skip to content

feat(documents)!: no 10,000-entry ceiling on a documents account - #2944

Merged
leemour merged 2 commits into
mainfrom
feat/documents-catalog-no-ceiling
Nov 14, 2026
Merged

leemour merged 2 commits into
mainfrom
feat/documents-catalog-no-ceiling

Conversation

@leemour

@leemour leemour commented Nov 14, 2026

Copy link
Copy Markdown
Member

Task

notion-cli plan C10, owner's ruling NEED-2639 A: lift the per-account catalog ceiling and make the catalog import and the local document listing work in portions, so a sync goes past any total. A single call may stay bounded.

Why

A Notion workspace synced whole (the default, NEED-2636) passes 10,000 pages. cli-core refused such an account: catalog.list above 10,000 entries / 32 MB, catalog.reconcile and the ingestion import above 10,000 ids, and the ingestion listing stopped at 10,000. Drive has the same limit.

What

  • src/store/sqlite/catalog.ts: the per-account guard in list is gone (it also counted the whole account on every page); reconcile takes any number of ids.
  • src/services/documents/ingestion.ts: the import takes any number of files, upserting and reporting observed 200 at a time. The whole-account note cache is gone: it read every document (with text) in pages of 500 that each re-read all rows before them. Each save and removal now looks up its one document with the new notes.fileNote(folderId, path) (src/store/sqlite/file-note.ts, indexed by the documents key, or the files row of a local folder).
  • Per-call bounds stay: 200 entries per catalog write, 1000 per list page, 1 MB per entry.
  • docs/dev/DOCUMENTS.md: the <id>.md external id contract that the shared catalog commands rely on (lane L2 asked for it to be either documented or removed; documented here), and the bounds.
  • feat!: an own NotesStore implementation must add fileNote; the catalog.scope-limit error is no longer raised (the reason stays registered).

Measured

cli-testing#375, performance/documents/catalog-scale: before, over 10,000 entries cannot be imported. After, 100,000 entries import in 8.6 s with a 489 MB peak; 200 saves take 0.3 s at any size (2.4 s at 9,800 before, 37 s at 100,000 with the old listing); a list page takes 60 ms. The import runs on every sync, also when nothing changed (about 7 s at 100,000): the next thing to speed up, not a blocker.

Testing

🤖 Generated with Claude Code

leemour and others added 2 commits November 14, 2026 06:36
Owner's ruling NEED-2639 A (notion-cli plan C10). A Notion workspace
synced whole passes 10,000 pages; cli-core refused such an account.

- catalog.list drops its per-account guard (10,000 entries / 32 MB),
  which also counted the whole account on every page.
- catalog.reconcile and documentIngestion's catalog import take any
  number of ids; the import writes and reports `observed` 200 at a time.
- documentIngestion no longer reads every document of the account into
  memory before its first save (pages of 500 that each re-read all rows
  before them, capped at 10,000). Each save and removal looks up its one
  document with the new notes.fileNote(folderId, path), through the
  documents (account_id, external_id) key or the files row of a local
  folder (src/store/sqlite/file-note.ts).
- Per-call bounds stay: 200 entries per catalog write, 1000 per list
  page, 1 MB per entry.
- DOCUMENTS.md states the `<id>.md` external id contract the shared
  catalog commands rely on, and the bounds.

Measured in cli-testing performance/documents/catalog-scale: 100,000
entries import in 8.6 s with a 489 MB peak; 200 saves 0.3 s at any size
(2.4 s at 9,800 before; 37 s at 100,000 with the old listing); a list
page 60 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The catalog import reads each entry back only when the binding gave
  an `observed` callback (100,000 wasted reads per sync otherwise).
- The test now reaches notes.fileNote on a documents account: it reads
  the note back and checks that a changed save marks the document's
  memory stale, which fails if fileNote finds nothing.
- The unused reason `catalog.scope-limit` is removed.
- The changelog and DOCUMENTS.md say the store sets no ceiling, while a
  sync still walks at most the `maxEntries` its CLI passes (drive 10,000).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@leemour
leemour force-pushed the feat/documents-catalog-no-ceiling branch from 56ca2f5 to 22a7e06 Compare November 14, 2026 05:37
@leemour
leemour merged commit 7b6f89b into main Nov 14, 2026
43 checks passed
@leemour
leemour deleted the feat/documents-catalog-no-ceiling branch November 14, 2026 06:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant