Summary
Privileged provisioning steps in wp-coding-agents create files under /var/lib/datamachine/workspace (and /opt/kimaki-config) owned by root:root, but the runtime they serve executes as User=opencode. The agent therefore cannot read its own config or clean up its own worktrees, the DMC-blessed cleanup path fails with Permission denied, and disk fills with un-reclaimable node_modules.
On this VPS that's 19G of node_modules across 29 worktrees, with the disk at 95% and the agent unable to delete a single byte of it.
Evidence (live VPS, extrachill.com)
The kimaki/opencode runtime is the opencode user:
$ systemctl show kimaki.service -p User
User=opencode
$ id -un # what the agent runs as
opencode
But the systemd unit runs a root ExecStartPre (note the + prefix = run as root regardless of User=):
# /etc/systemd/system/kimaki.service.d/post-upgrade.conf
[Service]
ExecStartPre=
ExecStartPre=-/usr/bin/pkill -TERM -u opencode -f "opencode-ai/bin/.*serve"
ExecStartPre=+/opt/kimaki-config/post-upgrade.sh # <-- runs as ROOT
/opt/kimaki-config/post-upgrade.sh itself is root-owned and unreadable to the agent:
$ cat /opt/kimaki-config/post-upgrade.sh
cat: Permission denied
Workspace worktrees + the lock dir are all root:root, so the agent can't manage them:
$ ls -ld /var/lib/datamachine/workspace/data-machine@wake-briefing
drwxr-xr-x 12 root root 4096 Jun 6 22:31 .../data-machine@wake-briefing
$ ls -ld /var/lib/datamachine/workspace/.locks
drwxr-xr-x 2 root root 4096 .../.locks
$ ls -l /var/lib/datamachine/workspace/.locks | head -2
-rw-r--r-- 1 root root 0 .../worktree-agents-api.lock
Consequence — the blessed cleanup path is unusable for the agent:
$ wp datamachine-code workspace hygiene
Warning: fopen(/var/lib/datamachine/workspace/.locks/worktree-*.lock):
Failed to open stream: Permission denied
(repeats for every repo; report never completes)
$ rm -rf /var/lib/datamachine/workspace/data-machine@wake-briefing
rm: cannot remove '.../node_modules/...': Permission denied
Disk impact:
$ df -h /
/dev/sda1 150G 136G 8.6G 95% /
$ du -sch /var/lib/datamachine/workspace/*/node_modules | tail -1
19G total
$ ls -1d /var/lib/datamachine/workspace/*@* | wc -l
29
Root cause
Two privileged write paths leave root:root artifacts in trees the opencode runtime is supposed to self-manage:
ExecStartPre=+/opt/kimaki-config/post-upgrade.sh runs as root on every kimaki start/upgrade.
- Root-invoked
homeboy worktree/deploy steps (cross-referenced in the linked homeboy issue) write worktrees as root.
Both contradict the runtime's User=opencode.
Suggested fix (in wp-coding-agents provisioning)
- After any privileged step,
chown -R opencode:opencode /var/lib/datamachine/workspace /opt/kimaki-config (or whatever the configured agent user/group is — don't hardcode opencode).
- Better: have privileged steps create as the agent user (drop privileges /
install -o "$AGENT_USER" -g "$AGENT_GROUP"), and set group-writable umask so the agent can always clean its own workspace.
- Ensure
/var/lib/datamachine/workspace/.locks is agent-owned so wp datamachine-code workspace hygiene/cleanup can actually run.
Acceptance
wp datamachine-code workspace hygiene runs to completion as the agent user with no Permission denied.
- The agent can
rm/prune its own worktrees and node_modules without sudo.
- A fresh
post-upgrade.sh run does not leave root-owned files under the workspace or config dirs.
Cross-ref: Extra-Chill/homeboy (root-run deploy/worktree ownership side).
Summary
Privileged provisioning steps in wp-coding-agents create files under
/var/lib/datamachine/workspace(and/opt/kimaki-config) owned byroot:root, but the runtime they serve executes asUser=opencode. The agent therefore cannot read its own config or clean up its own worktrees, the DMC-blessed cleanup path fails withPermission denied, and disk fills with un-reclaimablenode_modules.On this VPS that's 19G of node_modules across 29 worktrees, with the disk at 95% and the agent unable to delete a single byte of it.
Evidence (live VPS, extrachill.com)
The kimaki/opencode runtime is the
opencodeuser:But the systemd unit runs a root ExecStartPre (note the
+prefix = run as root regardless ofUser=):/opt/kimaki-config/post-upgrade.shitself is root-owned and unreadable to the agent:Workspace worktrees + the lock dir are all
root:root, so the agent can't manage them:Consequence — the blessed cleanup path is unusable for the agent:
Disk impact:
Root cause
Two privileged write paths leave
root:rootartifacts in trees theopencoderuntime is supposed to self-manage:ExecStartPre=+/opt/kimaki-config/post-upgrade.shruns as root on every kimaki start/upgrade.homeboyworktree/deploy steps (cross-referenced in the linked homeboy issue) write worktrees as root.Both contradict the runtime's
User=opencode.Suggested fix (in wp-coding-agents provisioning)
chown -R opencode:opencode /var/lib/datamachine/workspace /opt/kimaki-config(or whatever the configured agent user/group is — don't hardcodeopencode).install -o "$AGENT_USER" -g "$AGENT_GROUP"), and set group-writable umask so the agent can always clean its own workspace./var/lib/datamachine/workspace/.locksis agent-owned sowp datamachine-code workspace hygiene/cleanupcan actually run.Acceptance
wp datamachine-code workspace hygieneruns to completion as the agent user with noPermission denied.rm/prune its own worktrees and node_modules without sudo.post-upgrade.shrun does not leave root-owned files under the workspace or config dirs.Cross-ref: Extra-Chill/homeboy (root-run deploy/worktree ownership side).