You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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/updateswith{ rooms: [{ room, client_id, after (cursor), updates[], awareness }] }.sync_step1(announce state vector) → receive peers'sync_step2(missing updates) → ongoingupdates. Advance cursor fromend_cursorin the response.current_user_can( 'edit_post', N )for roompostType/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.document(record/blocks) +state; blocks ↔ CRDT via the equivalent of core-data'sapplyPostChangesToCRDTDoc/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
wp.sync.Yclient joins room as awareness-only (no writes). Proves auth (join as user, passedit_post), the polling/cursor loop, and the runtime boundary. Low blast radius.updates into thedocumentmap; 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'sblog_id.Acceptance
edit_postgate.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.Layer notes
wp_is_collaboration_enabled(); pin GB (experimentalwordpress-7.0compat).Prereqs: Phase 0 (Extra-Chill/extrachill-multisite#61), Phase 1 (Extra-Chill/blocks-everywhere#106). Builds atop #2669.