The problem
An agent driving a brmbh theme will sooner or later change a field value on a live page — swap an image ID, fix a typo, reorder a repeater. Nothing in the suite tells it how, so the obvious approach is to treat post_content as a string and str_replace the bit that changes.
That silently corrupts every escape in the block it touches, and there is no guardrail, no verify step, and no error.
Why it corrupts
An ACF block stores its whole field set as JSON inside an HTML comment:
<!-- wp:acf/events-grid {"name":"acf/events-grid","data":{"events_0_body":"…Main &\r\nProf. Dr. …"}} /-->
So serialize_block_attributes() (wp-includes/blocks.php) hex-escapes anything that could break out of that comment — &→&, </>, -- (would end the comment), \" — plus \r\n for newlines typed into a textarea field.
Strip one backslash level and every escape degrades into literal on-page text:
| Stored |
Means |
After the strip |
& |
& |
u0026 |
\r\n |
newline |
rn |
< / > |
< / > |
u003c / u003e |
The usual culprit is the write, not the read: wp_update_post() and wp_insert_post() call wp_unslash() on their input (magic-quotes-era legacy — they expect raw $_POST). Hand them clean content and a backslash level dies. Shell round-trips (--post_content="$(…)", heredocs, sed, jq) do the same.
Nothing warns you. u0026 is still valid JSON, just the wrong string. parse_blocks() parses it, ACF returns it, the template prints it. No checksum, no validation.
It already happened
On a client site built with this theme (Megaherz / Alfasigma), a one-line event-thumbnail image-ID swap corrupted the acf/events-grid block on 2026-07-30. Pinned to a 28-minute window by revision history: rev 259 (11:35:54) clean, rev 264 (12:03:41) corrupt. It shipped to production the same day via db push and the client found it six weeks later, in a PDF review.
The follow-on damage was worse than the bug: someone then hand-deleted the junk tokens in the ACF field, which destroyed the original & and the line breaks outright, with nothing left on the page to show anything had ever been there.
Proposed fix (docs + skill, no code)
- New
/edit-block-content skill in packages/cli/AGENTS/ — snapshot → parse_blocks() → modify → serialize_blocks() → wp_slash() → verify → diff, plus recovery steps for already-corrupted content.
- Hard rule in
AGENTS.md (operating contract + What NOT to do).
- Hard rule in
skills/wordpress/SKILL.md, so it ships via npx skills add brmbh/wordpress.
The verify step is the part that actually prevents recurrence — a rule an agent can check beats one it can only remember:
wp post get <ID> --field=content | grep -oE '[^\\]u00[0-9a-f]{2}|[a-zäöüß]rn[A-ZÄÖÜ]' # must print nothing
Out of scope
A doctor check that scans all posts for these artifacts would catch existing damage across a site — worth a separate issue.
The problem
An agent driving a brmbh theme will sooner or later change a field value on a live page — swap an image ID, fix a typo, reorder a repeater. Nothing in the suite tells it how, so the obvious approach is to treat
post_contentas a string andstr_replacethe bit that changes.That silently corrupts every escape in the block it touches, and there is no guardrail, no verify step, and no error.
Why it corrupts
An ACF block stores its whole field set as JSON inside an HTML comment:
<!-- wp:acf/events-grid {"name":"acf/events-grid","data":{"events_0_body":"…Main &\r\nProf. Dr. …"}} /-->So
serialize_block_attributes()(wp-includes/blocks.php) hex-escapes anything that could break out of that comment —&→&,</>,--(would end the comment),\"— plus\r\nfor newlines typed into a textarea field.Strip one backslash level and every escape degrades into literal on-page text:
&&u0026\r\nrn</></>u003c/u003eThe usual culprit is the write, not the read:
wp_update_post()andwp_insert_post()callwp_unslash()on their input (magic-quotes-era legacy — they expect raw$_POST). Hand them clean content and a backslash level dies. Shell round-trips (--post_content="$(…)", heredocs,sed,jq) do the same.Nothing warns you.
u0026is still valid JSON, just the wrong string.parse_blocks()parses it, ACF returns it, the template prints it. No checksum, no validation.It already happened
On a client site built with this theme (Megaherz / Alfasigma), a one-line event-thumbnail image-ID swap corrupted the
acf/events-gridblock on 2026-07-30. Pinned to a 28-minute window by revision history: rev 259 (11:35:54) clean, rev 264 (12:03:41) corrupt. It shipped to production the same day viadb pushand the client found it six weeks later, in a PDF review.The follow-on damage was worse than the bug: someone then hand-deleted the junk tokens in the ACF field, which destroyed the original
&and the line breaks outright, with nothing left on the page to show anything had ever been there.Proposed fix (docs + skill, no code)
/edit-block-contentskill inpackages/cli/AGENTS/— snapshot →parse_blocks()→ modify →serialize_blocks()→wp_slash()→ verify → diff, plus recovery steps for already-corrupted content.AGENTS.md(operating contract +What NOT to do).skills/wordpress/SKILL.md, so it ships vianpx skills add brmbh/wordpress.The verify step is the part that actually prevents recurrence — a rule an agent can check beats one it can only remember:
Out of scope
A
doctorcheck that scans all posts for these artifacts would catch existing damage across a site — worth a separate issue.