Repository navigation
feat(documents)!: no 10,000-entry ceiling on a documents account - #2944
Merged
Merged
Conversation
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
force-pushed
the
feat/documents-catalog-no-ceiling
branch
from
November 14, 2026 05:37
56ca2f5 to
22a7e06
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.listabove 10,000 entries / 32 MB,catalog.reconcileand 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 inlistis gone (it also counted the whole account on every page);reconciletakes any number of ids.src/services/documents/ingestion.ts: the import takes any number of files, upserting and reportingobserved200 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 newnotes.fileNote(folderId, path)(src/store/sqlite/file-note.ts, indexed by the documents key, or the files row of a local folder).docs/dev/DOCUMENTS.md: the<id>.mdexternal 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 ownNotesStoreimplementation must addfileNote; thecatalog.scope-limiterror 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
src/services/documents/ingestion-scale.test.ts: 10,050 entries import, list past 10,000, save twice to the same document, retire one by re-import, remove.src/store/catalog.test.ts: the reconcile-over-10,000 case now expects success.src/services/documents src/documents src/store2116 passed before the last test update, then the touched files 112 passed; biome, docs checks green.🤖 Generated with Claude Code