Use this runbook when you need to understand or reclaim Provenote-related disk usage without guessing.
Space governance uses five retention classes only:
ephemeral: cheap transient noise that is safe to clearrebuildable: rebuildable output that still has a developer-time costevidence: current proof or diagnostics that should not be auto-clearedprotected: backup, state, or mixed surfaces that require manual reviewshared_layer: machine-wide surfaces that may be related to Provenote but are not repo-exclusiveClear actions are intentionally separate from rebuildability:
safe_clearcautious_clearverify_before_cleardo_not_clearHuman-readable audit:
bash tooling/scripts/ops/audit_space_surfaces.sh
JSON output for automation:
bash tooling/scripts/ops/audit_space_surfaces.sh --format json
Machine-cache audit lane:
bash tooling/scripts/ops/cleanup_machine_cache.sh --mode audit-only
Housekeeping inventory for repo-managed cleanup candidates:
bash tooling/scripts/ops/audit_space_surfaces.sh \
--inventory-class repo_managed_candidate \
--action-filter safe_clear,cautious_clear
If you specifically need the repo-internal execution view that matches cleanup_runtime_cache.sh, use:
bash tooling/scripts/ops/audit_space_surfaces.sh \
--cleanup-owner cleanup_runtime_cache.sh \
--action-filter safe_clear,cautious_clear
Explicit operator path that chains repo-local runtime cleanup, repo-related machine cache review, and Docker/buildx review:
make cleanup-operator-audit
make cleanup-operator-apply
Detailed machine-cache dry run, including stale bootstrap snapshots:
bash tooling/scripts/ops/cleanup_machine_cache.sh \
--mode dry-run \
--include-stale-bootstrap-snapshots
Schema and contract validation:
bash tooling/scripts/runtime/run_uv_managed.sh run python tooling/scripts/ci/check_space_surfaces.py
Use one explicit operator path instead of remembering separate buildx and repo-local cleanup commands by hand.
make cleanup-operator-dry-run
make cleanup-operator-rebuildable
make cleanup-operator-aggressive
What each lane means:
cleanup-operator-dry-run
docker-buildx-clean is the next manual stepcleanup-operator-rebuildable
docker-buildx-cleancleanup_runtime_cache.sh~/.cache/provenote-* rootscleanup-operator-aggressive
These are small repo-local transient caches such as:
.hypothesis.runtime-cache/test/pytest_cachetests/**/__pycache__mutants/**/__pycache__These are repo-exclusive and rebuildable, but clearing them slows the next run. Some are repo-internal execution targets, while repo-external entries are candidate inventory only:
apps/web/node_modulesapps/web/.runtime-cache/build/next/cache.runtime-cache/local/ruff-cache.runtime-cache/local/mypy-cache.runtime-cache/ci-host/home-cache/provenote/python/uv-cache.runtime-cache/ci-host/home-cache/pre-commit.runtime-cache/ci-host/home-cache/go-build.runtime-cache/ci-host/tmp${HOME}/.cache/provenote/playwright/ms-playwright${HOME}/.cache/provenote/python/uv-cache${HOME}/.cache/provenote/ci-host/npm-cacheImportant boundary:
apps/web/node_modules is a repo-local dependency root..runtime-cache/ci-host/... paths are repo-local runtime/bootstrap residue owned by this checkout.${HOME}/.cache/provenote/... paths are limited to repo-specific machine download caches.Boundary note:
apps/web/node_modules is a repo-local rebuildable dependency root.cd apps/web && npm ci afterwards.These keep current proof, backup, state, or tracked worktree context:
.runtime-cache/runs/current.runtime-cache/closure-backups.runtime-cache/state/local/data.runtime-cache/venv/default.runtime-cache/ci-host/bootstrap/apps-web-node-modules.runtime-cache/ci-host/home-cache/provenote/python/uv-project-environment.runtime-cache/test/coverage/apps/web.runtime-cache/test/coverage/apps/web-direct.runtime-cache/test/coverage-batches/apps-web.runtime-cache/manual-front-a.runtime-cache/manual-front-b.runtime-cache/history-rebuild.runtime-cache/runs/final-release-proof-*.git/cursormutants${HOME}/.cache/provenote/open-source-audit${HOME}/.cache/provenote-* historical candidatesThese are not repo-managed cleanup targets:
.git.git/objects${HOME}/.cache/uv~/.cache/uv${HOME}/.npm${HOME}/Library/Caches/ms-playwright${HOME}/Library/Containers/com.docker.docker${HOME}/.docker${HOME}/.cache/provenote/browser/chrome-user-dataFrontend dependencies:
cd apps/web && npm ci && cd ../..
Managed Python environment and uv cache:
bash tooling/scripts/runtime/run_uv_managed.sh sync --frozen --extra dev
Repo-specific Playwright browsers:
cd apps/web && npm run test:e2e:install && cd ../..
Consistent-container caches:
bash tooling/scripts/ci/run_in_consistent_container.sh --profile python -- \
bash -lc 'bash tooling/scripts/runtime/run_uv_managed.sh sync --frozen --extra dev'
Repo-local managed Python environment:
bash tooling/scripts/runtime/run_uv_managed.sh sync --frozen --extra dev
The canonical single-container supervisor log roots are:
/app/.runtime-cache/runs/current/logs/single-container/.runtime-cache/runs/current/logs/single-container/Current truth boundary:
/tmp/*.log is not a source of truthShared layers are like a building-wide storage room: Provenote may use them, but other projects can be using the same storage at the same time.
That is why these paths stay advisory-only in repo automation:
${HOME}/.npm${HOME}/Library/Caches/ms-playwright${HOME}/Library/Containers/com.docker.docker${HOME}/.dockerThey can still appear in audits, but repo-owned cleanup scripts must not treat them as Provenote-exclusive reclaim targets.
The isolated Chrome user-data root is different:
${HOME}/.cache/provenote/browser/chrome-user-dataIt is repo-exclusive, but it is a permanent browser state surface, not a clearable download cache. Repo automation must treat it as protected browser state and keep it out of TTL/cap trimming.
Provenote now keeps Docker/buildx cleanup explicit instead of leaving it as tribal knowledge.
make docker-runtime-audit
open-notebook-ci:* images, buildx builders, and docker system df -v outputmake docker-buildx-clean
make cleanup-operator-audit
make cleanup-operator-apply
This split matters:
open-notebook-ci:* and buildx residue belong to the Docker operator viewapps/web/node_modules belongs to the repo-local rebuildable dependency view.runtime-cache/venv/default and .runtime-cache/ci-host/... belong to the repo-local runtime/bootstrap view~/.cache/provenote/... belongs to the repo-related machine-cache view only when the surface is a download cacheTwo inventory views intentionally coexist:
--inventory-class repo_managed_candidate --action-filter ...
--cleanup-owner cleanup_runtime_cache.sh --action-filter ...
cleanup_runtime_cache.shDocker attribution uses three states:
unresolvedreachable_but_unattributedresolvedUntil a dedicated per-repo Docker attribution lane exists, Docker Desktop should stay in the first two states only.
The canonical repo-specific machine cache root is:
${HOME}/.cache/provenoteImportant subtrees inside that namespace:
${HOME}/.cache/provenote/python/uv-cache${HOME}/.cache/provenote/playwright/ms-playwright${HOME}/.cache/provenote/ci-host/npm-cacheTreat this namespace like a repo-owned download shed: it is still Provenote-related space even though it lives outside the checkout, but it should only contain reusable download caches.
The audit intentionally separates four ideas:
This is why the distinct summary can show historical candidates separately from strict confirmed totals. It prevents parent/child double counting and keeps unresolved named candidates from being silently mixed into the confirmed repo footprint.
~/.cache/provenote-* entries are migration-only historical candidates. The canonical machine cache root is ~/.cache/provenote, and entrypoint-triggered machine-cache cleanup now removes stray legacy roots instead of preserving them indefinitely.
.runtime-cache/ci-host/bootstrap/apps-web-node-modules stores lock-hash keyed frontend dependency snapshots for the consistent-container bootstrap flow.
Those snapshots must be classified before cleanup:
active-bootstrap-cache: matches the current frontend lock hash and must be preservedstale-bootstrap-candidate: does not match the current lock hash; report first, then only clear when age/generation thresholds and lock-safety checks passThe repo-local cleanup lane must never wipe the bootstrap root wholesale. It may only consider stale snapshots individually, while preserving the active hash and any locked snapshot directories.