Skip to content
C.W.K.
Lesson 05 of 05 · published

Refuse and Stop, Never Prune

~15 min · retention, disk-space, purgeable, apfs, data-safety

Level 0Closed Lens
0 XP0/45 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete

The App Never Deletes a Recording

Invariant 11 is short: the app never deletes a recording. Space is protected by refusing to start and by stopping cleanly, never by pruning. Recordings are Dad's data, and the most common way recording software loses data is not a crash; it is a well-meant cleanup that deletes the oldest files to make room for new ones. Oriel does not have that code path at all.

So when the disk runs low, Oriel has exactly two moves. Before a session: refuse to start it. During a session: stop it cleanly, closing the open segment with its sidecar, so everything recorded so far is whole and indexed. Then a person decides what to move.

The Numbers Dad Approved

LineValueWhat happens
Recordings cap on the home Mac2.5 TB (about 107 h of both feeds)sessions beyond it are proposed for the archive
Start floor500 GB availableno new session below it
Stop floor300 GB availablea running session stops cleanly below it
Hard stop20 GB free right nowa running session stops below it, whatever "available" says
Archive proposalolder than 90 daysproposed for the NAS archive; moved only on Dad's yes; pinned sessions stay

The settings themselves defend the order: the stop floor must stay below the start floor, or the change is refused.

Which "Free" Do You Mean?

The floors judge available space, and on a Mac that word has two honest meanings. statfs (what df and Python's shutil.disk_usage report) counts only blocks free right now. System Settings, Finder and the family's disk tools add the APFS purgeable space macOS frees on demand: caches, local snapshots, files it can re-download. On the workbench Mac the two read 0.49 TB and 3.98 TB. A recorder judged by statfs there would have refused every session on a disk with nearly four terabytes Dad could use.

So Oriel judges the start and stop floors on available space as System Settings counts it, read through the family kit's disk-space helper. But it keeps a second line on the other meaning, because of one thing nobody has measured: macOS frees purgeable space on its own schedule, and a recorder is a writer that never pauses. If the purge does not keep pace, "available" can be large while the next write fails. The 20 GB hard stop on free-right-now space is that last line. A reading costs about 30 ms (it asks macOS's purge accounting), so the engine reuses one for ten seconds; ten seconds of recording is far inside 20 GB.

What Oriel Does Delete, Listed in One Place

"Never deletes a recording" does not mean "never deletes anything". A few files are working material, not recordings, and the architecture document's Retention section lists every one of them with its own clock: a one-shot frame (a peek, a gimbal move's before-and-after) a week after it was taken; a look's viewing copy of a phone-body or network-camera photo after two minutes; a park's check frames once measured; a phone-body photo with a person in it, or one that could not be checked, once the look has its copy. The rule for adding to that list is the interesting part: a new deletion is added to the Retention section first, and only then written. A list like that is only trustworthy if it is the one place deletions are allowed to exist.

Restarts Are a Way to Lose Data Too

The same instinct guards against the other quiet loss: a deploy that restarts the recorder in the middle of a recording. Every install script asks a deploy guard first. Any open session, or a held span such as the gap between a rehearsal and a test run, refuses the restart by default, naming every blocker; a script can wait for the session to end instead. Going under a blocker takes a single-use override that only Dad's own words can write. One deploy cut a synchronization test short before this existed, and that was enough.

Code

Two meanings of free, two lines, and a clean stop (trimmed excerpts, backend/engine.py)·python
def disk(self) -> dict:
    """The floors judge ``available_gb``: free + purgeable, as System Settings counts
    it (statfs alone called the workbench Mac 0.49 TB free against Settings' 3.98 TB
    and refused every new session there). ``free_gb`` is free right now. A recorder
    is a writer that never pauses, and macOS frees purgeable space on its own
    schedule; nobody has measured a purge keeping pace with it, so
    ``floor_hard_stop_gb`` of free now stays the last line."""
    ...


@staticmethod
def disk_refusal(disk: dict, floor: str) -> str | None:
    available = disk.get("available_gb", disk["free_gb"])
    if available < disk[floor]:
        return f"only {available} GB available; the line is {disk[floor]} GB"
    hard = disk.get("floor_hard_stop_gb")
    if hard is not None and disk["free_gb"] < hard:
        return (f"only {disk['free_gb']} GB free right now (macOS has not freed its purgeable "
                f"space); the hard stop is {hard} GB")
    return None


def guard_disk(self) -> None:
    session = self.store.open_session()
    if not session:
        return
    refusal = self.disk_refusal(self.disk(), "floor_stop_gb")
    if refusal:
        log.warning("%s; stopping the session", refusal)
        ...  # stop cleanly: the open segment closes with its sidecar
Read both meanings of free on your own Mac (save as space.swift, run with: swift space.swift)·swift
import Foundation

let home = URL(fileURLWithPath: NSHomeDirectory())
let keys: Set<URLResourceKey> = [.volumeAvailableCapacityKey,
                                 .volumeAvailableCapacityForImportantUsageKey,
                                 .volumeTotalCapacityKey]
let values = try home.resourceValues(forKeys: keys)
let gb = { (bytes: Int64?) in String(format: "%.1f GB", Double(bytes ?? 0) / 1e9) }

print("free right now (statfs-like):   ", gb(values.volumeAvailableCapacity.map(Int64.init)))
print("available incl. purgeable:      ", gb(values.volumeAvailableCapacityForImportantUsage))
print("total:                          ", gb(values.volumeTotalCapacity.map(Int64.init)))

External links

Exercise

Run the Swift script on your Mac and compare its two numbers with df -h ~ and with what System Settings, General, Storage shows. Then write a tiny guard for a recorder of your own: a function that refuses to start below a start floor and stops below a stop floor (both on the available figure) and also below a hard floor on free-right-now. Test it with fake readings where available is large and free is tiny.
Hint
The interesting case is available = 900 GB, free = 12 GB: purge has not kept up. Your guard should stop on the hard floor and say which figure failed, the way Oriel's message names "free right now" and the purgeable space macOS has not freed.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign in — Please sign in to comment.

No comments yet — be the first.