Skip to content

Docs: add integrator guidance to the Agent Users README - #1010

Closed
webmyc wants to merge 1 commit into
WordPress:add/agent-users-experimentfrom
webmyc:add/agent-users-integrator-guidance
Closed

webmyc wants to merge 1 commit into
WordPress:add/agent-users-experimentfrom
webmyc:add/agent-users-integrator-guidance

Conversation

@webmyc

@webmyc webmyc commented Sep 8, 2026 •

Copy link
Copy Markdown

Follow-up to #961 (comment), where you said you would take the integrator section as a follow-up. Based on add/agent-users-experiment rather than develop, because the README does not exist there yet.

Scope is exactly the section that was agreed: guidance for third-party code, no hooks, no changes to the identity model. It points at wpai_is_agent_user() and the documented wpai_agent key and stops there. I have deliberately not touched the site-owned KSES allowlist, since you postponed that until the identity contract settles and i think that is the right order.

Why these four parts

I shipped the same bug this documents, in three places, so the section is written from the repair rather than from theory.

Respira resolves a WordPress user for any request that arrives without one, so writes carry an author. Three resolvers picked the lowest-numbered administrator, which on a site provisioned agent-first by a host or WP-CLI is an agent: the run-as for a whole MCP session, the duplicator adopting an admin identity so wp_insert_post()'s internal unfiltered_html check passes, and the account an API key binds to.

The branch that most needed the fix is the one i would not have predicted. Our resolver falls back to a capability scan, and that fallback exists because the role query came back empty on two real customer sites: a multisite subsite whose administrator was a network super admin never added to the site, and a single-site install where admin rights came from a custom role plugin through user_has_cap. Both looped OAuth clients forever on a 401. The repair in both cases was to resolve by capability instead of by role.

Which is the standard advice, and which is exactly the branch an Administrator agent satisfies. Fixing only the role query would have moved the bug one branch down. That is why the section spends a paragraph on it rather than a line.

For scale: that code runs on 1,335 WordPress sites in the last 90 days, 1,001 of which took at least one successful write from an assistant, 187,050 successful writes since 10 June. Fixed on our side in 8.8.26, including the part where the security scanner deliberately keeps listing agent administrators, because an agent with admin rights that nobody remembers provisioning is the finding rather than noise.

Two things i left out on purpose

No recommended default for attribution. Whether an agent's display name should reach a visitor is a site's editorial decision, and a plugin guessing at it is how you get surprising bylines.

No hook, per the above.

One observation worth having in your pocket: the multisite rule that agents cannot be super admins gives integrators a fallback path that cannot land on an agent. It is a nice second-order property of a restriction you added for a different reason, and the section says so.

Happy to cut this down, split it, or move it under Developer reference instead of after it. Voice is aimed at matching the rest of the file rather than my own, so say the word if it reads off.

Open WordPress Playground Preview

Follow-up to the note in WordPress#961: guidance for plugin and theme code that has to
change once agent users exist.

Four parts. Choosing a user to act as, which is the resolver problem and the
one most likely to be several years old and several layers down. Attribution
and display, since post_author can now point at an agent. Content written by
an agent, because KSES applies below Administrator. And what not to change,
because the defensive instincts here make things worse.

Nothing is proposed that the experiment does not already provide: it points at
wpai_is_agent_user() and the documented wpai_agent meta key, and it adds no
hooks, matching the decision to withhold extension points until the identity
contract settles.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@webmyc
webmyc requested a review from a team as a code owner September 8, 2026 10:56
@github-actions

github-actions Bot commented Sep 8, 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: webmyc <urbankidro@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>
Co-authored-by: dkotter <dkotter@git.wordpress.org>

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

@webmyc

webmyc commented Sep 8, 2026

Copy link
Copy Markdown
Author

@gziolo this is the README section from #961 (comment), as a follow-up against the experiment branch. Scoped to what was agreed: integrator guidance only, no hooks, nothing that touches the identity model.

Since i last commented i went and fixed the same bug in my own plugin, so the section is written from the repair. The part i would not have guessed is that the capability-based fallback is the one that most needs the agent check. Our resolver has that fallback because the role query came back empty on two real customer installs, and resolving by capability is the standard repair for it. An Administrator agent satisfies it exactly. Fixing only the role query moves the bug one branch down, so the section spends a paragraph there rather than a line.

Also worth noting: agents not being able to become super admins means a resolver that falls back to get_super_admins() cannot land on one. That is a useful second-order property of a restriction you added for a different reason, and the section points it out.

Nothing here needs a decision from you on the KSES allowlist. That still reads to me like the right thing to hold until the identity contract settles.

@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 75.60%. Comparing base (dcae15b) to head (c828d7d).

Additional details and impacted files
@@                      Coverage Diff                      @@
##             add/agent-users-experiment    #1010   +/-   ##
=============================================================
  Coverage                         75.60%   75.60%           
  Complexity                         3562     3562           
=============================================================
  Files                               145      145           
  Lines                             13606    13606           
=============================================================
  Hits                              10287    10287           
  Misses                             3319     3319           
Flag Coverage Δ
unit 75.60% <ø> (ø)

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.

@webmyc

webmyc commented Sep 8, 2026

Copy link
Copy Markdown
Author

The six failing Test PHP jobs here are not from this PR, which changes one markdown file and no code.

They fail the same way on the base branch's own head (dcae15b), and repo-wide: of the last 30 Test runs there is one success on 5 September and nothing green since.

The cause is the wp-env image build, not the test suite:

27 |     RUN apt-get clean
28 | >>> RUN apt-get -qy update
target wordpress: failed to solve: process "/bin/sh -c apt-get -qy update"
  did not complete successfully: exit code: 100

Three retries, same result each time. apt exit 100 at image build is a package-source problem rather than anything in the branch, so it will most likely need either a base-image bump or a rebuild once the mirror settles.

Flagging it because a docs PR sitting under six red checks looks like it broke something, and it did not.

@gziolo

gziolo commented Sep 9, 2026

Copy link
Copy Markdown
Member

Thank you for opening the PR. I will have a closer look in the next few days. I experienced similar issues with CI jobs on another PR.

@dkotter

dkotter commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

I experienced similar issues with CI jobs on another PR.

Yeah, there's a known issue with wp-env where the PHP 7.4 and 8.0 images are no longer working (see #1011 (comment)).

Edit: I believe this has been fixed upstream now in WordPress/gutenberg#82478 and should be in the next release of wp-env

@jeffpaul
jeffpaul requested a review from gziolo September 21, 2026 17:01
@jeffpaul jeffpaul added this to the 1.5.0 milestone Sep 21, 2026
@jeffpaul jeffpaul moved this from Triage to Needs review in WordPress AI Roadmap Sep 21, 2026
@webmyc

webmyc commented Oct 5, 2026

Copy link
Copy Markdown
Author

@gziolo does this need anything from me to move forward? #961 has not changed since I opened it, so the section still matches the branch, and the CI failures were the wp-env images that are fixed upstream now. Happy to rebase or trim it if the identity model changes with #1068.

@gziolo

gziolo commented Oct 5, 2026

Copy link
Copy Markdown
Member

@webmyc, thank you for this! Please change the base of this PR to add/agent-users-parent-accounts in @nerrad's fork (#1068), which replaces #961.

Some details are outdated now. In #1068, every agent has a human parent account, and we use it to find on whose behalf a task was performed (wpai_get_agent_parent()). The parent's permissions also limit what the agent can do. Could you update the guide to match? The part about user resolvers that pick the first administrator is still useful.

@webmyc

webmyc commented Oct 5, 2026

Copy link
Copy Markdown
Author

@gziolo thanks. GitHub cannot point this PR at a branch in another fork, so I opened it against #1068's branch in @nerrad's fork instead: nerrad#1

The guide is updated for the parent model: wpai_get_agent_parent() to find the person an agent acts for, notifications and "needs a human" checks going to the parent, the parent as the ceiling on what the agent can do, and suspended agents in the resolver section. The first-administrator resolver part is kept. Closing this one in favour of it.

@webmyc webmyc closed this Oct 5, 2026
@jeffpaul jeffpaul removed this from the 1.5.0 milestone Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants