DocumentHistoryView.tsxfix: close the findings from reviewing the fixes themselves A second review pass, this time over the ten fix commits — which were unreviewed code, and which is where the worst finding was. Caps enforced in one place each, missing the path their own docstring cites. The cell-length limit lived only in `applyCellWrites`, so an agent bypassed it by choosing `add_rows` over `set` — those rows go through `materializeRow`, which checked the column name and not the value. Both now call one `assertCellLength`. The column cap lived only in `applyTableOps`, which the import path never reaches: it goes `writeDocument` → `writeFileAsYjs` → `writeTable`, so the "1,000x300 import" the docstring describes was still uncapped. Now checked in `table-import.ts` alongside the row cap. `rename_column` was the one route left to give a column a reserved label — the guard was added to `create` and `add_columns` in the same commit and not there, so the invariant its error message asserts was not actually held. The invalidation hook in `next-step-sync` fires inside `applyUpdate`'s transaction, and it detaches a chain that opens its own connection — so it could read the pre-commit row and cache the stale value back into every bound cell with nothing left to re-fire. Queued as a `postCommitEffect` instead. The five sibling call sites added in the same commit are all on auto-commit connections and were already right. `focusCellAbove`/`focusCellLeft` were added by the keyboard/ARIA commit and never wired to anything — arrow-key cell navigation does not exist, so they were dead code claiming otherwise. Deleted rather than left as a promise. The gutter also needed `role="gridcell"`: `aria-colcount` counts it as column 1 and the data cells start at 2, so without it the row declared a cell that did not exist. And two `_`-prefixed unused bindings in test files I wrote, which the repo forbids outright. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 15, 2026, 2:24 PMHistoryDiffView.tsxrefactor: consolidate document code into documents/ + add {{ event mention Frontend: move the editor primitive, file-link/, mention/, yjs/, and history/ under apps/mail/modules/documents/ so every doc-editor concern lives in one place. Rename AgendaConversationMention -> ConversationMention and generalize it to take an onSelect callback so the agenda keeps its task-promotion dispatch while regular docs insert a plain conversationNode chip. Backend: rename services/document-store/ -> services/documents/ and absorb services/sse/doc-event-bus.ts + services/sse/doc-events-delta.ts alongside their tests. New: {{ event mention in documents. Custom Tiptap suggestion matcher requires the literal {{ prefix; picker shows a type-icon, title, conversation context, and relative time; selecting inserts an eventNode chip. New tRPC route crm.searchEventsForMention runs a global search across the user's crm_events (emails, slack, meetings, calls, notes, custom) joined to company info. crm_conversation_updates lives in its own table and stays excluded by design. Co-Authored-By: Claude Opus 4.7 (1M context) <<email>>May 26, 2026, 9:30 AMHistorySidebar.tsxrefactor: consolidate document code into documents/ + add {{ event mention Frontend: move the editor primitive, file-link/, mention/, yjs/, and history/ under apps/mail/modules/documents/ so every doc-editor concern lives in one place. Rename AgendaConversationMention -> ConversationMention and generalize it to take an onSelect callback so the agenda keeps its task-promotion dispatch while regular docs insert a plain conversationNode chip. Backend: rename services/document-store/ -> services/documents/ and absorb services/sse/doc-event-bus.ts + services/sse/doc-events-delta.ts alongside their tests. New: {{ event mention in documents. Custom Tiptap suggestion matcher requires the literal {{ prefix; picker shows a type-icon, title, conversation context, and relative time; selecting inserts an eventNode chip. New tRPC route crm.searchEventsForMention runs a global search across the user's crm_events (emails, slack, meetings, calls, notes, custom) joined to company info. crm_conversation_updates lives in its own table and stays excluded by design. Co-Authored-By: Claude Opus 4.7 (1M context) <<email>>May 26, 2026, 9:30 AMuseDocumentHistory.tsrefactor: consolidate document code into documents/ + add {{ event mention Frontend: move the editor primitive, file-link/, mention/, yjs/, and history/ under apps/mail/modules/documents/ so every doc-editor concern lives in one place. Rename AgendaConversationMention -> ConversationMention and generalize it to take an onSelect callback so the agenda keeps its task-promotion dispatch while regular docs insert a plain conversationNode chip. Backend: rename services/document-store/ -> services/documents/ and absorb services/sse/doc-event-bus.ts + services/sse/doc-events-delta.ts alongside their tests. New: {{ event mention in documents. Custom Tiptap suggestion matcher requires the literal {{ prefix; picker shows a type-icon, title, conversation context, and relative time; selecting inserts an eventNode chip. New tRPC route crm.searchEventsForMention runs a global search across the user's crm_events (emails, slack, meetings, calls, notes, custom) joined to company info. crm_conversation_updates lives in its own table and stays excluded by design. Co-Authored-By: Claude Opus 4.7 (1M context) <<email>>May 26, 2026, 9:30 AMuseVersionDiff.tsrefactor: consolidate document code into documents/ + add {{ event mention Frontend: move the editor primitive, file-link/, mention/, yjs/, and history/ under apps/mail/modules/documents/ so every doc-editor concern lives in one place. Rename AgendaConversationMention -> ConversationMention and generalize it to take an onSelect callback so the agenda keeps its task-promotion dispatch while regular docs insert a plain conversationNode chip. Backend: rename services/document-store/ -> services/documents/ and absorb services/sse/doc-event-bus.ts + services/sse/doc-events-delta.ts alongside their tests. New: {{ event mention in documents. Custom Tiptap suggestion matcher requires the literal {{ prefix; picker shows a type-icon, title, conversation context, and relative time; selecting inserts an eventNode chip. New tRPC route crm.searchEventsForMention runs a global search across the user's crm_events (emails, slack, meetings, calls, notes, custom) joined to company info. crm_conversation_updates lives in its own table and stays excluded by design. Co-Authored-By: Claude Opus 4.7 (1M context) <<email>>May 26, 2026, 9:30 AM