Skip to main content
  1. Posts/

Five wrong answers in one day. One nearly deleted 10 GB of coursework.

··1903 words·9 mins·
Nick Liu
Author
Nick Liu
Building infrastructure for Facebook Feed Ranking at Meta. Previously at Walmart, Twitter, AWS, and eBay. MS in Computer Science at Georgia Tech.
Table of Contents
Hardening My Dotfiles - This article is part of a series.
Part 6: This Article
`mdls kMDItemLastUsedDate` returned `(null)` for Microsoft Word. I read the null as "never opened" and put Office on a removal list: 10.1 GB, four apps. One last check saved me. My home directory held 150 Office documents, a conference presentation edited two weeks earlier, and a PowerPoint lock file, which only exists while the file is open. The proof that the null was misleading had been sitting in my own diagnostic report for an hour.

That was one of five. In a single day of hardening this machine, five different tools told me things that were not true. None of the answers looked like an error. Each one arrived as a clean, confident finding, and under each one a check had quietly failed or asked the wrong question. All five had the same shape underneath. Once I could name the shape, I stopped falling for it.

Case 1: null means “I don’t know”, not “no”
#

The plan was simple: free disk space by removing apps that had never been used. The evidence came from Spotlight metadata:

$ mdls -name kMDItemLastUsedDate -raw "/Applications/Google Chrome.app"
2026-08-15 20:18:18 +0000
$ mdls -name kMDItemLastUsedDate -raw "/Applications/Microsoft Word.app"
(null)

Chrome had a date. Word did not. The conclusion looked solid, because the same command told the two apps apart: Chrome is in use, Word is not.

It was not solid. kMDItemLastUsedDate is null when an app has never been opened, and when Spotlight’s metadata store has been reset. My store had been reset. I even knew that, because four hours earlier I had written this line into my own diagnostic report:

12:14:16.629  lsd  _CSStoreCreateWithURL failed with error ... "The file
              com.apple.LaunchServices-33554481-v2.csstore couldn't be opened
              because there is no such file."

The LaunchServices database was rebuilding at boot. In one section of my report, this was a strange log line. In another section, its consequences became hard evidence for deletion. I never connected the two.

What answers “is this app still needed” is user data:

$ find ~/Documents ~/Desktop ~/Downloads -iname '*.docx' -o -iname '*.pptx' | wc -l
     150
$ ls -t ~/Documents/**/*.pptx | head -3
cs6460-final-GT.pptx
~$cs6460-milestone2-GT.pptx      # lock file: exists only while the file is open
cs6460-milestone2-GT.pptx

Documents, lock files, container contents. Things a person made on purpose. An index field is different: the OS is free to throw it away and rebuild it, and while that happens the field tells you nothing.

Case 2: a query that never ran is not a query that found nothing
#

My environment audit reported “no git remotes configured” for a repository that had pushed four signed commits and opened a pull request earlier the same day.

The check behind that sentence was this:

$ cd ~ && git remote -v
fatal: not a git repository (or any of the parent directories): .git

These dotfiles are managed with yadm, and yadm keeps its bare repository in ~/.local/share/yadm/repo.git. $HOME is the work tree, not a git directory. Plain git in $HOME cannot answer the question at all. Then “cannot answer” got recorded as “the answer is none”.

$ yadm remote -v
origin  [email protected]:nickboy/dotfiles.git (fetch)
origin  [email protected]:nickboy/dotfiles.git (push)

The tool did not lie. fatal: not a git repository and empty output are two different results, but the code reading them treated both as “nothing there”.

Case 3: a 404 from the wrong endpoint
#

Same audit, same day: “branch protection could not be determined”. The check had asked the classic API:

$ gh api repos/nickboy/dotfiles/branches/master/protection
{"message":"Branch not protected","status":"404"}

That is a real 404, and the message reads like a finding. But GitHub has two protection mechanisms, and this repo uses the newer one:

$ gh api repos/nickboy/dotfiles/rulesets --jq '.[] | "\(.name) \(.enforcement)"'
Main Branch Protection active

A branch protected by a ruleset returns 404 from /branches/*/protection. Any tool that only checks the old endpoint will report every ruleset-protected branch as unprotected, in a sentence that sounds like it actually checked.

Asking the right endpoint paid off twice, because the true answer held a detail the false one would have hidden. The ruleset requires a pull request and four status checks, with no bypass actors. But required_approving_review_count is 0, and there is no signature requirement. “Protected” here means “must go through a PR and CI”. It does not mean “must be reviewed”. My signed commits are a habit; the server never checks them. Recording how strong a control is beats recording that one exists.

Case 4: the number was real, the units were not
#

My health check started with a headline number: WindowServer was eating 62.4% CPU, the biggest single CPU user on the machine. The number came from ps:

$ ps -Ao pid,%cpu,comm | grep WindowServer
  436  62.4  .../SkyLight.framework/Resources/WindowServer

On macOS, ps %cpu is a decaying average. It leans hard toward the last minute, not toward the life of the process. The cumulative figure is CPU time divided by elapsed time:

$ ps -o time=,etime= -p 436
   26:03.57    01:02:14      # 1563s CPU / 3734s elapsed = 41.9%

So 42%, not 62%. The next morning brought a bigger correction, after sixteen hours of normal use:

WindowServer   6.6%   (16.4 hours)
ghostty        3.3%   (16.4 hours)

Six point six. My original 62% came from an hour in which I was the load. I was running diagnostics nonstop, with Activity Monitor open and a backup copying files in the background. I had measured the observer and blamed the system. The whole “WindowServer is the problem” section of that report was an accident of timing.

Case 5: the benchmark that measured nothing happening
#

ll felt slow. The alias behind it is eza with a long list of flags, including --git. I benchmarked it and got a number that ended the discussion:

eza --all --long --git --icons ...   8.4 ms

Eight milliseconds. Nothing to fix. Except the same command, in the same directory, also reported this:

$ eza --all --long --git ... ~/Downloads | wc -lc
       0       0

Zero lines, zero bytes, exit 0, and 128 ms of system time. The benchmark had run inside the sandboxed shell my coding agent uses, and that sandbox blocks the metadata and git reads that --long --git needs. eza was making syscalls, and the sandbox refused every one of them. My benchmark timed the result with great precision: a program doing nothing, very fast.

I re-ran everything in a real terminal:

directorysizewith --gitwithout
nickboy.github.io47 entries, 263 tracked68.8 ms13.9 ms
claudedeck125 tracked49.0 ms20.8 ms
Downloads622 entries, not a repo49.6 ms39.8 ms

Inside a repo, --git costs 2x to 5x, and the cost follows the repository, not the directory being listed: eza resolves git status for every tracked file to fill one column. Listing a 47-entry folder inside a 263-file repo pays for all 263 files. My everyday alias paid that price in every project directory, which is exactly where I type it most.

The flag moved to an opt-in alias, llg. It also came out of ls, l, lt and tree completely, because the git column only renders in long view. For those four, the output is byte-identical with and without the flag. I verified that instead of assuming it:

$ [[ $(eza --git ... | md5) == $(eza ... | md5) ]] && echo "no-op"
no-op

Dead config, carried for months, costing a git query on every call.

The common shape
#

Five cases, one sentence:

A query that failed and a query that found nothing are different results.

Every case was a tool reporting an absence. In none of them had anyone checked whether the question ever reached the thing it was asking about.

what actually answered

the question I asked

is Word still used?

any git remotes?

is master protected?

how much CPU does
WindowServer use?

how fast is ll?

a Spotlight index
that had just been reset

$HOME, which is not
a git directory

the old protection API,
which cannot see rulesets

a decaying average of
the last minute

a sandbox that blocks
the real syscalls

what actually answered

the question I asked

is Word still used?

any git remotes?

is master protected?

how much CPU does
WindowServer use?

how fast is ll?

a Spotlight index
that had just been reset

$HOME, which is not
a git directory

the old protection API,
which cannot see rulesets

a decaying average of
the last minute

a sandbox that blocks
the real syscalls

“Absence of evidence is not evidence of absence” is an old phrase. The working version is more direct: evidence gathered by a broken method is not evidence at all, and a broken method usually exits 0.

The test that could not fail
#

The same day turned up a bug that had survived for a year because the test guarding it was written backwards.

Ghostty on macOS reads both ~/.config/ghostty/config and ~/Library/Application Support/com.mitchellh.ghostty/config. My bootstrap script had symlinked the second to the first, so the same file was parsed twice. For single-value keys the last value wins, so nothing looked wrong. But repeatable keys append:

$ ghostty +show-config | grep -c '^custom-shader = '
4                       # the file declares 2

Two extra full-screen shader passes on every frame, for a year. And the test suite stayed green the whole time, because it contained this:

GHOSTTY_LINK="$HOME/Library/Application Support/com.mitchellh.ghostty/config"
if [ -e "$GHOSTTY_LINK" ] || [ -L "$GHOSTTY_LINK" ]; then
    run_test "Ghostty config is symlink" "[ -L \"$GHOSTTY_LINK\" ]"
fi

Two problems in four lines. The assertion checks the opposite of the correct rule, because the symlink should not exist at all. And the assertion sits inside a guard, so when I deleted the symlink, the test did not fail. It silently stopped running. The first post in this series was a catalog of safety nets that had quietly died. This test is the sharpest example I have found since: it disappeared at the exact moment it finally had something to say.

The replacement tests the property instead of the mechanism:

run_test "Ghostty config is not parsed twice (custom-shader not duplicated)" \
    "[ '$LOADED_SHADERS' -eq '$CFG_SHADERS' ]"

Whatever causes a double parse next time (this symlink, a different symlink, an include directive, some future Ghostty change), the count stops matching and the test goes red. I put the symlink back once, on purpose, and watched the test fail before I trusted it.

Lessons
#

  • Null, empty, and 404 are answers about the query, not always about the world. Before treating one as a finding, confirm the query reached the right place.
  • Decide “is this app still needed” from data a person created. An index the OS can reset is not a record of anything.
  • Know which average your tool reports. ps %cpu on macOS leans toward the last minute; cumulative load is CPU time divided by elapsed time.
  • Measure where the work really happens. A sandbox that blocks the syscalls under test produces a fast, precise, meaningless number.
  • Never measure a system while you are the heaviest thing running on it.
  • Test the property, not the mechanism. The symlink was one way to get a double parse; the count catches all of them.

References
#

  • eza (--git cost measured on v0.23.5)
  • yadm (bare repo location: ~/.local/share/yadm/repo.git)
  • GitHub rulesets API (rulesets are invisible to the older /branches/*/protection endpoint)
  • Ghostty configuration (macOS reads both the XDG path and the Application Support path)
  • ps(1) on macOS (%cpu is documented as a decaying average)
  • The repo and its test suite: nickboy/dotfiles
Hardening My Dotfiles - This article is part of a series.
Part 6: This Article

Related

My commands vanished with exit 0. The culprit was a file named env.

··1441 words·7 mins
`env -u VAR command` did nothing. Exit code 0, no output, no error. A different command, same thing. A different variable, same thing. Any invocation that started with `env` just quietly evaporated. What finally made the problem visible was a `git init` that reported success while creating no `.git` directory at all. That was a year ago. The case closed last month, and the culprit was not uv, not some third-party installer, not anything exotic. It was this repo’s own bootstrap script. The thing that caught it was the regression test I had written for the original incident.

My dotfiles had a no-exceptions test gate. It had never run once.

··1331 words·7 mins
My dotfiles repo has a CLAUDE.md, and the CLAUDE.md has a rule in bold: every commit must pass the test suite, no exceptions. Within the first hour of an audit this July, I learned that this rule had been enforced exactly zero times since the day it was written. The hook file existed, its contents were correct, it even had its executable bit. It was just sitting at a path that yadm stopped reading a major version ago. No error message. No warning. To yadm, a hook in the wrong place and no hook at all are the same thing.

My diagrams rendered on refresh and vanished on click. The head never loaded.

··1010 words·5 mins
A reader clicking from my homepage to a post with a diagram got a block of raw mermaid source. The same reader pasting that post's URL directly got a rendered diagram. Same page, same build, same browser. The difference was the click, and the bug had been live on this site for months across every diagram, every math formula, and every chart, because I had only ever tested pages by loading them directly. 🧪 Tested with Blowfish 2.10x · htmx 2.0.10 Two features, both reasonable, one collision # This site has htmx’s hx-boost on the body: internal navigation swaps page content in place instead of doing full page loads, which keeps transitions smooth. Separately, the Blowfish theme is smart about heavy libraries: mermaid, KaTeX, and Chart.js bundles are only included on pages that use them, injected into the <head> of exactly those pages.