Why
A Railway Trial instance reported /data at about 392 MB used with 33 MB free. Its observed breakdown was:
| Path |
Size |
Role |
/data/platform |
133 MB |
live, agent-editable Möbius source tree |
/data/platform.crashloop-prev.20260716T211243Z |
95 MB |
recoverable prior platform tree |
/data/agent-browser-profiles |
95 MB |
per-chat Chromium cache/session state |
/data/logs |
18 MB |
mostly chat.log |
| auth/compiled/db/apps |
~8–16 MB each |
normal durable state |
Railway currently caps Trial volume storage at 0.5 GB and bills volume storage separately from RAM. This is distinct from the active-turn OOM/process-lifecycle work in #130 and the host Docker/build-disk admission work in #151.
Current Railway docs:
What current main already gets right
- Chromium itself is installed in the image at build time and moved to
/opt/agent-browser; it is not the 95 MB under /data.
/data/agent-browser-profiles is cache plus cookies/IndexedDB/session state. Current main applies Railway-aware 128 MiB/96 MiB high/low water defaults and an hourly quota sweep.
/data/platform is intentionally persistent and editable: every owner holds a local copy they can change to change the running app.
- crash-loop trees are intentionally preserved for recovery, not treated as disposable cache.
So “move Chrome into the image” is already done. Moving the live platform tree out of /data would break the local-editability contract, and deleting recovery trees blindly would trade a full-volume failure for data loss.
Needed invariants
- Surface actual volume capacity/free bytes plus a bounded top-level
/data breakdown on the operator health surface. Do not conflate volume bytes with cgroup memory/RSS.
- Before a crash-loop re-clone or any other operation that temporarily needs a second platform tree, perform a free-space admission check.
- Reclaim proven-regenerable browser cache first; never delete an active profile, transcript, credential, DB, app data, or the only recoverable platform copy.
- Replace count-only crash-loop retention (currently up to three full trees) with a byte/capacity-aware policy. Always preserve the newest recovery point; if older recovery history must be pruned, make that explicit and observable.
- Consider whether older platform recovery points can be represented losslessly as a smaller git bundle/patch plus untracked-file archive. Do this only if round-trip tests prove owner edits, modes, symlinks, and untracked files survive.
- Make the browser-profile budget proportional to the actual volume after reserving space for the live platform, DB/auth/app data, one recovery point, and clone/update headroom; keep operator overrides.
- Keep scans off the hot path: event-trigger after known large writes plus a low-frequency reconciliation sweep.
Suggested verification
- simulate a 0.5 GB volume with the measured directory mix and prove a crash-loop restore either admits safely or fails before moving the live tree
- prove reclaim order is cache → older redundant recovery history, never durable owner state
- prove the newest crash-loop recovery point round-trips local commits, dirty tracked files, untracked files, symlinks, and executable modes
- prove active browser profiles and running chats are excluded under pressure
- prove diagnostics report volume bytes separately from cgroup memory values
Related: #130 (RAM/active turns), #151 (host build disk).
Why
A Railway Trial instance reported
/dataat about 392 MB used with 33 MB free. Its observed breakdown was:/data/platform/data/platform.crashloop-prev.20260716T211243Z/data/agent-browser-profiles/data/logschat.logRailway currently caps Trial volume storage at 0.5 GB and bills volume storage separately from RAM. This is distinct from the active-turn OOM/process-lifecycle work in #130 and the host Docker/build-disk admission work in #151.
Current Railway docs:
What current main already gets right
/opt/agent-browser; it is not the 95 MB under/data./data/agent-browser-profilesis cache plus cookies/IndexedDB/session state. Current main applies Railway-aware 128 MiB/96 MiB high/low water defaults and an hourly quota sweep./data/platformis intentionally persistent and editable: every owner holds a local copy they can change to change the running app.So “move Chrome into the image” is already done. Moving the live platform tree out of
/datawould break the local-editability contract, and deleting recovery trees blindly would trade a full-volume failure for data loss.Needed invariants
/databreakdown on the operator health surface. Do not conflate volume bytes with cgroup memory/RSS.Suggested verification
Related: #130 (RAM/active turns), #151 (host build disk).