All posts
sovereign-aiself-hosted-aivendor-risklinux

An AI Coding App Indexed 627,652 Files On My Laptop. I Only Noticed Because It Got Hot.

OpenAI's Codex desktop app registered my home directory as a workspace and kept scanning a project folder deleted three months earlier. The interesting part isn't the bug. It's that I could find it at all.

Stéphane Lepain··6 min read

The fan told me before the software did.

I had installed OpenAI's new Codex desktop app on my Fedora laptop that evening. It is beta, I expected rough edges, and I wanted to see whether it was worth keeping. Two hours later the machine was at 74.8 °C with the window sitting idle, and GNOME was offering to force-quit it.

The obvious assumption was that a big Electron app is just heavy. That turned out to be wrong, and finding out why took most of the night.

What was actually running

I sampled /proc directly rather than trusting ps, which reports lifetime averages and hides bursts. Settled idle, the app used 30% of a CPU and 3.4 GB of RAM, peaking at 41.8%.

Inside the main process, one thread was doing nearly all of it. The thread was named git. In one 8 second sample it burned 99 of the process's 121 CPU ticks.

The reason was in the app's config file:

[projects."/home/me"]
trust_level = "trusted"

My home directory was registered as a workspace. It contains 627,652 files and is itself a git repository, with twelve more repos underneath it. The app was walking all of it.

Alongside that, the journal was filling up:

[git-init-watcher] Failed to watch workspace root for git init
    cwd=/home/me/git/LibreChat errorCode=ENOENT

Fifty five of those in thirty minutes, roughly one every five seconds. LibreChat is a project I moved to a server months ago. The directory has not existed on this laptop since May. The app was retrying a path that could never resolve, forever, with no backoff.

The part that made me stop and take notes

I removed the [projects] entry from the config. The thread kept running.

I launched the app from an empty directory with no project entries at all. The thread kept running.

I opened its SQLite database, found a table called local_thread_catalog with three rows pointing at the dead path, and deleted them. The thread stopped. Then I restarted the app and all three rows came back.

They came back because the catalogue is rebuilt on startup from session transcripts. Three JSONL files dated 1 May, each carrying "cwd":"/home/me/git/LibreChat" inside. The thread IDs in the database matched the filenames exactly. A second database, state_5.sqlite, held the same path in its own table.

So the state I was trying to remove was derived from conversation history I had forgotten I had. To get rid of it I had to delete three old conversations. There was no setting for it.

After that, plus forcing the app onto Wayland instead of the X11 backend it hardcodes:

CPURAMTemperature
as installed, settled30.0%3417 MB64.9 °C
as installed, peak41.8%3437 MB74.8 °C
after clearing stale session state2.0%2328 MB58.0 °C

I reported it upstream. There was already an open issue describing the same watcher failing on Windows with a different error code, so I added the Linux case rather than filing a duplicate.

Why I am writing this down

Not to dunk on OpenAI. Beta software has bugs, the retry loop is a genuine mistake anyone could ship, and I have written worse.

What stayed with me is the shape of the problem. An application I installed forty minutes earlier had quietly decided that my entire home directory was its working set, and was acting on a path from a conversation I had in May and had completely forgotten. Nothing about that was visible in the interface. There was no indicator, no permission prompt, no setting to inspect. The only symptom exposed to me as a user was heat.

Every client conversation I have about sovereign AI eventually arrives at the same question, usually phrased as "where does the data go." That is the right question but it is asked too late. The prior question is: can you see what the tool touches?

On my own laptop I could answer that. I read /proc for the thread breakdown, opened the app's SQLite files, grepped its session transcripts, and watched its network-facing package metadata. Twenty minutes of work with standard Linux tools, no vendor cooperation required, no support ticket.

That is the argument for keeping sensitive workloads on infrastructure you control, and it is not the argument people expect. It is not that local means nothing ever leaves. My own stack is hybrid: some routes stay on my hardware and those bytes genuinely never leave, others send minimized context to a frontier model under no-training terms, and those are logged. Nonzero and accounted for.

The argument is narrower and more useful. Local means observable. When something behaves oddly you can open it up, and the answer takes an evening instead of a support thread and a vendor NDA.

What this looks like when it is not your laptop

A hot laptop is an annoyance. The same pattern on a workstation holding client files is a different conversation.

Consider what actually happened here, translated: a third-party application enumerated an entire user profile without asking, retained references to a project it had seen months earlier, and persisted those references somewhere the user interface never exposed. If you are subject to Article 28 and someone asks you to describe your processing activities, "an app was indexing everything and I found out because the fan spun up" is not an answer.

The questions worth asking about any AI tool before it touches real work:

What does it consider its workspace, and did you tell it or did it decide? Where does it keep state, and can you read that store without vendor tooling? When you delete something in the interface, what actually gets deleted? Can you observe its behaviour from outside the application?

For the Codex app the answers were: it decided, yes but only because it uses SQLite, not what you would expect, and yes only because I run Linux.

Three of those four are properties of the software. The last one is a property of where you run it.

The uncomfortable bit

I found this because I was watching. I had a CPU sampler to hand, I knew how to read a thread table, and I happened to notice the temperature.

Most people would have felt a warm laptop, assumed AI tools are heavy, and carried on. The app worked. It answered questions. Nothing appeared broken.

That is what makes this worth writing about rather than just fixing. The failure was silent by default, and the only thing that surfaced it was physical.

If you are putting AI tooling in front of regulated work, the question is not whether your vendor is trustworthy. It is whether you would notice if something were wrong.


I run a sovereign AI consulting practice for regulated European teams. If you want to know what your current AI tooling actually touches, that is roughly what a Sovereignty Assessment is for.