Skip to content

Let an owner preview a connected app's edit before it applies #352

Description

@HMarzban

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

  • The measurement query below ran on a read-only copy of the production database. Its two counts are posted on this issue.
  • The maintainer has posted a ruling on this issue: build, or not yet.
  • On "build": a design note on this issue names the proposal store, the proposal lifetime, the new tool and the Accept path. It meets every constraint under "Desired behavior".
  • On "build": the maintainer has opened the build issues from that note.

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    EditorTiptap & ProsemirrorIdea

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions