Skip to content

Add core/edit-content ability for targeted post content edits - #945

Open
seedprod wants to merge 1 commit into
WordPress:developfrom
seedprod:feat/core-edit-content
Open

Add core/edit-content ability for targeted post content edits#945
seedprod wants to merge 1 commit into
WordPress:developfrom
seedprod:feat/core-edit-content

Conversation

@seedprod

@seedprod seedprod commented Aug 16, 2026

Copy link
Copy Markdown

What?

See #40.

Adds a core/edit-content Ability — the write twin of core/read-content (#739). It applies a server-side, exact-match text replacement to a post's title, excerpt, or content, instead of requiring clients to round-trip the whole field.

Why?

Whole-field writes force an AI client to fetch an entire content blob, mutate it in context, and send it all back — expensive, and every untouched byte the model re-emits is a byte it can corrupt. A server-side anchored patch means only the changed snippet ever transits the client. This is the editing contract AI coding tools have broadly converged on (exact string, unique match, fail loudly), applied to WordPress content with capability checks and revisions.

How?

  • old_content is matched byte-for-byte against the stored raw value; the match count must equal expected_matches (default 1) or the edit is refused with the actual count. No regex, no fuzzy matching — a stale or wrong snippet fails loudly rather than editing the wrong place.
  • Every refusal (unknown/unexposed post, unsupported field, serialized value, no match, count mismatch) leaves the post unchanged.
  • Persists via wp_update_post(), so revisions and normal save filters apply. The response reports replaced, status, modified_gmt, and an exact_persistence flag (false when save filters such as KSES altered the saved value) — deliberately not the full field value.
  • Permission gate: authenticated + post type exposed via show_in_abilities + current_user_can( 'edit_post' ), resolved before execution; all denials are uniform.
  • Registers through its own gated class (Gated\Edit_Content) rather than inside Read_Content, so write access is an individually removable unit via the wpai_gated_abilities filter. Maintainers may prefer a separate experiment for write abilities — open to that.

Known limitations (documented in code): the match check and save are not atomic (patch-on-snapshot, not compare-and-swap); is_serialized() guards whole-value serialization only; the input schema's post type enum snapshots exposure at registration (same as read). Natural follow-up: a bounded raw search/snippet ability so clients can locate exact anchors without reading whole fields.

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code (Fable); Codex CLI (independent design review)
Model(s): Claude Fable 5, GPT-5.6-sol
Used for: Implementation and tests, built to my specification and design decisions; the design and final patch were adversarially reviewed with independent AI reviewers before submission. I take responsibility for this contribution.

Testing Instructions

  1. npm run wp-env:test start
  2. npm run test:php -- --filter EditContentTest (18 tests: happy paths for all three fields with revision assertions, every refusal code, capability and exposure denials, serialized refusal, literal $/\ handling, fail-closed ID parsing, expected-match semantics)
  3. Full suite: npm run test:php — 1391 tests passing locally; composer lint and composer phpstan clean.

Changelog Entry

Added - New core/edit-content Ability that applies an exact-match, server-side text replacement to a post's title, excerpt, or content, with expected-match verification, uniform permission gating, and revision support.

🤖 Generated with Claude Code

Open WordPress Playground Preview

Registers a write twin of core/read-content: a server-side, exact-match
text replacement on a post's title, excerpt, or content. The snippet
must match exactly expected_matches times (default 1); every failure
leaves the post unchanged. Saves through wp_update_post() so revisions
and save filters apply, and reports the persisted result compactly
without echoing the full field value.

The ability registers through its own gated class so write access is an
individually gateable unit alongside the read-only gated abilities.

See WordPress#40.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@seedprod
seedprod requested a review from a team August 16, 2026 23:34
@github-actions

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: seedprod <johnnytee@git.wordpress.org>

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

@codecov

codecov Bot commented Aug 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.66667% with 44 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.12%. Comparing base (a0f5ea2) to head (6c5b185).
⚠️ Report is 19 commits behind head on develop.

Files with missing lines Patch % Lines
includes/Abilities/Content/Content.php 81.27% 44 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             develop     #945      +/-   ##
=============================================
+ Coverage      76.01%   76.12%   +0.11%     
- Complexity      3032     3074      +42     
=============================================
  Files            132      133       +1     
  Lines          12001    12241     +240     
=============================================
+ Hits            9123     9319     +196     
- Misses          2878     2922      +44     
Flag Coverage Δ
unit 76.12% <81.66%> (+0.11%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jeffpaul jeffpaul added this to the 1.4.0 milestone Aug 18, 2026
@jeffpaul jeffpaul moved this from Triage to Needs review in WordPress AI Roadmap Aug 18, 2026
@gziolo
gziolo removed their request for review September 3, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Needs review

Development

Successfully merging this pull request may close these issues.

2 participants