Parent
#328. Related: #230
What to build
A connected app's write reaches every reader at once, so the owner sees it with everyone else. Today the owner checks it in History Compare and undoes it with Restore. This issue measures whether owners undo connected-app writes often enough to need a preview. If they do, it records a design for an owner-only preview with Accept and Discard.
This issue is not a build. Its first step is a measurement and a ruling.
Acceptance criteria
Blocked by
None — can start now.
Agent brief
Type: HITL — a maintainer with production database access runs the query, and the maintainer rules on this issue. Proposed gate: Restores within 24 hours after an mcp version reach 5% of mcp versions. The maintainer may change the number.
Category: ruling
Current behavior:
-
An MCP write stores a version row with trigger = 'mcp' and triggeredBy set to the caller (apps/hocuspocus.server/src/modules/document-content/http/controller.ts:193).
-
A Restore stores a row with trigger = 'revert' (apps/hocuspocus.server/src/modules/document-versions/infra/versionOps.ts:182).
-
History labels those rows "Connected app" and "Restored" (apps/webapp/src/components/pages/history/components/HistorySidebarRowParts.tsx:89-96).
-
Retention thins unnamed rows older than DOC_AUTOSAVE_RETENTION_DAYS (default 30) to one per document per day (apps/hocuspocus.server/src/lib/retention.ts:62-90). An MCP tool write sets no name, so its row can be thinned. A revert row is named and stays. So count only the last 30 days.
-
Measurement query, on the Prisma table "Documents" (apps/hocuspocus.server/prisma/schema.prisma:11-30):
select
count(*) as mcp_versions,
count(*) filter (where exists (
select 1 from "Documents" r
where r."documentId" = m."documentId"
and r.trigger = 'revert'
and r."createdAt" > m."createdAt"
and r."createdAt" <= m."createdAt" + interval '24 hours'
)) as restored_within_24h
from "Documents" m
where m.trigger = 'mcp'
and m."createdAt" > now() - interval '30 days';
Run it on a read-only copy, not on the live primary. It counts every Restore in the 24-hour window, not only one that undid the connected-app write. So the second count is an upper bound.
Desired behavior: any preview design must meet these constraints.
- In a Yjs room, an applied edit is published at once. So the preview lives outside the shared document, and only the owner sees it.
- The preview is a decoration in the owner's editor. It adds no node type and no mark. A tab whose schema lacks a node type deletes that node from the shared document (
@tiptap/y-tiptap, the catch that calls _item.delete).
- Nothing is written to the room until the owner chooses Accept. For a section edit, Accept runs today's
edit_blocks or replace_text write path with the stored rev. A stale rev tells the owner the section changed.
- Discard deletes the proposal and writes nothing.
- Visitors and other members never see a proposal.
- Accept and Discard work by keyboard and on the phone, and read correctly in light and dark.
Where to start: edit_blocks and replace_text in apps/hocuspocus.server/src/modules/mcp/tools/documentTools.ts; the History Compare view under apps/webapp/src/components/pages/history/. Line numbers are hints as of 2026-09-28; the agent searches by symbol.
Rules that apply:
apps/webapp/src/components/TipTap/CLAUDE.md §Document Model And Migrations.
apps/webapp/CLAUDE.md §Document Version History.
apps/hocuspocus.server/CLAUDE.md §MCP Connector and §Retention and schema.
CONTEXT.md entries "Connected app" and "Restore".
.cursor/docs/design-system.md for any pad UI.
.cursor/skills/tech-writer/SKILL.md §Simplified English (house standard) for the design note.
Verify: gh issue view <this issue number> --comments shows the two counts and the maintainer's ruling. On "build", it also shows the design note and links to the build issues. This issue changes no code.
Out of scope
- Shared tracked changes. That is a separate strategy call, and it needs new marks.
- Building the preview. The build issues come from the design note, after the ruling.
- An AI model inside docs.plus.
Parent
#328. Related: #230
What to build
A connected app's write reaches every reader at once, so the owner sees it with everyone else. Today the owner checks it in History Compare and undoes it with Restore. This issue measures whether owners undo connected-app writes often enough to need a preview. If they do, it records a design for an owner-only preview with Accept and Discard.
This issue is not a build. Its first step is a measurement and a ruling.
Acceptance criteria
Blocked by
None — can start now.
Agent brief
Type: HITL — a maintainer with production database access runs the query, and the maintainer rules on this issue. Proposed gate: Restores within 24 hours after an
mcpversion reach 5% ofmcpversions. The maintainer may change the number.Category: ruling
Current behavior:
An MCP write stores a version row with
trigger = 'mcp'andtriggeredByset to the caller (apps/hocuspocus.server/src/modules/document-content/http/controller.ts:193).A Restore stores a row with
trigger = 'revert'(apps/hocuspocus.server/src/modules/document-versions/infra/versionOps.ts:182).History labels those rows "Connected app" and "Restored" (
apps/webapp/src/components/pages/history/components/HistorySidebarRowParts.tsx:89-96).Retention thins unnamed rows older than
DOC_AUTOSAVE_RETENTION_DAYS(default30) to one per document per day (apps/hocuspocus.server/src/lib/retention.ts:62-90). An MCP tool write sets no name, so its row can be thinned. Arevertrow is named and stays. So count only the last 30 days.Measurement query, on the Prisma table
"Documents"(apps/hocuspocus.server/prisma/schema.prisma:11-30):Run it on a read-only copy, not on the live primary. It counts every Restore in the 24-hour window, not only one that undid the connected-app write. So the second count is an upper bound.
Desired behavior: any preview design must meet these constraints.
@tiptap/y-tiptap, thecatchthat calls_item.delete).edit_blocksorreplace_textwrite path with the storedrev. A stalerevtells the owner the section changed.Where to start:
edit_blocksandreplace_textinapps/hocuspocus.server/src/modules/mcp/tools/documentTools.ts; the History Compare view underapps/webapp/src/components/pages/history/. Line numbers are hints as of 2026-09-28; the agent searches by symbol.Rules that apply:
apps/webapp/src/components/TipTap/CLAUDE.md§Document Model And Migrations.apps/webapp/CLAUDE.md§Document Version History.apps/hocuspocus.server/CLAUDE.md§MCP Connector and §Retention and schema.CONTEXT.mdentries "Connected app" and "Restore"..cursor/docs/design-system.mdfor any pad UI..cursor/skills/tech-writer/SKILL.md§Simplified English (house standard) for the design note.Verify:
gh issue view <this issue number> --commentsshows the two counts and the maintainer's ruling. On "build", it also shows the design note and links to the build issues. This issue changes no code.Out of scope