Latent's one promise: nothing is called safe without evidence, and nothing is deleted without a way back — the Trash for files, a recorded re-fetch command for the two things the Trash cannot hold.
Every item Latent tracks wears one of three badges for what happens if you delete it:
Three letters, three meanings — and nothing else. There is no fourth state on screen. A cache the catalogue believes comes back but that nobody has proved for your folder is not "probably fine": it is I, amber, with a lock, until a measurement or the vendor's own documentation makes it R. The letter says what happens if the row goes; the colour repeats it — green means Latent may act on its own evidence, amber means the decision is yours, grey means nobody's.
Where a letter goes. Letters grade the things that go with a removal — a cache, a data folder, a package, an app's bundle listed under the app. The unit you choose to remove (an app row in Apps) carries no letter; its parts do. Anything that is only a state — in use, held by a dependency, waiting in quarantine — is written beside the letter in grey, never as a fourth letter.
"Safe to delete" is earned, never assumed. Latent uses four kinds of evidence, strongest first:
| Proof | What it means | Examples |
|---|---|---|
| Registry identity | At deletion time, the exact artifact still answers on its registry — digests, revisions, and filenames are compared, not just names. | Ollama models, Hugging Face repos, LM Studio models |
| Recorded provenance | The tool's own index recorded where every entry came from; bulk deletion passes only when everything traces to a public source that still serves it. | npm cache, Gradle modules |
| Vendor contract | The vendor ships its own purge command — the tool itself declares the cache disposable. Latent still uses the Trash, so you keep the undo. | pip (pip cache purge), uv (uv cache clean) |
| Vendor documentation | The vendor's own documentation or source states that the tool re-fetches or rebuilds this on next use — read on the vendor's page, never a blog or a guess. A manual reinstall does not count. | Core ML's compiled-model cache (Apple), pip's built wheels, Adobe's media cache, Android SDK packages Gradle downloads itself |
| Observed experiment | The folder is moved aside, the app relaunched, and Latent watches whether it comes back — then puts the original back byte for byte. Quarantine does the same over seven days for anything you unlock. Every observation becomes recorded evidence with its date. | Codex's component caches, LM Studio's bundled tools, Claude Desktop's agent runtime; anything you unlock |
Some folders are graded per piece rather than whole: Xcode's device symbols are R for a build a device still paired with this Mac runs and I for the rest; a Keras weights folder is R only while every file in it is a Keras Applications weight.
When a store mixes provable and unprovable content, Latent deletes only the proven part and tells you exactly what it kept and why. A custom fine-tune sitting next to downloaded models stays put, always.
Every I row carries a lock. Opening it is a deliberate act of consent: the row becomes selectable, the deletion is marked as forced in the record, and the confirm sheet flags it in red. Consent is scoped — a rescan clears every open lock. Latent never opens a lock for you, and connected AI assistants can't open one at all. P rows have no lock to open: Latent does not offer them at all.
Because they count everything that looks like a cache. Latent's number is smaller on purpose: every byte in it carries evidence — a registry answer, a recorded origin, a vendor contract, or an observed regeneration. The bytes without evidence are still shown; they're just yours to decide about, with the lock in your hand.
The Latent tab is the one-click action: the logo itself is the button, a progress ring wraps it while it runs, and the freed total lands when it's done. What it deletes passes two bars, not one: recovery must already be evidenced, and the item must be of the grade you wouldn't even notice losing — package caches whose vendor ships its own purge command, browser HTTP caches, thumbnail stores. Anything you'd have to re-earn (downloaded models, toolchains, plugins you installed) stays out of Optimize and waits in Space for a deliberate click. It is deliberately the same allowlist a connected AI assistant is limited to, so one click can never reach further than an assistant is allowed to.
Optimize never touches unverified rows, your own files, or protected paths; it never opens a lock for you; it never uninstalls apps or packages, unloads models, or empties the Trash. If some targets are held open by a running app, Optimize asks first — a checklist of the blocking apps, each quit politely (the app's own save prompts appear) only if you leave it checked; uncheck one and its files are simply skipped. Everything that moves goes to the Trash under a single undo manifest, and the guards re-run at the moment of deletion. The confirm sheet also lists what is being deliberately left alone, so the number you see is a floor, not a brag.
Space is one list of owners — Xcode, Homebrew, Hugging Face, Chrome and so on —
each with a bar coloured by what it holds: green for proven R, amber for I. Open an
owner and its rows come R first, then I, largest first within each. Every row shows
its letter, its path (home as ~, the full path on hover) and a
↗ that reveals it in Finder. The owner's head bar carries the same
☐ R chip as the top of the list — it selects that owner's proven rows, and
nothing else — and an Unlock N locked below… button that opens every lock
under it in one deliberate step. Below the owners come your own folders — Documents,
Downloads, Photos — listed, never preselected.
Caches are what Latent can prove things about; the space that's actually yours needs a different contract. Below the tool owners, Space lists six kinds of your own candidates under a divider that says so, and every one of them follows the same rule: listed, never preselected, never touched by Optimize or an assistant.
.dmg/.pkg
already past their purpose, in Downloads and on the Desktop) and abandoned
partial downloads.node_modules, Rust target,
build/dist, virtualenvs inside your project folders.
Claimed only next to their project marker (package.json,
Cargo.toml, …), and a virtualenv without a requirements file
stays locked — the package list would die with it. They carry R, but a
rebuild costs time, so these never enter Optimize.Apps has eight sources, each a tab: Mac apps, Homebrew, npm -g, Python (pip), Conda, Docker · Simulators, .pkg receipts and Leftovers. Every row that stands for something removable wears R, I or P like a Space row; the app row itself does not — it is the unit you choose, and its parts underneath are what get graded. The wheel on the left shows the apps by size, and the foot bar under it says what all of them hold: the bundles themselves, then what they leave behind by letter.
Click an app to see every file its bundle identifier owns — bundle, caches, preferences, containers, launch agents — R first, then I, largest first. The bundle itself is an I row (getting the app back is a reinstall, and that is yours). Folders Space already lists as stores are folded into one Space stores: row with the store names, one tick for all of them. Latent pre-checks only what it can attribute with certainty; two kinds of rows are never pre-checked:
Checking an app's own box selects everything underneath it — after one question if any of it contains your data, and your answer is remembered for the session. An uninstall is one manifest: one undo restores the whole thing. If macOS demands admin rights for the bundle, Latent hands the job to Finder — you'll see the standard authentication prompt. .pkg receipts lists installer leftovers in admin-owned places and deletes nothing there: it shows what remains, runs the vendor's uninstaller when the receipt names one, and otherwise reveals the files for you to remove in Finder. Leftovers lists data whose app is gone — all of it I, ticked by you.
Docker keeps images, containers, volumes and build cache inside one
opaque VM disk, so a file-level delete would be a factory reset — Latent
lists that disk as your data and never preselects it. What the Docker
pane offers instead is Docker's own removal of single items: an image, or
the build cache. That removal is irreversible — it does not go to
the Trash and there is no undo — so it has a confirm sheet that says so
in those words, and Latent writes the record before running the
command: what went, how big it was, and the exact
docker pull line that gets it back. Images a container is
using are refused, and volumes are never listed — a volume is somebody's
database.
iOS simulator runtimes work the same way and for the same reason: a
runtime is a signed Apple disk image, mounted live and tracked in Apple's
own registry, so only simctl can remove it. Same contract —
the sheet says it cannot be undone, the record keeps
xcodebuild -downloadPlatform iOS, a runtime with a booted
simulator is refused, and the one Xcode ships with is never offered. The rows
speak the same three letters as everywhere else: a runtime Apple can download
again is R, the one Apple marks not deletable is P, a registry-backed image is
R and a dangling layer is I. "In use" is a state written in grey beside the
letter, and the button waits until the simulator or container is gone.
Four of the sources manage what brew, npm -g,
pip --user and conda installed — the stuff that quietly
accumulates for years. A keg's symlinks and a wheel's scattered files make a Trash
move a lie, so removal runs the vendor's own uninstall, and the undo manifest records
the exact reinstall command instead. The same proof rule applies: before anything is
removed, Latent checks that the registry (formulae.brew.sh / npm / PyPI) still serves
that name and version — no answer, no removal. Each package row wears a letter: R when
the manager can reinstall it, R but held when another package depends on it (the
dependents are named, and clicking one takes you there), I when nobody could prove it
or you pinned it yourself, P when it is the manager's own body — pip and setuptools,
node and npm, the conda install, anything outside your home or owned by another
account. A Python user-site whose interpreter is gone (the classic
~/Library/Python/3.x leftover) is offered as one whole-folder Trash move
with a normal undo.
No purge buttons, no health scores — macOS already compresses and pages idle
memory, so "freeing RAM" mostly means paying to read it back. What's real is a
forgotten app holding gigabytes, so the App memory card lists your own apps by
actual footprint with a Quit button that is exactly Cmd-Q: the app raises its own
save prompt, and nothing is ever force-killed. System processes are never listed.
The tab also shows what unified memory is
doing and which model daemons (Ollama, LM Studio, llama.cpp, ComfyUI…) hold weights
resident. Every button runs the vendor's own command — ollama stop,
lms unload --all, ComfyUI's /free, llama.cpp's router unload —
so models simply reload on next use. Latent never force-kills anything. The wheel
shows your apps only; the system's share, swap and compression sit in the small rings
under it. The live charts here and on Overview start sampling the moment Latent
opens, so switching to the tab shows history, not a blank graph.
A few deletions are offered a safer route instead of the Trash — a 7-day quarantine — but only where the loss would be opaque or hard to reverse: protected items and unreadable "your data" stores. Everything else (unverified caches, your own listed files) goes straight to the Trash, where the Recovery row already states the risk. It is a recommendation, never imposed. During the window, restoring is one click from the Recovery tab. At expiry the item moves on to the Trash — and Latent records whether the owning tool recreated the path, building the evidence the claim never had. Prefer the direct route? Choose "Straight to Trash" in the confirm sheet; your call wins.
Everything that can come back lives in one sortable table, with the date it was removed:
Green rows — a recorded re-fetch command, or a verified store the owning tool rebuilds on its own — can also be emptied right from Recovery — one row or all of them at once, behind an explicit no-undo confirmation — because their way back survives the bytes. Rows that would be gone for good never get that button; Finder keeps that decision.
Rows are grouped by stage — quarantine, Trash, gone — newest first, with the date an item entered each stage in that stage's column; sort by name, source or size, filter by stage, search by name, source or command. Each row also wears the letter it was graded with when it was removed — R or I — because the way back depends on it. That last group is the point: the record outlives the Trash, so emptying the Trash costs you nothing you cannot deliberately get back. Commands only run in narrow, validated shapes; anything else is shown for you to copy.
Other items in the Trash. Whatever Finder put in the Trash — not Latent — is listed under its own heading, read-only, with a Put Back button that returns it to the spot Finder recorded when one exists. Latent never empties or discards those; it only lets you see them next to its own records.
Latent moves things to the Trash and never empties it out from under you. It touches nothing it did not put there, and it discards nothing that has no way back. Overview's Trash card shows what's inside, and one button opens it in Finder.
Two places do offer to finish the job. Recovery empties rows one at a time, or all the safe ones at once — where "safe" means the row still carries a recorded re-fetch command, or the verified evidence that the tool rebuilds it. And Optimize offers it immediately after a run, for that run only. Optimize removes nothing but proven-safe items, so every row it moved re-fetches or rebuilds itself; sending you to Finder to reclaim the space would be the app losing its nerve about a decision it had already stood behind. The button names the count and the size, and asks once.
Everything else in the Trash — including whatever you picked yourself in Space — stays for you to judge, in Recovery or in Finder.
File deletions go to the Trash, never straight to oblivion, and every run writes an undo manifest that restores exactly what moved. Simulator runtimes and Docker images are removed by their own tools, which have no Trash — those record the command that fetches them again before they go. Before a Space cleanup moves anything, four guards run: the owning tool isn't running, no running binary lives inside the target, no file inside is held open by any process, and nothing changed in the last 10 minutes. Guards re-check at the moment of deletion, not just at planning time. The Apps uninstaller runs its own pair — the app must not be running, and no file inside the target may be held open.
Latent ships an MCP server, so any MCP-capable assistant can read your disk picture and propose cleanups. The server is the app binary itself:
/Applications/Latent.app/Contents/MacOS/Latent --mode mcpLatent can wire itself into every assistant on this Mac. Paste this in Terminal:
/Applications/Latent.app/Contents/MacOS/Latent --mode mcp-installIt writes only where a client actually is: it runs the client's own mcp add where there is one (Claude Code, Codex, Gemini, Grok) and edits the JSON config where there is not (Cursor, Claude Desktop, VS Code, Windsurf). The JSON configs it edits are copied to .bak first — a client with a CLI of its own keeps its own config — and no config is invented for a client you do not have. A client that already knows Latent is left alone. Add --dry-run to see what it would do. Then start a new session in that client and ask it what is filling your disk.
Or wire one client yourself:
claude mcp add latent -- /Applications/Latent.app/Contents/MacOS/Latent --mode mcpcodex mcp add latent -- /Applications/Latent.app/Contents/MacOS/Latent --mode mcpgemini mcp add latent /Applications/Latent.app/Contents/MacOS/Latent --mode mcpgrok mcp add latent /Applications/Latent.app/Contents/MacOS/Latent -- --mode mcpThe -- matters: it hands --mode mcp to Latent instead of
letting Grok read it as its own flag. Grok can also check its side of the
wiring for you — grok mcp doctor reports whether the server
starts, whether the handshake completes, and how many tools it found.
Add this under the client's MCP servers section — ~/.cursor/mcp.json
for Cursor, claude_desktop_config.json for Claude Desktop,
.vscode/mcp.json for VS Code (VS Code nests it under
"servers" instead of "mcpServers"):
{
"mcpServers": {
"latent": {
"command": "/Applications/Latent.app/Contents/MacOS/Latent",
"args": ["--mode", "mcp"]
}
}
}The transport is plain stdio — no port, no daemon, nothing to keep running;
the client launches the server on demand. Both generations of the protocol are
served: the current one (2026-07-28, with server/discover and a
version on every request) and the older handshake, so any client from 2024 on
connects.
The server offers six tools, and you never call them by name — you ask in your own words and the assistant picks:
latent_overview — “where has my disk gone?”
Totals by owner and by tier.latent_items — “what could I clear over 500 MB?”
Individual items with their size, tier and evidence.latent_clean — “clear the pip and npm download
caches”. This is the tool that moves things to the Trash, and it
takes item keys the assistant got from latent_items —
never a folder you named in passing.latent_free — “now actually give me the space
back”. Empties from the Trash only what Latent put there, so the
number on the disk moves. This one cannot be undone, and the panel names
whatever will not come back before you approve it.latent_duplicates — “any duplicate model
weights?”latent_memory — “what is holding RAM right
now?” Reading only; quitting an app is never the
assistant's to do.Most of what fills a developer's disk is not unsafe to remove. It is only expensive to get back, and how much of that cost you will accept is a question nobody but you can answer. So every row the assistant reads carries a level, and it should show you the four totals before it proposes anything:
You say how far to go, the assistant passes that number along, and the plan it gets back names every row with its level, so you can check it kept to what you chose before you agree. It cannot raise the ceiling on its own: 3 is as far as the server goes, whatever it asks for.
An assistant sees paths, sizes, tiers and evidence labels — never file contents. But a path is information: if your assistant runs in the cloud, the names of folders under your home directory travel to it, the same as any file you paste into a chat. A local model keeps them on the machine. Latent itself sends nothing anywhere; it answers the client that launched it, over a pipe, and that client decides where the answer goes.
The assistant's powers are strictly smaller than yours: by default it can only touch verified R items, the same allowlist as one-click Optimize, and it goes further only when you say how far (see How far to go). One rule is absolute: an assistant cannot delete anything it has not shown you and you have not agreed to. Latent itself decides which items a request covers, hands the assistant that exact list, and then acts only on that list: once, within a few minutes, refusing any item that changed in between. No answer means no deletion. Assistants can never open a lock, never reach your own files, and never see file contents — only sizes, paths, and the evidence labels. Every item the assistant may not take says why in the list itself — unproven, costs real time to rebuild, your own files, protected — so it never has to guess, and the overview states both the figure it can move and the larger proven R total the app shows.
So the approval happens where you already are: in the conversation. Latent writes down exactly what it would take — item, size, level — and the assistant reads that list to you and waits. Say no, or say nothing, and nothing moves: the plan expires on its own after a few minutes, and the list has to be made again.
A removal an assistant proposed is a removal like any other: it goes to the Trash, it writes the same undo record, and it appears in the Recovery tab with the same one-click return. Nothing about the request coming from an assistant makes it harder to reverse.
Latent without a license is a full-strength viewer: scan as often as you like, explore the wheels and rings, watch growth over time, read the log. Nothing expires. Removing files is what a license unlocks — and recovery (undo, quarantine restore) always works either way, because the one thing this app will never do is hold your files hostage.
Menu bar → Latent → Enter License…, paste your key, done. One key covers more than one Mac (a beta key activates on up to 2). Scanning never needed the key in the first place; deletion unlocks the moment the key lands. No account, no email, nothing else to sign into. Under the hood the key is exchanged for a licence token signed by the server for this Mac; the app verifies the signature itself and refreshes the token at launch, so a copied settings file cannot unlock a second Mac, and a Mac that is offline keeps working for weeks before it asks to see the server again. Without a licence, every confirm sheet still shows what it would do and offers Get a licence… instead of the button.
A purchased key activates on up to 3 Macs. If you sell or retire one, open Latent → Enter License… on it and press Release — the slot goes straight back to your key and you can use it somewhere else. Nothing on that Mac is deleted, and you can activate it again any time.
If a purchase is refunded or charged back, the key stops working for deletion at the app's next launch. Recovery never stops working. Undo, quarantine restore and Put Back are outside the licence entirely — a refund can take the product away, but it can never leave your files stranded.
Latent is signed with a Developer ID and notarized by Apple, and the ticket is stapled to the disk image — macOS checks it when you first open the app, even offline. If the file had been altered anywhere between our build and your Mac, it would not open at all.
To see that for yourself, after moving the app to Applications:
spctl -a -vv /Applications/Latent.appaccepted
source=Notarized Developer ID
origin=Developer ID Application: FatTail Labs (BUS4S7XFQV)
The team identifier BUS4S7XFQV is ours and cannot be forged; that line is what a checksum on this page could not give you, because anyone who could replace the download could replace the checksum beside it.
Updates are held to the same test. Before it replaces anything, Latent verifies the downloaded bundle's signature, checks the team identifier, and asks Gatekeeper — any one of those failing ends the update and leaves the copy you have.
Latent is one app bundle and one folder. To remove it, quit Latent — the menu bar icon leaves with it — and drag Latent.app to the Trash. It installs no helper, no login item and no kernel extension, and it keeps no password.
Your records live in ~/.latent: undo records, the quarantine folder (items still in their observation window), the exclusion list and the activity log. Leave it if you might reinstall — those are the ways back. Delete it only when you are done for good: anything still in quarantine goes with it, so restore or empty those first from the Recovery tab.
Latent lists itself in Apps as P — it never removes itself from inside.
In the app: Help → Send Feedback…. It sends your message plus the app and macOS version; the activity log goes along only if you tick its box, with your home folder name stripped first. Nothing is ever sent in the background — only that button sends. Or write to fattaillabs.ceo@gmail.com — we read everything.