Files
Panama/user/agents/skills/diagnosing-bugs/TRACING.md
T
Gabriel Brown 89761a7da3 Keep the personal half of the desktop in one place, and ask before installing it
Agent instructions, skills, SSH host aliases and expansion triggers are worth
having identical on every machine one person owns, and belong in none of the
shared configuration. They live in user/ now, with a manifest saying where each
piece goes and a link-user stage that puts it there.

That stage does nothing unless the machine said yes. Somebody who clones Panama
to try the desktop keeps their own ~/.claude/CLAUDE.md exactly where it was;
the question names the destinations and defaults to no. Anything displaced goes
to config/old rather than being deleted.

~/.claude/CLAUDE.md and ~/.codex/AGENTS.md were byte-identical copies of one
file, which is the drift this exists to prevent.

Also adds the vitals toggles for the battery and Claude usage readouts, which
had preferences and no way to reach them.
2026-08-22 08:54:43 -04:00

2.2 KiB

Root cause tracing

Bugs often surface deep in a call chain: a file written to the wrong directory, a database opened with the wrong path, a query built from an empty string. The instinct is to fix where the error appears, which treats the symptom.

Trace backward through the call chain until you find the original trigger, then fix at the source.

Reach for this when the error happens far from the entry point, the stack trace is long, or it is unclear where an invalid value came from.

The process

1. Observe the symptom.

Error: git init failed in ~/project/packages/core

2. Find the immediate cause. What code directly produces this?

await execFileAsync("git", ["init"], { cwd: projectDir });

3. Ask what called it, and keep walking up:

WorktreeManager.createSessionWorktree(projectDir, sessionId)
  ← Session.initializeWorkspace()
  ← Session.create()
  ← the test at Project.create()

4. Follow the value, not just the frames. What was actually passed?

projectDir was "". An empty string as cwd resolves to process.cwd(), which was the source directory. The git init was never the bug.

5. Find where the bad value was born. That is the fix site.

Where to stop

Stop tracing at the first point where the value could have been validated but was not, and where fixing it prevents every downstream symptom rather than one of them. That is the source.

Where the chain leaves code you control (a library, a framework callback), you have hit a dead end. Fix at the closest boundary you own, and say explicitly that you stopped there and why.

Then consider a guard at the boundary

Fixing the source removes this bug. A cheap validation where the value enters the system removes the whole class of it, and turns a confusing deep failure into an obvious early one:

if (!projectDir) {
  throw new Error("projectDir is required and was empty");
}

Add the guard where it makes the failure legible, not at every layer. Validation repeated at five levels is its own maintenance problem, and the deletion test applies: if removing the check just moves the complexity, it was not earning its place.