Skip to content

RTC: Fix race condition on room creation which can cause a split update log#77675

Merged
dmsnell merged 11 commits into
WordPress:trunkfrom
danluu:danluu/fix-rtc-room-split
May 6, 2026
Merged

RTC: Fix race condition on room creation which can cause a split update log#77675
dmsnell merged 11 commits into
WordPress:trunkfrom
danluu:danluu/fix-rtc-room-split

Conversation

@danluu

@danluu danluu commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

What?

This is part of a series of bug reports and PRs from an AI fuzzing project. See #77532 for more details on that. I'm filing a few more of these after a discussion with @alecgeatches on how the fuzzer found a bug that I hadn't file that ended up taking some developer time to chase down and repro.

first-room-storage-live-repro.mp4
first-room-storage-document-edit-repro.mp4

BEGIN AI GENERATED TEXT

The post-meta sync storage backend creates one wp_sync_storage post per sync room and uses md5( $room ) as the post slug. On first access to a new room, two concurrent writers can both miss the existing-storage lookup and both call wp_insert_post() with the same slug. WordPress keeps slugs unique, so one request receives the canonical slug and the other receives a suffixed slug such as <hash>-2.

There is one trunk/product bug covered by this fix:

First-writer split storage bug. The original storage creation path trusted the inserted post ID without checking whether WordPress kept the exact room-hash slug. If a request received a suffixed post, it could acknowledge awareness or sync updates written to the suffixed lineage. A fresh storage instance later looks up only the canonical room hash, so those acknowledged first-access writes are unreachable. Source: get_storage_post_id() creates and caches the storage post. Repro/test: test_first_access_race_does_not_split_room_storage().

Branch Layout

The PR branch danluu/fix-rtc-room-split intentionally contains only the PHPUnit regression tests and the storage fix. This explanation is kept on the separate danluu/rtc-room-split-explanation branch so it does not appear in the PR diff.

There is no top-level Playwright/e2e test in the PR branch.

Reproduction Layers

PHPUnit storage repro

phpunit/tests/collaboration/wpSyncPostMetaStorage.php::test_first_access_race_does_not_split_room_storage

This test installs a wp_insert_post_data filter that injects a competing wp_insert_post() exactly between the storage layer's miss and its insert. It then asserts:

  • only one published wp_sync_storage lineage exists for the room hash;
  • the surviving lineage uses the exact room hash slug;
  • a fresh WP_Sync_Post_Meta_Storage instance can read the acknowledged update.

On the vulnerable implementation, the test fails because WordPress creates both <hash> and <hash>-2, and the update can be written to the suffixed post.

Browser/video repro

The local browser/video harness uses editor-visible presence to expose the split. It creates a draft post, enables a test-only race injector for the post's sync room, opens the post as admin, and delays the initial empty sync polls until the admin's presence payload contains visible collaborator metadata. The first meaningful admin presence poll then travels through the production /wp-sync/v1/updates endpoint and triggers the storage race.

After that acknowledged first write, the test pauses admin polling so the normal retry loop cannot immediately heal the symptom. A collaborator opens the same post and polls the canonical room. The test then holds the collaborator's next poll and releases the admin poll. On the vulnerable implementation, the admin screen learns that the collaborator joined, but the collaborator screen still has no Collaborators list button, because the admin's acknowledged first presence write was written to the suffixed storage lineage.

The deterministic browser harness still drives the production editor and sync REST path. The artificial parts are the scheduler that forces the otherwise timing-dependent first-writer race and the short admin-poll pause that keeps the user-visible presence loss observable long enough for the assertion and video. The diagnostic REST endpoint verifies the supporting storage invariant. The browser/video harness is not part of the PR branch.

Annotated videos for this bug:

  • /Users/danluu/conductor/workspaces/gutenberg-v1/providence/.context/rtc-issue-08/first-room-storage-live-repro.mp4
  • /Users/danluu/conductor/workspaces/gutenberg-v1/providence/.context/rtc-issue-08/first-room-storage-document-edit-repro.mp4

Observed vulnerable-branch result:

Expected lineage_count: 1
Received lineage_count: 2
Admin screen shows collaborator presence
Collaborator screen has no Collaborators list button

Real-vs-False-Positive Analysis

Oracle validity

The oracle is valid. A sync room must have one reachable storage lineage because fresh readers find storage by the canonical room hash. If an acknowledged write lands in a suffixed lineage, it is not reachable through normal get_storage_post_id() lookup in a new request.

Generated shape validity

The generated room shape is valid. The low-level repro uses postType/post:<id>:first-access-race, which matches the production REST room pattern. The browser repro uses the normal editor room postType/post:<id>.

Helper misuse

The failing path does not rely on private test-only storage calls for the browser repro. It opens normal editor sessions and lets the production sync endpoint call WP_Sync_Post_Meta_Storage. The PHPUnit repro uses the storage class directly to minimize the race window, but the same get-or-insert code is used by production REST requests.

Environment contamination

The tests reset the static room cache before fresh-reader checks. The room hash includes the test post ID and a unique suffix, and lineage counting filters by post type, publish status, exact room-hash slug, and suffixed room-hash slugs. The failure is not caused by stale cache state or older storage rows.

Race-injection-only behavior

The injection forces an interleaving that can occur with two concurrent HTTP requests first accessing a new room: both miss lookup, both insert, and WordPress uniquifies one slug. The injected writer uses wp_insert_post() with the same post type, status, title, and slug as production storage creation.

Known-fixed bug masking

The issue is independent of previously fixed cursor and compaction races. Those bugs affect update retrieval and deletion after storage already exists. This bug happens before the room has canonical storage and can lose the very first awareness or sync update into a suffixed lineage.

Fix Plan

The storage layer must treat the exact room-hash slug as the only canonical storage lineage:

  • After inserting a storage post, resolve the canonical exact-slug post before returning or caching a post ID.
  • If the inserted post is the only candidate and no exact slug exists, promote that post to the exact room-hash slug before using it.
  • If a suffixed duplicate is observed while resolving the race, merge its metadata into the exact-slug post.
  • Do not delete a suffixed storage post if moving its postmeta rows fails.
  • Cache only the resolved canonical post ID.
  • Cover the first-access race in PHPUnit.

The PR branch intentionally does not include this explanation, the browser-only diagnostic mu-plugin, or an e2e repro harness.

END AI GENERATED TEXT

Use of AI Tools

The code here is all AI generated. As noted above, the bug finding came from an AI fuzzing project.

@github-actions

github-actions Bot commented Apr 25, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: danluu <danluu@git.wordpress.org>
Co-authored-by: dmsnell <dmsnell@git.wordpress.org>
Co-authored-by: peterwilsoncc <peterwilsoncc@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions github-actions Bot added the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label Apr 25, 2026
@github-actions

Copy link
Copy Markdown

👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @danluu! In case you missed it, we'd love to have you join us in our Slack community.

If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information.

@danluu danluu changed the title Fix sync storage first room race RTC: Fix race condition on room creation which can cause a split update log Apr 25, 2026
@danluu danluu force-pushed the danluu/fix-rtc-room-split branch from 6a3168f to a02b370 Compare April 25, 2026 23:32
@t-hamano t-hamano added [Type] Bug An existing feature does not function as intended [Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration labels Apr 27, 2026
return null;
}

clean_post_cache( $post_id );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven’t followed the post-cache issues too closely, but I wonder if this is going to be problematic as well.

I would expect that promoting a non-canonical storage meta will occur rarely (vs. multiple times per second as was occurring in trunk for edits), but I would like some double-checking on this to make sure it would not cause thrashing on the site with other posts.

@peterwilsoncc this PR might seem a bit random, but are you able to speak to the use of clean_post_cache() here? the situation is that two sessions opened a post and due to a race condition, created two separate wp_sync_storage rows. this code is resolving that race.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can use wp_update_post()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @peterwilsoncc — I’ve made that update in a871f1c, but I wonder if there’s important gains running through all the additional machinery in get_posts(). given that this is going to be occurring frequently during an edit session.

I’ll leave it and we can see later if it’s problematic. if this code disappears in favor of a table then I suppose this is good enough.

self::POST_TYPE,
$room_hash,
$wpdb->esc_like( $room_hash . '-' ) . '%'
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the concern may be minor here, but I wanted to ask if this OR clause is hiding a needless table scan. I asked an LLM to analyze it and it suggested that a UNION instead could introduce two index-scans to replace a single table scan.

Here is MariaDB’s EXPLAIN for the two versions:

MariaDB [wordpress]> EXPLAIN SELECT ID FROM wp_posts WHERE post_type = "wp_sync_storage" AND post_status = "publish" AND ( post_name = "abc123" OR post_name LIKE "abc123-" ) ORDER BY ID ASC;
+------+-------------+----------+-------+-----------------------------------------------+---------+---------+------+------+-------------+
| id   | select_type | table    | type  | possible_keys                                 | key     | key_len | ref  | rows | Extra       |
+------+-------------+----------+-------+-----------------------------------------------+---------+---------+------+------+-------------+
|    1 | SIMPLE      | wp_posts | index | post_name,type_status_date,type_status_author | PRIMARY | 8       | NULL | 35   | Using where |
+------+-------------+----------+-------+-----------------------------------------------+---------+---------+------+------+-------------+
1 row in set (0.003 sec)

MariaDB [wordpress]> EXPLAIN SELECT ID FROM wp_posts WHERE post_type = "wp_sync_storage" AND post_status = "publish" AND post_name = "abc123" UNION SELECT ID FROM wp_posts WHERE post_type = "wp_sync_storage" AND post_status = "publish" AND post_name LIKE "abc123-" ORDER BY ID ASC;
+------+--------------+------------+-------+-----------------------------------------------+-----------+---------+-------+------+----------------+
| id   | select_type  | table      | type  | possible_keys                                 | key       | key_len | ref   | rows | Extra          |
+------+--------------+------------+-------+-----------------------------------------------+-----------+---------+-------+------+----------------+
|    1 | PRIMARY      | wp_posts   | ref   | post_name,type_status_date,type_status_author | post_name | 766     | const | 1    | Using where    |
|    2 | UNION        | wp_posts   | range | post_name,type_status_date,type_status_author | post_name | 766     | NULL  | 1    | Using where    |
| NULL | UNION RESULT | <union1,2> | ALL   | NULL                                          | NULL      | NULL    | NULL  | NULL | Using filesort |
+------+--------------+------------+-------+-----------------------------------------------+-----------+---------+-------+------+----------------+
3 rows in set (0.002 sec)

Granted, for my little test site with two posts both are going to be roughly equivalent, but if we hit a site with thousands of posts, I wonder if this could introduce noticeable DB overhead.

Not being sure how to interpret the Using filesort I also asked about eliminating that by sorting in PHP and there was no clear guidance other than to say that when the expected set is small (which it is here) there’s no practical difference.

@peterwilsoncc

Copy link
Copy Markdown
Contributor

@danluu Are you able to provide more information about how the race condition is being forced, so I can do so locally.

The reason I am asking is that I'd like to know how real world this is, the additional work being done will slow down requests which would make any race condition more likely to occur.

@dmsnell The clear_post_cache call is correct as so get_posts() queries up-to-date data on follow up calls.

@peterwilsoncc peterwilsoncc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some first view notes inline but my main question is in the comment above re: reproduction steps.

I know from conversations with Matt that he is pretty keen on avoiding the post/post_meta approach so I'd really prefer to focus our energies there rather than on code that's unlikely to make a WordPress release.

As the updates are added to a row identified by the room name, the race condition isn't able to occur with the improved storage structure.

Aside: while post_meta has been the prompt for Core-64696 (don't read all of it), using posts for rooms is an abuse of both the posts and posts_meta tables in my view.

Comment on lines +364 to +370
$move_result = $wpdb->update(
$wpdb->postmeta,
array( 'post_id' => $canonical_post_id ),
array( 'post_id' => $duplicate_id ),
array( '%d' ),
array( '%d' )
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may result in two copies of awareness post_meta stored against a single post ID.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you have the mechanism for how this would create the duplicates? we did some investigation into meta_id, but trying to prevent that ended up adding considerable complexity and was addressing a secondary effect of this PR, which itself is preventing duplicate posts at a more frequent rate.

I think that even in the presence of new risk here, my assessment is that this is significantly lowering the overall risk. that is, we’re not introducing the possibility of creating duplicate awareness posts; we’re starting in a system that already duplicates them and we’re removing one common way it does that.

Comment on lines +396 to +402
$post_id = $wpdb->get_var(
$wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_status = 'publish' AND post_name = %s ORDER BY ID ASC LIMIT 1",
self::POST_TYPE,
$room_hash
)
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can use the get_posts API.

$posts = get_posts(
				array(
					'post_type'      => self::POST_TYPE,
					'posts_per_page' => 1,
					'post_status'    => 'publish',
					'name'           => $room_hash,
					'fields'         => 'ids',
					'orderby'        => 'ID',
					'order'          => 'ASC',
				)
			);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @peterwilsoncc — I’ve made that update in a871f1c, but I wonder if there’s important gains running through all the additional machinery in get_posts(). given that this is going to be occurring frequently during an edit session.

I’ll leave it and we can see later if it’s problematic. if this code disappears in favor of a table then I suppose this is good enough.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops I changed the code to get_posts() but then I didn’t change the response handler, introducing a bug. @t-hamano caught it and resolved it in #78053

return null;
}

clean_post_cache( $post_id );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can use wp_update_post()

@danluu

danluu commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

@peterwilsoncc Thanks for taking a look! Specifically on the question of the repro, the checked in e2e test forced a race by creating a wp_insert_post_data filter that does a wp_insert_post (with a check to prevent infinite recursion).

For a less artificial (but non-deterministic) repro, this script attempts to demonstrate the race: https://github.com/danluu/gutenberg/blob/danluu/rtc-room-split-explanation/docs/explanations/fuzzer-bugs/rtc-issue-08-normal-rest-repro.sh. The script creates concurrent draft posts across users and then checks if there was a room split. It works on my machine fairly consistently, but it may be less consistent in a different environment.

@peterwilsoncc

Copy link
Copy Markdown
Contributor

For a less artificial (but non-deterministic) repro, this script attempts to demonstrate the race: https://github.com/danluu/gutenberg/blob/danluu/rtc-room-split-explanation/docs/explanations/fuzzer-bugs/rtc-issue-08-normal-rest-repro.sh. The script creates concurrent draft posts across users and then checks if there was a room split. It works on my machine fairly consistently, but it may be less consistent in a different environment.

Thanks for the script @danluu -- while feedback comes in from hosts on the performance of the various options (see the call for testing on make/hosting), I'm going to compare the effects across the various options. There's a good chance something will be needed but the exact shape is yet to be determined.

@dmsnell

dmsnell commented Apr 30, 2026

Copy link
Copy Markdown
Member

@peterwilsoncc

I know from conversations with Matt that he is pretty keen on avoiding the post/post_meta approach so I'd really prefer to focus our energies there rather than on code that's unlikely to make a WordPress release.

I might have missed the news in the flurry over the past week, but I thought we are still shipping the post meta approach for 7.0?

If so, the goal is to get this code in for the release, as a bug fix to the RTC functionality introduced in 7.0. The idea being that it would be best to risk duplicating some effort now to prevent people from getting corrupted documents when they try out the new hallmark feature of the release.

@peterwilsoncc

peterwilsoncc commented May 3, 2026 via email

Copy link
Copy Markdown
Contributor

@danluu danluu requested review from nerrad and ntwb as code owners May 5, 2026 23:26
@dmsnell

dmsnell commented May 6, 2026

Copy link
Copy Markdown
Member

I'd really prefer to focus our energies there rather than on code that's unlikely to make a WordPress release.

@peterwilsoncc thank you for your insight here and your helpful review on this PR. I hear that feedback, but I want to provide a bit more context:

  • this work isn’t taking focus away from other parts of the system. @danluu and I have been doing bug sprints on RTC and are going to be continuing to do through up through the release. we’re tackling whichever parts of the system present the bugs and this one just happened to be in the post_meta part.
  • if we end up with a table in 7.0 then I would hope that work we do on post_meta won’t end up mattering that much. we can throw it all away, and this code can be deleted. as it stands, this is currently in the RC so I’d rather we have a more-working RC even if we re-engineer it than a broken RC. hopefully as we update the code, these additional tests and verifications will guide our transition to a table.

I just want to say that as far as we can guarantee, we will be monitoring this code and happy to handle any necessary follow-ups or reverts. as we stack up detected bugs and fixes though, it’s becoming harder and harder to address them because we’re finding the same bugs repeatedly.

@dmsnell dmsnell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could be some follow-up work on this, but it appears to solve a real problem. I’ll handle the backport.

If anything serious turns up we can revert.

@dmsnell dmsnell merged commit f770b5d into WordPress:trunk May 6, 2026
42 of 45 checks passed
@github-actions github-actions Bot added this to the Gutenberg 23.2 milestone May 6, 2026
@Mamaduka

Mamaduka commented May 7, 2026

Copy link
Copy Markdown
Member

The unit tests are failing on trunk after this was merged. Details - https://github.com/WordPress/gutenberg/actions/runs/25459792903/job/74699025309

@t-hamano

t-hamano commented May 7, 2026

Copy link
Copy Markdown
Contributor

These unit tests should be fixed here: #78053

Furthermore, let's backport this to wp/7.0 to maintain consistency.

@t-hamano t-hamano added the Backport to WP 7.0 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label May 7, 2026
@github-actions github-actions Bot added Backported to WP Core Pull request that has been successfully merged into WP Core and removed Backport to WP 7.0 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta labels May 7, 2026
@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown

I just cherry-picked this PR to the wp/7.0 branch to get it included in the next release: 888812a

gutenbergplugin pushed a commit that referenced this pull request May 7, 2026
…te log (#77675)

When two edit sessions create a “room” for the same document, they can encounter a race where WordPress creates two copies of the sync post meta for that document and the editors can work on two different histories of the document, leading to data loss.

This change introduces a process to merge updates into a canonical sync post meta to avoid this race. When duplicates are detected, the newest sync’d meta is chosen as the new canonical copy and it replaces the other copies.

During this process, additional database activity occurs to resolve the duplicates, though that should normatively present itself when duplicates already exist. Due to a lack of a broadly-supported way to perform database locking, there remains a secondary race when resolving the duplicates; this condition should be rarer than the one which motivated this in the first place. That means that while risk still exists, the overall risk should be much lower. An attempt was made to cover this secondary risk but the solution was complicated and itself unclear.

Co-authored-by: danluu <danluu@git.wordpress.org>
Co-authored-by: dmsnell <dmsnell@git.wordpress.org>
Co-authored-by: peterwilsoncc <peterwilsoncc@git.wordpress.org>
dmsnell added a commit to dmsnell/wordpress-develop that referenced this pull request May 7, 2026
Trac ticket: Core-65138

Backport of WordPress/gutenberg#77675

A race condition on opening an editor session allows for Core to create
duplicate post meta for sync storage. This creates two copies of the
document which the editors operate on independently, leading to a
mismatch between the sessions.

In this patch, when such a duplicate storage row is detected, a
canonical version of the post meta is chosen (the one with the lowest id
viz. the oldest one) and the duplicate is merged into it.

This should ensure that all edit sessions for a given post use the same
synchronized backing store.

Co-authored-by: Dennis Snell <dmsnell@git.wordpress.org>
talldan pushed a commit that referenced this pull request May 8, 2026
…te log (#77675)

When two edit sessions create a “room” for the same document, they can encounter a race where WordPress creates two copies of the sync post meta for that document and the editors can work on two different histories of the document, leading to data loss.

This change introduces a process to merge updates into a canonical sync post meta to avoid this race. When duplicates are detected, the newest sync’d meta is chosen as the new canonical copy and it replaces the other copies.

During this process, additional database activity occurs to resolve the duplicates, though that should normatively present itself when duplicates already exist. Due to a lack of a broadly-supported way to perform database locking, there remains a secondary race when resolving the duplicates; this condition should be rarer than the one which motivated this in the first place. That means that while risk still exists, the overall risk should be much lower. An attempt was made to cover this secondary risk but the solution was complicated and itself unclear.

Co-authored-by: danluu <danluu@git.wordpress.org>
Co-authored-by: dmsnell <dmsnell@git.wordpress.org>
Co-authored-by: peterwilsoncc <peterwilsoncc@git.wordpress.org>
pento pushed a commit to WordPress/wordpress-develop that referenced this pull request May 8, 2026
This updates the pinned hash from the `gutenberg` from `e2970ba736edb99e08fb369d4fb0c378189468ee ` to `c15cef1d6b07f666df28dac0383bafb0edfe0914`.

The following changes are included:

- RTC: Predefined retry schedules for disconnect dialog, make more lenient (WordPress/gutenberg#76966)
- Block Editor: Prevent Enter key from inserting paragraphs in contentOnly sections (WordPress/gutenberg#76989)
- Cover block: fix embed video background Error 153 in editor (WordPress/gutenberg#76904)
- Restore original template registration tests alongside activation variants (WordPress/gutenberg#77068)
- Avoid stale values in core/cover block for RTC compatibility (WordPress/gutenberg#76916)
- Bump oras-project/setup-oras (WordPress/gutenberg#77096) (WordPress/gutenberg#77110)
- RTC: Change SyncConnectionModal to isSyncConnectionErrorHandled filter and drop IS_GUTENBERG_PLUGIN check (WordPress/gutenberg#76853)
- contentOnly template lock: Fix block insertion and removal rules (WordPress/gutenberg#77119)
- Global Styles Revisions: Fix footer overflow (WordPress/gutenberg#77103)
- Revision: Fix 'Show changes' button reset state (WordPress/gutenberg#77122)
- Link picker: Decode HTML entities in link preview title (WordPress/gutenberg#77170)
- Connectors: don't clobber third-party custom render in registerDefaultConnectors (WordPress/gutenberg#77116)
- Connectors: Replace speak() with notice store for state changes (WordPress/gutenberg#77174)
- Core Data: Fix 'useEntityProp' for raw attributes (WordPress/gutenberg#77120)
- Fix PatternsActions prop name from postType to type (WordPress/gutenberg#77251)
- Fix: restore editor canvas padding in classic themes (WordPress/gutenberg#76864)
- RTC: Add filterable flag for meta box RTC compatibility (WordPress/gutenberg#76939)
- Fix failing 'WP_HTTP_Polling_Sync_Server' unit test (WordPress/gutenberg#77025) (WordPress/gutenberg#77325)
- Edit Post: Fix warning in 'useMetaBoxInitialization' hook (WordPress/gutenberg#77311)
- Update the page slug we link to for the AI plugin after the plugin has been installed and activated (WordPress/gutenberg#77336)
- Test: Connectors Point to the righ page. (WordPress/gutenberg#77272)
- Post Editor: Store metaboxes RTC-compatible flag on location entries (WordPress/gutenberg#77361)
- Core Abilities: Export initialization promise as `ready` (WordPress/gutenberg#77254)
- Block Editor: Strip per-block custom CSS on save for users without edit_css (WordPress/gutenberg#76650)
- Add heading level 1 for the fonts page (WordPress/gutenberg#77482)
- Connectors: Treat network-active plugins as active in plugin status check (WordPress/gutenberg#77661)
- RTC: Fix disconnect dialog due to uneditable entity (WordPress/gutenberg#77242)
- RTC: Fix "Connection Lost" dialog when too many entities are loaded (WordPress/gutenberg#77631)
- RTC: Fix "Edit as HTML" content reset during collaboration (WordPress/gutenberg#77043)
- RTC: Add optional `shouldSync` function to entity sync config (WordPress/gutenberg#76947)
- RTC: Fixed orphaned meta causing dirty editor state (WordPress/gutenberg#77529)
- Ensure "Retry" button is stable during retries (WordPress/gutenberg#77234)
- Patterns: add confirmation dialog before disconnecting/detaching (WordPress/gutenberg#75713)
- Template parts: make 'Detach' context menu item consistent across patterns and template parts (WordPress/gutenberg#77581)
- Remove sandbox `allow-same-origin` for core/html blocks (Merge WordPress/gutenberg#77212 to `wp/7.0`) (WordPress/gutenberg#77699)
- Added Context for Next/Prev Enlarge Image (WordPress/gutenberg#76967)
- Backport: Writing Flow: fix arrow keys skipping paragraph containing link (WordPress/gutenberg#77478)
- Revisions: Improve screen reader accessibility for diff markers region and slider (WordPress/gutenberg#77660)
- Connectors: Add role="list" wrapper to connector cards for valid ARIA structure (WordPress/gutenberg#77689)
- Command Palette: Fix macOs label for sites unable to determine UA via PHP (WordPress/gutenberg#77638)
- RTC: Fix inline inserter reset on update sync (WordPress/gutenberg#76980) (WordPress/gutenberg#77706)
- Connectors: keep focus on action Button during install (WordPress/gutenberg#77544)
- Added Translator Context for Reply (WordPress/gutenberg#77891)
- Editor: Improve revisions diff pairing performance (WordPress/gutenberg#77126)
- Core Data: Treat single-item responses specially (WordPress/gutenberg#76318)
- Site editor: preserve non-global styles in pattern previews (WordPress/gutenberg#77957)
- RTC: Fix divergence when two offline users reconnect (WordPress/gutenberg#77980)
- RTC: Fix compaction unit test (WordPress/gutenberg#77986)
- Connectors: Stop e2e capability restriction from leaking across specs (WordPress/gutenberg#77857)
- Connectors: Clarify AI plugin callout copy (WordPress/gutenberg#78043)
- Fix: Only auto register settings if the plugin the connector references is installed and active. (WordPress/gutenberg#77273)
- Connectors: Add is_active callback support to plugin registration (WordPress/gutenberg#77897)
- RTC: Fix race condition on room creation which can cause a split update log (WordPress/gutenberg#77675)
- RTC: Fix find_canonical_storage_post_id() always returning null (WordPress/gutenberg#78053)
- i18n: add context to scale (WordPress/gutenberg#76917)
- Revisions: Simplify fetching (WordPress/gutenberg#77086)
- e2e: Add e2e tests for template and template part revisions (WordPress/gutenberg#76923)
- Editor: Paginate revisions slider by 100 per page (WordPress/gutenberg#77200) (WordPress/gutenberg#78070)
- Revisions: Add diagonal stripe patterns to diff markers to avoid color-only distinction (WordPress/gutenberg#77904)
- Revision: Fix failing e2e test (WordPress/gutenberg#78079)
- Real-time collaboration: Bundle @wordpress/sync instead of exposing as wp.sync (WordPress/gutenberg#78085)

A full list of changes can be found on GitHub: https://github.com/WordPress/gutenberg/compare/e2970ba736edb99e08fb369d4fb0c378189468ee…c15cef1d6b07f666df28dac0383bafb0edfe0914.

Log created with:

git log --reverse --format="- %s" e2970ba736edb99e08fb369d4fb0c378189468ee..c15cef1d6b07f666df28dac0383bafb0edfe0914 | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy

See #64595.

git-svn-id: https://develop.svn.wordpress.org/trunk@62333 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request May 8, 2026
This updates the pinned hash from the `gutenberg` from `e2970ba736edb99e08fb369d4fb0c378189468ee ` to `c15cef1d6b07f666df28dac0383bafb0edfe0914`.

The following changes are included:

- RTC: Predefined retry schedules for disconnect dialog, make more lenient (WordPress/gutenberg#76966)
- Block Editor: Prevent Enter key from inserting paragraphs in contentOnly sections (WordPress/gutenberg#76989)
- Cover block: fix embed video background Error 153 in editor (WordPress/gutenberg#76904)
- Restore original template registration tests alongside activation variants (WordPress/gutenberg#77068)
- Avoid stale values in core/cover block for RTC compatibility (WordPress/gutenberg#76916)
- Bump oras-project/setup-oras (WordPress/gutenberg#77096) (WordPress/gutenberg#77110)
- RTC: Change SyncConnectionModal to isSyncConnectionErrorHandled filter and drop IS_GUTENBERG_PLUGIN check (WordPress/gutenberg#76853)
- contentOnly template lock: Fix block insertion and removal rules (WordPress/gutenberg#77119)
- Global Styles Revisions: Fix footer overflow (WordPress/gutenberg#77103)
- Revision: Fix 'Show changes' button reset state (WordPress/gutenberg#77122)
- Link picker: Decode HTML entities in link preview title (WordPress/gutenberg#77170)
- Connectors: don't clobber third-party custom render in registerDefaultConnectors (WordPress/gutenberg#77116)
- Connectors: Replace speak() with notice store for state changes (WordPress/gutenberg#77174)
- Core Data: Fix 'useEntityProp' for raw attributes (WordPress/gutenberg#77120)
- Fix PatternsActions prop name from postType to type (WordPress/gutenberg#77251)
- Fix: restore editor canvas padding in classic themes (WordPress/gutenberg#76864)
- RTC: Add filterable flag for meta box RTC compatibility (WordPress/gutenberg#76939)
- Fix failing 'WP_HTTP_Polling_Sync_Server' unit test (WordPress/gutenberg#77025) (WordPress/gutenberg#77325)
- Edit Post: Fix warning in 'useMetaBoxInitialization' hook (WordPress/gutenberg#77311)
- Update the page slug we link to for the AI plugin after the plugin has been installed and activated (WordPress/gutenberg#77336)
- Test: Connectors Point to the righ page. (WordPress/gutenberg#77272)
- Post Editor: Store metaboxes RTC-compatible flag on location entries (WordPress/gutenberg#77361)
- Core Abilities: Export initialization promise as `ready` (WordPress/gutenberg#77254)
- Block Editor: Strip per-block custom CSS on save for users without edit_css (WordPress/gutenberg#76650)
- Add heading level 1 for the fonts page (WordPress/gutenberg#77482)
- Connectors: Treat network-active plugins as active in plugin status check (WordPress/gutenberg#77661)
- RTC: Fix disconnect dialog due to uneditable entity (WordPress/gutenberg#77242)
- RTC: Fix "Connection Lost" dialog when too many entities are loaded (WordPress/gutenberg#77631)
- RTC: Fix "Edit as HTML" content reset during collaboration (WordPress/gutenberg#77043)
- RTC: Add optional `shouldSync` function to entity sync config (WordPress/gutenberg#76947)
- RTC: Fixed orphaned meta causing dirty editor state (WordPress/gutenberg#77529)
- Ensure "Retry" button is stable during retries (WordPress/gutenberg#77234)
- Patterns: add confirmation dialog before disconnecting/detaching (WordPress/gutenberg#75713)
- Template parts: make 'Detach' context menu item consistent across patterns and template parts (WordPress/gutenberg#77581)
- Remove sandbox `allow-same-origin` for core/html blocks (Merge WordPress/gutenberg#77212 to `wp/7.0`) (WordPress/gutenberg#77699)
- Added Context for Next/Prev Enlarge Image (WordPress/gutenberg#76967)
- Backport: Writing Flow: fix arrow keys skipping paragraph containing link (WordPress/gutenberg#77478)
- Revisions: Improve screen reader accessibility for diff markers region and slider (WordPress/gutenberg#77660)
- Connectors: Add role="list" wrapper to connector cards for valid ARIA structure (WordPress/gutenberg#77689)
- Command Palette: Fix macOs label for sites unable to determine UA via PHP (WordPress/gutenberg#77638)
- RTC: Fix inline inserter reset on update sync (WordPress/gutenberg#76980) (WordPress/gutenberg#77706)
- Connectors: keep focus on action Button during install (WordPress/gutenberg#77544)
- Added Translator Context for Reply (WordPress/gutenberg#77891)
- Editor: Improve revisions diff pairing performance (WordPress/gutenberg#77126)
- Core Data: Treat single-item responses specially (WordPress/gutenberg#76318)
- Site editor: preserve non-global styles in pattern previews (WordPress/gutenberg#77957)
- RTC: Fix divergence when two offline users reconnect (WordPress/gutenberg#77980)
- RTC: Fix compaction unit test (WordPress/gutenberg#77986)
- Connectors: Stop e2e capability restriction from leaking across specs (WordPress/gutenberg#77857)
- Connectors: Clarify AI plugin callout copy (WordPress/gutenberg#78043)
- Fix: Only auto register settings if the plugin the connector references is installed and active. (WordPress/gutenberg#77273)
- Connectors: Add is_active callback support to plugin registration (WordPress/gutenberg#77897)
- RTC: Fix race condition on room creation which can cause a split update log (WordPress/gutenberg#77675)
- RTC: Fix find_canonical_storage_post_id() always returning null (WordPress/gutenberg#78053)
- i18n: add context to scale (WordPress/gutenberg#76917)
- Revisions: Simplify fetching (WordPress/gutenberg#77086)
- e2e: Add e2e tests for template and template part revisions (WordPress/gutenberg#76923)
- Editor: Paginate revisions slider by 100 per page (WordPress/gutenberg#77200) (WordPress/gutenberg#78070)
- Revisions: Add diagonal stripe patterns to diff markers to avoid color-only distinction (WordPress/gutenberg#77904)
- Revision: Fix failing e2e test (WordPress/gutenberg#78079)
- Real-time collaboration: Bundle @wordpress/sync instead of exposing as wp.sync (WordPress/gutenberg#78085)

A full list of changes can be found on GitHub: https://github.com/WordPress/gutenberg/compare/e2970ba736edb99e08fb369d4fb0c378189468ee…c15cef1d6b07f666df28dac0383bafb0edfe0914.

Log created with:

git log --reverse --format="- %s" e2970ba736edb99e08fb369d4fb0c378189468ee..c15cef1d6b07f666df28dac0383bafb0edfe0914 | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy

See #64595.
Built from https://develop.svn.wordpress.org/trunk@62333


git-svn-id: http://core.svn.wordpress.org/trunk@61614 1a063a9b-81f0-0310-95a4-ce76da25c4cd
pento pushed a commit to WordPress/wordpress-develop that referenced this pull request May 8, 2026
This updates the pinned hash from the `gutenberg` from `e2970ba736edb99e08fb369d4fb0c378189468ee ` to `c15cef1d6b07f666df28dac0383bafb0edfe0914`.

The following changes are included:

- RTC: Predefined retry schedules for disconnect dialog, make more lenient (WordPress/gutenberg#76966)
- Block Editor: Prevent Enter key from inserting paragraphs in contentOnly sections (WordPress/gutenberg#76989)
- Cover block: fix embed video background Error 153 in editor (WordPress/gutenberg#76904)
- Restore original template registration tests alongside activation variants (WordPress/gutenberg#77068)
- Avoid stale values in core/cover block for RTC compatibility (WordPress/gutenberg#76916)
- Bump oras-project/setup-oras (WordPress/gutenberg#77096) (WordPress/gutenberg#77110)
- RTC: Change SyncConnectionModal to isSyncConnectionErrorHandled filter and drop IS_GUTENBERG_PLUGIN check (WordPress/gutenberg#76853)
- contentOnly template lock: Fix block insertion and removal rules (WordPress/gutenberg#77119)
- Global Styles Revisions: Fix footer overflow (WordPress/gutenberg#77103)
- Revision: Fix 'Show changes' button reset state (WordPress/gutenberg#77122)
- Link picker: Decode HTML entities in link preview title (WordPress/gutenberg#77170)
- Connectors: don't clobber third-party custom render in registerDefaultConnectors (WordPress/gutenberg#77116)
- Connectors: Replace speak() with notice store for state changes (WordPress/gutenberg#77174)
- Core Data: Fix 'useEntityProp' for raw attributes (WordPress/gutenberg#77120)
- Fix PatternsActions prop name from postType to type (WordPress/gutenberg#77251)
- Fix: restore editor canvas padding in classic themes (WordPress/gutenberg#76864)
- RTC: Add filterable flag for meta box RTC compatibility (WordPress/gutenberg#76939)
- Fix failing 'WP_HTTP_Polling_Sync_Server' unit test (WordPress/gutenberg#77025) (WordPress/gutenberg#77325)
- Edit Post: Fix warning in 'useMetaBoxInitialization' hook (WordPress/gutenberg#77311)
- Update the page slug we link to for the AI plugin after the plugin has been installed and activated (WordPress/gutenberg#77336)
- Test: Connectors Point to the righ page. (WordPress/gutenberg#77272)
- Post Editor: Store metaboxes RTC-compatible flag on location entries (WordPress/gutenberg#77361)
- Core Abilities: Export initialization promise as `ready` (WordPress/gutenberg#77254)
- Block Editor: Strip per-block custom CSS on save for users without edit_css (WordPress/gutenberg#76650)
- Add heading level 1 for the fonts page (WordPress/gutenberg#77482)
- Connectors: Treat network-active plugins as active in plugin status check (WordPress/gutenberg#77661)
- RTC: Fix disconnect dialog due to uneditable entity (WordPress/gutenberg#77242)
- RTC: Fix "Connection Lost" dialog when too many entities are loaded (WordPress/gutenberg#77631)
- RTC: Fix "Edit as HTML" content reset during collaboration (WordPress/gutenberg#77043)
- RTC: Add optional `shouldSync` function to entity sync config (WordPress/gutenberg#76947)
- RTC: Fixed orphaned meta causing dirty editor state (WordPress/gutenberg#77529)
- Ensure "Retry" button is stable during retries (WordPress/gutenberg#77234)
- Patterns: add confirmation dialog before disconnecting/detaching (WordPress/gutenberg#75713)
- Template parts: make 'Detach' context menu item consistent across patterns and template parts (WordPress/gutenberg#77581)
- Remove sandbox `allow-same-origin` for core/html blocks (Merge WordPress/gutenberg#77212 to `wp/7.0`) (WordPress/gutenberg#77699)
- Added Context for Next/Prev Enlarge Image (WordPress/gutenberg#76967)
- Backport: Writing Flow: fix arrow keys skipping paragraph containing link (WordPress/gutenberg#77478)
- Revisions: Improve screen reader accessibility for diff markers region and slider (WordPress/gutenberg#77660)
- Connectors: Add role="list" wrapper to connector cards for valid ARIA structure (WordPress/gutenberg#77689)
- Command Palette: Fix macOs label for sites unable to determine UA via PHP (WordPress/gutenberg#77638)
- RTC: Fix inline inserter reset on update sync (WordPress/gutenberg#76980) (WordPress/gutenberg#77706)
- Connectors: keep focus on action Button during install (WordPress/gutenberg#77544)
- Added Translator Context for Reply (WordPress/gutenberg#77891)
- Editor: Improve revisions diff pairing performance (WordPress/gutenberg#77126)
- Core Data: Treat single-item responses specially (WordPress/gutenberg#76318)
- Site editor: preserve non-global styles in pattern previews (WordPress/gutenberg#77957)
- RTC: Fix divergence when two offline users reconnect (WordPress/gutenberg#77980)
- RTC: Fix compaction unit test (WordPress/gutenberg#77986)
- Connectors: Stop e2e capability restriction from leaking across specs (WordPress/gutenberg#77857)
- Connectors: Clarify AI plugin callout copy (WordPress/gutenberg#78043)
- Fix: Only auto register settings if the plugin the connector references is installed and active. (WordPress/gutenberg#77273)
- Connectors: Add is_active callback support to plugin registration (WordPress/gutenberg#77897)
- RTC: Fix race condition on room creation which can cause a split update log (WordPress/gutenberg#77675)
- RTC: Fix find_canonical_storage_post_id() always returning null (WordPress/gutenberg#78053)
- i18n: add context to scale (WordPress/gutenberg#76917)
- Revisions: Simplify fetching (WordPress/gutenberg#77086)
- e2e: Add e2e tests for template and template part revisions (WordPress/gutenberg#76923)
- Editor: Paginate revisions slider by 100 per page (WordPress/gutenberg#77200) (WordPress/gutenberg#78070)
- Revisions: Add diagonal stripe patterns to diff markers to avoid color-only distinction (WordPress/gutenberg#77904)
- Revision: Fix failing e2e test (WordPress/gutenberg#78079)
- Real-time collaboration: Bundle @wordpress/sync instead of exposing as wp.sync (WordPress/gutenberg#78085)

A full list of changes can be found on GitHub: https://github.com/WordPress/gutenberg/compare/e2970ba736edb99e08fb369d4fb0c378189468ee…c15cef1d6b07f666df28dac0383bafb0edfe0914.

Log created with:

git log --reverse --format="- %s" e2970ba736edb99e08fb369d4fb0c378189468ee..c15cef1d6b07f666df28dac0383bafb0edfe0914 | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy

Reviewed by desrosj.
Merges [62333] to the 7.0 branch.

Props ellatrix, desrosj.
See #64595.

git-svn-id: https://develop.svn.wordpress.org/branches/7.0@62335 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to WordPress/WordPress that referenced this pull request May 8, 2026
This updates the pinned hash from the `gutenberg` from `e2970ba736edb99e08fb369d4fb0c378189468ee ` to `c15cef1d6b07f666df28dac0383bafb0edfe0914`.

The following changes are included:

- RTC: Predefined retry schedules for disconnect dialog, make more lenient (WordPress/gutenberg#76966)
- Block Editor: Prevent Enter key from inserting paragraphs in contentOnly sections (WordPress/gutenberg#76989)
- Cover block: fix embed video background Error 153 in editor (WordPress/gutenberg#76904)
- Restore original template registration tests alongside activation variants (WordPress/gutenberg#77068)
- Avoid stale values in core/cover block for RTC compatibility (WordPress/gutenberg#76916)
- Bump oras-project/setup-oras (WordPress/gutenberg#77096) (WordPress/gutenberg#77110)
- RTC: Change SyncConnectionModal to isSyncConnectionErrorHandled filter and drop IS_GUTENBERG_PLUGIN check (WordPress/gutenberg#76853)
- contentOnly template lock: Fix block insertion and removal rules (WordPress/gutenberg#77119)
- Global Styles Revisions: Fix footer overflow (WordPress/gutenberg#77103)
- Revision: Fix 'Show changes' button reset state (WordPress/gutenberg#77122)
- Link picker: Decode HTML entities in link preview title (WordPress/gutenberg#77170)
- Connectors: don't clobber third-party custom render in registerDefaultConnectors (WordPress/gutenberg#77116)
- Connectors: Replace speak() with notice store for state changes (WordPress/gutenberg#77174)
- Core Data: Fix 'useEntityProp' for raw attributes (WordPress/gutenberg#77120)
- Fix PatternsActions prop name from postType to type (WordPress/gutenberg#77251)
- Fix: restore editor canvas padding in classic themes (WordPress/gutenberg#76864)
- RTC: Add filterable flag for meta box RTC compatibility (WordPress/gutenberg#76939)
- Fix failing 'WP_HTTP_Polling_Sync_Server' unit test (WordPress/gutenberg#77025) (WordPress/gutenberg#77325)
- Edit Post: Fix warning in 'useMetaBoxInitialization' hook (WordPress/gutenberg#77311)
- Update the page slug we link to for the AI plugin after the plugin has been installed and activated (WordPress/gutenberg#77336)
- Test: Connectors Point to the righ page. (WordPress/gutenberg#77272)
- Post Editor: Store metaboxes RTC-compatible flag on location entries (WordPress/gutenberg#77361)
- Core Abilities: Export initialization promise as `ready` (WordPress/gutenberg#77254)
- Block Editor: Strip per-block custom CSS on save for users without edit_css (WordPress/gutenberg#76650)
- Add heading level 1 for the fonts page (WordPress/gutenberg#77482)
- Connectors: Treat network-active plugins as active in plugin status check (WordPress/gutenberg#77661)
- RTC: Fix disconnect dialog due to uneditable entity (WordPress/gutenberg#77242)
- RTC: Fix "Connection Lost" dialog when too many entities are loaded (WordPress/gutenberg#77631)
- RTC: Fix "Edit as HTML" content reset during collaboration (WordPress/gutenberg#77043)
- RTC: Add optional `shouldSync` function to entity sync config (WordPress/gutenberg#76947)
- RTC: Fixed orphaned meta causing dirty editor state (WordPress/gutenberg#77529)
- Ensure "Retry" button is stable during retries (WordPress/gutenberg#77234)
- Patterns: add confirmation dialog before disconnecting/detaching (WordPress/gutenberg#75713)
- Template parts: make 'Detach' context menu item consistent across patterns and template parts (WordPress/gutenberg#77581)
- Remove sandbox `allow-same-origin` for core/html blocks (Merge WordPress/gutenberg#77212 to `wp/7.0`) (WordPress/gutenberg#77699)
- Added Context for Next/Prev Enlarge Image (WordPress/gutenberg#76967)
- Backport: Writing Flow: fix arrow keys skipping paragraph containing link (WordPress/gutenberg#77478)
- Revisions: Improve screen reader accessibility for diff markers region and slider (WordPress/gutenberg#77660)
- Connectors: Add role="list" wrapper to connector cards for valid ARIA structure (WordPress/gutenberg#77689)
- Command Palette: Fix macOs label for sites unable to determine UA via PHP (WordPress/gutenberg#77638)
- RTC: Fix inline inserter reset on update sync (WordPress/gutenberg#76980) (WordPress/gutenberg#77706)
- Connectors: keep focus on action Button during install (WordPress/gutenberg#77544)
- Added Translator Context for Reply (WordPress/gutenberg#77891)
- Editor: Improve revisions diff pairing performance (WordPress/gutenberg#77126)
- Core Data: Treat single-item responses specially (WordPress/gutenberg#76318)
- Site editor: preserve non-global styles in pattern previews (WordPress/gutenberg#77957)
- RTC: Fix divergence when two offline users reconnect (WordPress/gutenberg#77980)
- RTC: Fix compaction unit test (WordPress/gutenberg#77986)
- Connectors: Stop e2e capability restriction from leaking across specs (WordPress/gutenberg#77857)
- Connectors: Clarify AI plugin callout copy (WordPress/gutenberg#78043)
- Fix: Only auto register settings if the plugin the connector references is installed and active. (WordPress/gutenberg#77273)
- Connectors: Add is_active callback support to plugin registration (WordPress/gutenberg#77897)
- RTC: Fix race condition on room creation which can cause a split update log (WordPress/gutenberg#77675)
- RTC: Fix find_canonical_storage_post_id() always returning null (WordPress/gutenberg#78053)
- i18n: add context to scale (WordPress/gutenberg#76917)
- Revisions: Simplify fetching (WordPress/gutenberg#77086)
- e2e: Add e2e tests for template and template part revisions (WordPress/gutenberg#76923)
- Editor: Paginate revisions slider by 100 per page (WordPress/gutenberg#77200) (WordPress/gutenberg#78070)
- Revisions: Add diagonal stripe patterns to diff markers to avoid color-only distinction (WordPress/gutenberg#77904)
- Revision: Fix failing e2e test (WordPress/gutenberg#78079)
- Real-time collaboration: Bundle @wordpress/sync instead of exposing as wp.sync (WordPress/gutenberg#78085)

A full list of changes can be found on GitHub: https://github.com/WordPress/gutenberg/compare/e2970ba736edb99e08fb369d4fb0c378189468ee…c15cef1d6b07f666df28dac0383bafb0edfe0914.

Log created with:

git log --reverse --format="- %s" e2970ba736edb99e08fb369d4fb0c378189468ee..c15cef1d6b07f666df28dac0383bafb0edfe0914 | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy

Reviewed by desrosj.
Merges [62333] to the 7.0 branch.

Props ellatrix, desrosj.
See #64595.
Built from https://develop.svn.wordpress.org/branches/7.0@62335


git-svn-id: http://core.svn.wordpress.org/branches/7.0@61616 1a063a9b-81f0-0310-95a4-ce76da25c4cd
adamsilverstein pushed a commit that referenced this pull request May 16, 2026
…te log (#77675)

When two edit sessions create a “room” for the same document, they can encounter a race where WordPress creates two copies of the sync post meta for that document and the editors can work on two different histories of the document, leading to data loss.

This change introduces a process to merge updates into a canonical sync post meta to avoid this race. When duplicates are detected, the newest sync’d meta is chosen as the new canonical copy and it replaces the other copies.

During this process, additional database activity occurs to resolve the duplicates, though that should normatively present itself when duplicates already exist. Due to a lack of a broadly-supported way to perform database locking, there remains a secondary race when resolving the duplicates; this condition should be rarer than the one which motivated this in the first place. That means that while risk still exists, the overall risk should be much lower. An attempt was made to cover this secondary risk but the solution was complicated and itself unclear.

Co-authored-by: danluu <danluu@git.wordpress.org>
Co-authored-by: dmsnell <dmsnell@git.wordpress.org>
Co-authored-by: peterwilsoncc <peterwilsoncc@git.wordpress.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backported to WP Core Pull request that has been successfully merged into WP Core [Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository [Type] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants