Persistent workspace quota and migration
Source:
docs/14-workspace-quota.mdat2081f31a099e· docs version 0.4.0
Result
Section titled “Result”tentaflake.workspaceQuota.agents.<container> mounts a fixed-size ext4
filesystem at one controller workspace. Its backing file has an exact declared
size, so both controller writes and worker-inbox writes receive a real
filesystem ENOSPC instead of consuming the host root filesystem without a
per-agent ceiling.
A deliberately stopped balanced scaffold may omit this disk mutation. An automatically started balanced controller must declare its matching quota; evaluation fails until the path and numeric owner match the runtime builder.
This module deliberately covers the code workspace, not every runtime-specific state path. Sessions, caches, broker state, audit, backups, and the backing image directory still require host free-space monitoring.
Declaration
Section titled “Declaration”The key, path, and owner must match the runtime builder:
tentaflake.workspaceQuota.agents.hermes-coding = { enable = true; workspace = "/var/lib/hermes-coding/workspace"; sizeMiB = 8192; ownerUid = 10000; ownerGid = 10000;};ZeroClaw uses numeric UID/GID 65534 by default. Builder assertions reject a path or owner mismatch. The agent unit requires the mount/ownership unit, so a missing image, failed filesystem check, mount failure, or ownership failure prevents the controller from starting.
First activation is a disk mutation
Section titled “First activation is a disk mutation”Enabling the option and activating the resulting NixOS generation creates:
/var/lib/tentaflake-workspace-volumes/ hermes-coding.imgThe prepare unit creates the exact-size sparse file, formats it as ext4, and
mounts it with loop,nodev,nosuid,noatime. This is an intentional filesystem
mutation. A source build or evaluation does not perform it and does not
authorize activation.
The managed mount starts after the host’s ordinary local filesystems and tmpfiles setup. Its ownership unit then recreates the private worker-control directories inside the mounted filesystem before the controller or worker watcher may start. The inbox is writable only by the exact agent UID/GID and the host worker’s statically declared matching service group. Unsafe symlink or non-directory control paths fail closed.
The module refuses first creation when the declared workspace contains data.
It tolerates only the empty .tentaflake-worker/inbox scaffolding that NixOS
tmpfiles may create during activation. It also rejects a symlink/non-regular
backing path, a leftover .new image, or any size mismatch. It never mounts
over existing data, shrinks, grows, or reformats an existing image silently.
Existing workspace migration
Section titled “Existing workspace migration”Perform this only in an approved maintenance window and adapt paths to the exact stopped agent:
- Back up and verify the existing workspace.
- Stop the exact agent and its brokers.
- Move the old workspace to a reviewed temporary path on the same host.
- Activate the generation with the quota declaration; confirm the empty filesystem mounted and has the configured byte size.
- Copy reviewed data into the mounted workspace without crossing its limit.
- Verify numeric ownership, run the security doctor, and start the agent.
- Keep the verified backup until a restore/start drill passes.
Tentaflake intentionally provides no automatic migration command because a wrong source, destination, or size would be destructive.
Resize and recovery
Section titled “Resize and recovery”Changing sizeMiB while the image exists fails closed. Resize requires a
separate offline procedure: stop the controller/worker, unmount the exact
workspace, verify a backup, check the filesystem, grow the backing file, run
resize2fs, update the declaration, and rebuild. Shrinking is substantially
riskier and should use backup/restore into a new image instead.
At boot, the prepare service runs e2fsck -p only while the workspace is not
mounted. Return codes above the automatically repairable class fail the mount
and therefore fail the controller dependency. Preserve the image and restore
from backup rather than forcing a damaged filesystem online.
Verification boundary
Section titled “Verification boundary”Module tests prove declaration matching, mount dependencies, fixed path/options, and the fail-closed non-empty check. The VM test boots the mount, verifies the exact backing-file size and ext4 type, and confirms a write beyond the limit fails. Without a completed VM/live run, evaluation alone is not quota proof.