Skip to content

wordpress-source section lost its purpose, and wp-admin/wp-config.php are neither referenced nor denied #322

Description

@chubes4

The wordpress-source AGENTS.md section has drifted from its purpose, and the read-only root set it shares with the runtime permission layer is missing half of WordPress core.

1. The section's purpose is capability, not restriction

It exists so the agent stops guessing at WordPress and reads the source actually running underneath it. That is what lets a cheap model be competent about WordPress without skills or fine-tuning — Direct Reference was the point, Read-Only was the qualifier.

The managed variant added in #315 inverted that. It is now an editable list, a read-only list, a justification, a production contract, and a "not source" appendix — with "verify core APIs, hooks, conventions, and runtime behavior" surviving as one clause in the middle.

The restriction half is also redundant. lib/source-policy.sh makes the runtime enforce it; the agent cannot write to a denied path. Prose enforces nothing, so restating the deny list buys no safety while crowding out the one thing prose is uniquely good at. Enumerating rather than generalising still matters (#318) — but only so the agent is not misinformed about what it may change, which is a far smaller job than the one the section currently does.

2. wp-admin/ is neither referenced nor denied

wp-admin/ and wp-includes/ are siblings. Core is split across both, plus root bootstrap files.

As reference, the section points only at wp-includes/. That is half of core. wp-admin/ holds the list tables, get_plugins(), media handling, and the upgrade routines — an agent asked to understand or extend admin behavior is pointed away from the code that implements it. This directly undercuts the section's actual purpose.

As policy, _source_policy_all_roots is:

wp-content/plugins
wp-content/themes
wp-includes

So on every install, engineering and managed alike, the agent may edit wp-admin/** and every root PHP file — including wp-config.php, which holds the database credentials, the salts, and the constants that govern the agent itself (DATAMACHINE_COMPOSE_AGENTS_MD, DATAMACHINE_WORKSPACE_PATH). An agent that can rewrite wp-config.php can switch off its own AGENTS.md composition.

Confirmed live on h44lacrosse.com. This predates the posture work; the three globs are original.

3. wp-config.php needs an opt-in, not a blanket deny

Most managed installs should never touch it, but there are legitimate cases (toggling WP_DEBUG, memory limits, a constant a plugin requires).

It cannot reuse --managed-source. That flag means editable and captured, and it is what makes the "your work is recorded" promise true. wp-config.php is not captured by a component harvest. Declaring it as a managed source would have AGENTS.md assert a safety property that does not hold for that path — the #318 bug again.

Two categories, with different prose:

declaration editable captured guidance says
--managed-source <dir> yes yes this site's own source, recorded by the operator's capture
--managed-writable <path> yes no you may change this; nothing records it, so a rebuild loses it

4. Glob trap for whoever implements this

OpenCode's matcher (packages/opencode/src/util/wildcard.ts) converts * to .*, which spans slashes. A pattern like wp-*.php intended for root files would also match wp-content/plugins/acme/wp-thing.php and over-deny inside an owned component.

Root files must be exact literals (wp-config.php, wp-settings.php, …). Wildcard.match anchors ^…$, so a literal matches only that exact relative path. Directory roots keep /**.

This also means source_policy_edit_rules should emit a kind (dir / file) alongside each path, because the three runtimes format them differently: OpenCode appends /** to directories, Claude Code wraps in Edit($site/…), and Codex uses bare directory names in its filesystem profile.

Proposed shape

## WordPress Source

The WordPress running this site is on disk underneath you. Read it to verify core
APIs, hooks, conventions, and runtime behavior instead of relying on assumptions:
`wp-admin/` and `wp-includes/` for core, `wp-content/` for everything installed here.

This site's own source, which is yours to change:
- <enumerated owned paths>

Everything else is reference material.

Reference first. Ownership second. Consequence in a line or two. The permission layer does the rest. The production contract and capture caveats are real but are a different concern and should not swell this section.

Supersedes #320, which fixed false claims inside a shape that is itself wrong.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions