Overview
Use this for emergency local disk cleanup on the user's machine. The core rule is: inspect first, reclaim obvious rebuildable or disposable data, preserve continuity, and never delete personal/project artifacts just because they are old.
The concrete macOS pattern learned on this host: a single active Codex log (~/.codex/log/codex-tui.log) can grow past 150 GiB while many Codex processes keep it open. The right response is not broad deletion; preserve a tail, truncate the active log, then verify free space.
When to Use
Use when the user says any of:
- Insufficient local space
- Disk is full
- Not enough space
- Free up space
- Clean up local junk
- Delete what is not used
- Delete what has not been used within a week
- Delete untagged ones
- Clean up untagged files
- Codex logs are too large
- Hermes state snapshots are too large
- macOS cache is too large
Do not use for:
- deciding which personal documents, books, screenshots, or Downloads to delete without a candidate list
- deleting repos, worktrees, session history, memories, skills, plugins, cron jobs, auth, or credentials
- destructive cleanup without a manifest and before/after verification
Safety Contract
- Baseline first:
df -h / /System/Volumes/Data 2>/dev/null || df -h /du -xhd1 "$HOME" 2>/dev/null | sort -h | tail -30
- Treat Finder tags as keep signals. Before deleting user-facing files, check
com.apple.metadata:_kMDItemUserTags. - Default safe deletion scope:
- rebuildable caches:
~/.cache,~/Library/Caches, package-manager caches - temp folders explicitly named temp/tmp
- old Hermes pre-update snapshots or legacy checkpoints beyond retention
- oversized logs, but truncate with tail preservation rather than blind delete
- rebuildable caches:
- Default protected scope:
~/Downloads,~/Documents,~/Desktop, repo roots, credentials, session transcripts, memories, skills, plugins, cron state
- For active logs opened by a running process, use
lsoffirst and preserve a tail before truncation. - Write a cleanup manifest under
~/.hermes/logs/with removed paths, byte counts, skipped tagged paths, command outputs, and errors. - Verify after cleanup with
dfand targeteddu.
Triage Commands
Session References
references/macos-disk-candidates-20260530.mdrecords observed Codex SQLite log behavior, Chrome model-cache targets, Hermes state caveats, and targeted macOS scan commands from a real cleanup run.
Triage Commands
# Filesystem pressure
df -h / /System/Volumes/Data 2>/dev/null || df -h /
# Largest top-level roots under home
du -xhd1 "$HOME" 2>/dev/null | sort -h | tail -30
# Common local-state roots
du -xhd1 "$HOME"/.codex "$HOME"/.hermes "$HOME"/.cache "$HOME"/Library 2>/dev/null | sort -h | tail -50
# Largest files in a suspect root
python3 - <<'PY'
import os, time, heapq
root=os.path.expanduser('~/.codex/log')
heap=[]
for dp, dns, fns in os.walk(root):
for fn in fns:
p=os.path.join(dp,fn)
try: st=os.stat(p)
except OSError: continue
item=(st.st_size,p,st.st_mtime)
if len(heap)<30: heapq.heappush(heap,item)
else: heapq.heappushpop(heap,item)
for size,p,mt in sorted(heap, reverse=True):
print(f'{size/1024/1024/1024:8.2f}G {((time.time()-mt)/86400):6.1f}d {p}')
PY
# Who is writing an oversized log
lsof "$HOME/.codex/log/codex-tui.log" 2>/dev/null | head -20
Safe Active Log Truncation
Use this pattern when a log is huge and active. It keeps the last bytes for evidence and truncates the same inode so open writers continue safely.
python3 - <<'PY'
from pathlib import Path
import time
path = Path.home()/'.codex/log/codex-tui.log'
keep_bytes = 20 * 1024 * 1024
archive_dir = Path.home()/'.codex/archived_logs'
archive_dir.mkdir(parents=True, exist_ok=True)
stamp = time.strftime('%Y%m%d-%H%M%S')
tail_path = archive_dir / f'{path.name}.{stamp}.tail'
size = path.stat().st_size
with open(path, 'rb') as f:
f.seek(max(0, size - keep_bytes))
data = f.read()
with open(tail_path, 'wb') as out:
out.write(data)
with open(path, 'r+b') as f:
f.truncate(0)
print(f'truncated={path} old_bytes={size} kept_tail={tail_path} kept_bytes={len(data)}')
PY
Also check Hermes MCP stderr when Hermes logs are large:
lsof "$HOME/.hermes/logs/mcp-stderr.log" 2>/dev/null | head -20
Apply the same preserve-tail-and-truncate pattern, with keep_bytes = 5 * 1024 * 1024 and archive dir ~/.hermes/logs/archived.
Older-than-7-Days Untagged Cleanup
For this user's phrasing, "no need [to use it] within one week" means candidates older than 7 days. Do not apply it to all of $HOME. Apply only to safe classes unless the user explicitly approves a candidate list for personal files.
Safe classes:
~/.cache/*older than 7 days and untagged~/Library/Caches/*older than 7 days and untagged~/tmp/*older than 7 days and untagged~/.hermes/state-snapshots/YYYYMMDD-*-pre-updateolder than 7 days and untagged~/.hermes/checkpoints/legacy-*older than 7 days and untagged
Do not automatically delete old files under ~/Downloads; produce a list first.
Finder tag check:
import os
def has_finder_tags(path: str) -> bool:
try:
return bool(os.getxattr(path, 'com.apple.metadata:_kMDItemUserTags'))
except OSError:
return False
Package Cache Cleaners
Run after targeted triage, not before the baseline:
uv cache prune --no-progress
npm cache clean --force
python3 -m pip cache purge
go clean -cache -testcache
brew cleanup --prune=7
Ignore unavailable tools. Record output in the manifest.
Manifest Requirements
Write JSON to:
~/.hermes/logs/disk-cleanup-YYYYMMDD-HHMMSS.json
Include:
- start and finish timestamp
- before and after
df - every removed path and byte count
- every truncated log, old size, tail path, kept bytes
- every skipped path due to Finder tags
- every package-clean command exit code and output tail
- errors such as macOS Trash permission denial
Verification Checklist
-
dfshows meaningful reclaimed space. - Largest suspected log no longer dominates disk usage.
- Tail archive exists for truncated logs.
- Recent Hermes state snapshots remain if they are within retention.
-
Downloads, repos, documents, skills, memories, sessions, auth, and cron state were not broadly deleted. - Manifest path is reported to the user.
Common Pitfalls
- Broadly applying "older than 7 days" to the whole home directory. This can delete books, screenshots, datasets, and project artifacts. Restrict to safe classes first.
- Deleting an open log file instead of truncating it. On Unix, deleting an open file may not reclaim space until the writer exits. Truncate the active inode after preserving a tail.
- Trusting source paths over live disk usage. Always use
duandlsofon the live machine. - Treating all
.hermesstate as disposable. Preserve sessions, auth, skills, plugins, cron jobs, and recent snapshots. - Failing silently on macOS protected folders such as
.Trash. Record permission errors; do not force privileged deletion unless explicitly approved.