Skip to content

Agent Yjs-peer client: let a Data Machine agent join a Gutenberg collaboration room and emit live block edits #2675

Description

@chubes4

Child of Extra-Chill/extrachill-multisite#60 (Agent-as-RTC-peer epic). Phases 2–3 — the agent-side build.

Goal

Make a Data Machine agent a real peer in a Gutenberg RTC room (postType/post:N): it joins as a WP user, and its block edits are emitted as Yjs CRDT updates that propagate live to every human peer. The existing content tools (get_post_blocks/edit_post_blocks/replace_post_blocks/insert_content, multisite-aware via #2669) gain an "emit into room" mode instead of REST-apply-only.

The protocol the peer must speak (verified)

  • POST /wp-json/wp-sync/v1/updates with { rooms: [{ room, client_id, after (cursor), updates[], awareness }] }.
  • Yjs handshake: sync_step1 (announce state vector) → receive peers' sync_step2 (missing updates) → ongoing updates. Advance cursor from end_cursor in the response.
  • Server gates on current_user_can( 'edit_post', N ) for room postType/post:N (WP_HTTP_Polling_Sync_Server::check_permissions). The agent joins as the acting user (writer or scoped bot) — reuse the agent-acts-as-user model (agent_id + owner_id) + Roadie author-scoping.
  • CRDT doc schema: root maps document (record/blocks) + state; blocks ↔ CRDT via the equivalent of core-data's applyPostChangesToCRDTDoc / getPostChangesFromCRDTDoc.

The crux risk — Yjs instance (yjs#438)

The agent's updates MUST be built with Gutenberg's Yjs instance (wp.sync.Y) to be binary-compatible with browser peers. A pure-PHP Yjs reimplementation is a non-starter. → the peer is almost certainly a headless JS/Node participant that DM orchestrates (a sidecar invoked by the agent runtime), not PHP. Validating this runtime boundary is the primary unknown.

Phasing

  • Phase 2 (presence-only): headless wp.sync.Y client joins room as awareness-only (no writes). Proves auth (join as user, pass edit_post), the polling/cursor loop, and the runtime boundary. Low blast radius.
  • Phase 3 (writes): agent emits block edits as CRDT updates into the document map; they appear live in every human peer. Gate which rooms/users via Roadie tier + author-scoping (extrachill-roadie). Multisite room resolution via feat: multisite-aware block-content abilities via optional blog_id #2669's blog_id.

Acceptance

  • Phase 2: a DM-orchestrated headless client appears as a peer (presence) in a room a human is editing, authenticated as the acting user, without violating the edit_post gate.
  • Phase 3: an edit_post_blocks-class edit emitted by the agent materializes live in a human peer's editor; rejected/unauthorized rooms are refused; multisite (blog_id) rooms resolve correctly.
  • A documented decision on the agent-peer runtime (Node sidecar invocation, lifecycle: join on session/scheduled window, leave when done to bound polling cost).

Layer notes

  • Keep the Yjs/sync peer generic in DM (agent runtime owns 'how an agent acts'); EC-specific policy (which agent, which room, as whom) stays in extrachill-roadie / extrachill-multisite.
  • Guard everything behind wp_is_collaboration_enabled(); pin GB (experimental wordpress-7.0 compat).

Prereqs: Phase 0 (Extra-Chill/extrachill-multisite#61), Phase 1 (Extra-Chill/blocks-everywhere#106). Builds atop #2669.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions