Where smith keeps its files

The shell data dir, the core data dir, the desk dir, the work home, run copies and check caches on Linux and Windows, and what is safe to delete.

Smith has two data dirs, not one: the desktop shell's and the core's. Windows entries are not verified on a Windows host. "Not checked" means the source does not settle it.

01everything smith writes#

Windows cells are from code only. "Not checked" means the code does not settle it.

what Linux Windows safe to delete?
core data dir (config.Dir(); desk.json data_dir overrides) ~/.smith %LOCALAPPDATA%\smith (from code only) not checked
shell data dir (shellDataDir) $SMITH_DESK_HOME, else ~/.local/share/smith $SMITH_DESK_HOME, else %APPDATA%\smith (from code only) not checked
shell attachments/ and scratch/<conversation> (;) under the shell data dir (base dir not checked) same (from code only) not checked
<project>/.smith/desk same same (from code only) not checked
<project>/.smith/templates (TemplatesDir) same same (from code only) not checked
<project>/.smith/patch-runs/<id>/events.jsonl same same (from code only) not checked
<patch root>/.smith/context, see retained context same same (from code only) not checked; a launch needs its context
work home and clones ~/smith-work/<name> <user home>\smith-work\<name> (from code only) not checked
<checkout>.runs/<id> beside the checkout same (from code only) not checked
backups (default set in, not in internal/backup) ~/smith-backups <user home>\smith-backups (from code only) not checked
check caches ~/.cache/smith/checks %LocalAppData%\smith\checks (from code only) yes, made again as needed
conductor run dir smith-desk-<pid>-* $XDG_RUNTIME_DIR, else the temp dir the temp dir (from code only) not checked; that the sockets live there is not checked
core-dir cache/run-digests.json, ticket-accepts.json in the core data dir same (from code only) not checked
core-dir runs/, assets/, memory/, outbox/ in the core data dir same (from code only) not checked
<core data dir>/assets/folders/<id>, a new snapshot asset's working folder unless dir was given (;); see assets ~/.smith/assets/folders/<id> %LOCALAPPDATA%\smith\assets\folders\<id> (from code only) not checked
install/token, lib/roles, diagnostics/ not checked (base dir not traced to the core data dir) not checked not checked

02shell-data#

Chosen by shellDataDir (desktop/update-logic.js). Order: $SMITH_DESK_HOME if set; else on Windows Electron's userData; else on Linux $XDG_DATA_HOME/smith, falling back to ~/.local/share/smith.

Linux Windows (not verified on a Windows host)
Folder ~/.local/share/smith C:\Users\<you>\AppData\Roaming\smith

It holds logs/app.log (restarted past 5 MB, the previous one kept as app.log.1; desktop/main.js), projects.json, desktop.json, handoff.json and crashes/. Safe to delete: not checked.

03data#

A different folder from the shell's. deskDataDir (internal/cli/desk.go) uses desk.json data_dir if set, else config.Dir() (internal/config/config.go).

Linux Windows (not verified on a Windows host)
Folder ~/.smith %LOCALAPPDATA%\smith when LOCALAPPDATA is set, else ~/.smith

It holds the built-in tracker store tickets/tickets.db (ticketsDBPath, internal/cli/desk_backup.go) and the search model models/bge-small-en-v1.5 (DefaultLocalModelDir, internal/tickets/embed/local.go). Safe to delete: not checked. Deleting tickets.db removes the built-in tracker's tickets.

04projects#

<project>/.smith/desk (internal/cli/desk.go), the same on both systems. It holds:

Templates live in <project>/.smith, not in the desk dir. Safe to delete: not checked.

search is a block in desk.json that picks what embeds text for ticket search. It is global only (no per-project value) and live-reloaded.

A failed ollama probe leaves search keyword only. It never falls back to the built-in model by itself.

05tracker record#

The record is not a file in the desk dir. For the built-in tracker it sits in <core data dir>/tickets/tickets.db. For a remote tracker it lives on that tracker's host (internal/cli/desk.go).

06work home and work clones#

The work home is fixed at <user home>/smith-work (NewProjects, internal/cli/desk.go); no setting was found. A project's workspace defaults to <work home>/<name> (internal/desk/projects.go). Safe to delete: not checked.

07runs#

RunWorktreesDir (internal/service/run_worktree.go) gives <checkout>.runs. Each run gets a git worktree at <checkout>.runs/<first 12 characters of the launch id> (runWorktree). Only a git checkout of its own with a commit gets one (MakesRunWorktrees); any other folder is built in place, one run at a time.

Smith removes a run's worktree and branch by itself (worktreeLeftovers, sweepWorktrees, internal/desk/leftovers.go) when the core starts, after a sync, and after a landed run ends. It does so only when the run is not live, the tree is clean (untracked files count; a changed file byte-identical to main counts as clean), and either the branch is already in main, every commit on it is in main under another hash, or its ticket is done. It uses git worktree remove, then git branch -d. It adds --force to the tree only after checking again that every changed file is byte-identical to main, and -D to the branch only when every commit is in main under another hash or the ticket is done; a branch that is just an ancestor of main keeps -d. If git still refuses, the tree stays and isn't counted. It posts one line to the project's manager chat only when something was removed. It keeps, and never touches: live runs; a failed or stopped run's tree, which is what continue reuses; dirty trees; unlanded commits on a ticket that isn't done; and the asset-* mounts, trees no run record names, and any tree modified in the last hour. Removing a tree by hand is safe only when it is clean and its branch is in main: from the clone, run git worktree remove <path> then git branch -d <branch>. Never rm -rf alone; if you did, git worktree prune clears the dead entry.

08check caches#

<os.UserCacheDir>/smith/checks/{gocache,golangci-lint} (internal/service/patch_checks.go).

Linux Windows (not verified on a Windows host)
Folder ~/.cache/smith/checks %LocalAppData%\smith\checks

They persist across runs. They are caches, created again as needed (MkdirAll), so safe to delete. The check HOME is a fresh temp dir removed after the check.

09logs#

<shell data dir>/logs/app.log holds the shell's events and the core's output. The core's stderr reaches it as [core] … lines (desktop/main.js keep). It is restarted past 5 MB, the old one kept as app.log.1.

A failed go shows in the card thread and in app.log as smith: couldn't start <entry>: <error>. Search app.log for couldn't start. For a saved-context folder error, see retained context and troubleshooting.

10report outbox#

A problem report is written to <core data dir>/outbox/ before anything is posted: <stamp>-<rand>-<kind>.multipart is the body and <stamp>-<rand>-<kind>.json beside it says how the sends went. The sidecar holds kind, content_type, created_at, attempts, next_at, last_status (0 means the address gave no answer) and last_error. A report the intake refused for good (400 or 413) moves to outbox/failed/. Both are in the core data dir, not the shell data dir, and backups don't copy them.

A report that is waiting is tried again once at launch and then every hour. A pressed send posts its new report at once and ignores the backlog's next_at. A retry pass posts the due reports oldest first, stops at the first answer that isn't a 202 and posts at most 15, half of the intake's 30 reports an hour per install. After a failed try the next one waits:

Every send that isn't a 202 writes a line to app.log (search smith report:), and a retry pass that had something due writes one more:

The key is never in app.log or on a card. The card for a report that waits says why:

Card says It means
saved; the intake is rate-limiting this install (30 reports an hour), will send after HH:MM the intake answered 429; the report goes after that local time
saved; couldn't reach <address>: <error>, will retry at HH:MM no answer from the address this install was linked at; check that address and the network
saved; the intake answered <code> <words>, will retry at HH:MM any other answer but a 202
saved; the intake refused this install's key, re-link in settings › system a 401
saved; couldn't send it now (<error>), will retry within the hour the key file didn't read, or the send took longer than the card waits; no answer was recorded