Problem
datamachine_code_resolve_wp_cli_cmd() in data-machine-code.php (line 484) detects posix_geteuid() === 0 and bakes --allow-root into the wp-cli prefix that gets injected into every example throughout the composed AGENTS.md:
function datamachine_code_resolve_wp_cli_cmd(): string {
$parts = array( 'wp' );
if ( function_exists( 'posix_geteuid' ) && 0 === posix_geteuid() ) {
$parts[] = '--allow-root';
}
// ...
}
This is technically correct — --allow-root is what wp-cli requires when running as root. But composing under root means every coding agent that subsequently reads AGENTS.md will be told to use --allow-root too, which keeps the entire host stuck in root-mode invocations. Files written by those agent sessions land as root:root, eventually breaking WordPress auto-updates (see Extra-Chill/wp-coding-agents#93 for the full cascade).
Why this is DMC-shaped
The root cause is upstream — kimaki.service running with User=root is what causes all PHP processes (including the one composing AGENTS.md) to be uid 0. Fixing that at the wp-coding-agents layer would make this a non-issue: posix_geteuid() would return the opencode user's uid, the function would return wp without --allow-root, and AGENTS.md would propagate clean instructions.
But DMC is the layer that actually writes the user-facing instruction. There's a small defensive improvement worth doing here regardless of upstream:
Proposed fix
When posix_geteuid() === 0 is detected during AGENTS.md compose, emit a warning via datamachine_log (or the pre-compose hook, whichever surfaces in the operator's view):
if ( function_exists( 'posix_geteuid' ) && 0 === posix_geteuid() ) {
do_action( 'datamachine_log', 'warning',
'AGENTS.md is being composed under root. Coding agents will inherit `--allow-root` for every wp-cli invocation, which will create root-owned files across wp-admin, wp-includes, wp-content, and uploads. WordPress auto-updates will fail intermittently as a result. Reconfigure the host so the PHP/wp-cli process runs as a non-root user (typically `opencode`); see https://github.com/Extra-Chill/wp-coding-agents/issues/93.',
array(
'composing_uid' => posix_geteuid(),
'composing_user' => function_exists('posix_getpwuid') ? (posix_getpwuid(0)['name'] ?? 'root') : 'root',
)
);
$parts[] = '--allow-root';
}
Alternatives:
- Inline a comment in the composed AGENTS.md (
<!-- WARNING: composed under root, examples below use --allow-root because of this -->) so anyone reading the file sees the trap
- Add a single line at the top of the composed AGENTS.md if the prefix contains
--allow-root: "Note: this site is running coding agents as root, which propagates root-owned files. See [link]."
Why it's worth doing even after wp-coding-agents fixes the upstream issue
- Existing installs that haven't migrated yet would see the warning and know to investigate.
- New installs that hit the
RUN_AS_ROOT=true path (still an option in upstream until that issue lands) would get the warning instead of silently propagating the misconfiguration.
- Local-dev contexts where someone runs
sudo wp datamachine memory compose once would get a one-off warning instead of permanently pinning their AGENTS.md to root semantics.
Acceptance
- AGENTS.md compose under root emits a clear warning explaining the cascade and pointing at the fix.
- The composed AGENTS.md still works (still includes
--allow-root in examples since that's what's required for the misconfigured host).
- No behavior change when composing under a non-root user.
Related
Problem
datamachine_code_resolve_wp_cli_cmd()indata-machine-code.php(line 484) detectsposix_geteuid() === 0and bakes--allow-rootinto the wp-cli prefix that gets injected into every example throughout the composedAGENTS.md:This is technically correct —
--allow-rootis what wp-cli requires when running as root. But composing under root means every coding agent that subsequently reads AGENTS.md will be told to use--allow-roottoo, which keeps the entire host stuck in root-mode invocations. Files written by those agent sessions land asroot:root, eventually breaking WordPress auto-updates (see Extra-Chill/wp-coding-agents#93 for the full cascade).Why this is DMC-shaped
The root cause is upstream — kimaki.service running with
User=rootis what causes all PHP processes (including the one composing AGENTS.md) to be uid 0. Fixing that at thewp-coding-agentslayer would make this a non-issue:posix_geteuid()would return the opencode user's uid, the function would returnwpwithout--allow-root, and AGENTS.md would propagate clean instructions.But DMC is the layer that actually writes the user-facing instruction. There's a small defensive improvement worth doing here regardless of upstream:
Proposed fix
When
posix_geteuid() === 0is detected during AGENTS.md compose, emit a warning viadatamachine_log(or the pre-compose hook, whichever surfaces in the operator's view):Alternatives:
<!-- WARNING: composed under root, examples below use --allow-root because of this -->) so anyone reading the file sees the trap--allow-root: "Note: this site is running coding agents as root, which propagates root-owned files. See [link]."Why it's worth doing even after wp-coding-agents fixes the upstream issue
RUN_AS_ROOT=truepath (still an option in upstream until that issue lands) would get the warning instead of silently propagating the misconfiguration.sudo wp datamachine memory composeonce would get a one-off warning instead of permanently pinning their AGENTS.md to root semantics.Acceptance
--allow-rootin examples since that's what's required for the misconfigured host).Related