- Last updated: 2026-11-04 (atomwrite 0.1.38)
atomwriteis a local CLI- It has no telemetry, no analytics and no phone-home: nothing is collected, so there is no opt-in switch to turn on (an explicit opt-in would be required before any telemetry could be added)
- It never uploads the contents of your files
- The only network traffic the product starts itself is the one-time download of tree-sitter parsers and of the two OCR models, described in Network Access
- All file reads, writes, searches, backups and WAL sidecars execute on the machine that invokes the binary
- Configuration is CLI flags + XDG directories +
.atomwrite.tomlonly, with no productATOMWRITE_*runtime knobs (policy since v0.1.35, current line0.1.38) - The product code reads exactly one variable,
CLAUDE_CODE_SESSION_ID, and only to key the per-session media cache, and the source guard carries that single allowlisted line - The OS crates
sys-localeanddirectoriesreadLANG(andLANGUAGE,LC_ALL,LC_MESSAGESon Unix),HOMEandXDG_*for you, see Environment Reads By Dependencies doctordetects the host with local file probes only, and itslocalecheck follows the OS locale throughsys-locale, soLANGchanges the reported locale- Agent staging directories under
.atomwrite/scratch/are local workspace files, never uploaded atomwrite config setandconfig unsetwrite only the XDGconfig.toml(mode0600on Unix) or the workspace.atomwrite.toml, atomically, andconfig listandconfig getonly read them- The
watch,semantic-searchandsemantic-mergeverbs work on local filesystem data only
- Core read, write, edit, search, replace and every other verb need no network
- The AST features need the tree-sitter parsers, and the build ships none of them:
outline,queryand--syntax-checkdownload the parser bundle the first time a language is used and the local cache has no copy - The download comes from
github.com/xberg-io/tree-sitter-language-pack(release assets), through theureqHTTP client of thetree-sitter-language-pack1.22.1 crate (ureq,rustlsandringare in the default binary) - Measured on 2026-10-31 in the
v1.22.1manifest: about 22 MiB (23,031,807 bytes forlinux-x86_64), written to$XDG_CACHE_HOME/tree-sitter-language-pack/v1.22.1/(~/.cache/tree-sitter-language-pack/v1.22.1/by default), and the six parsers this machine already extracted take 3.9 MiB - The request carries no data from your files, the HTTP client adds its own standard request headers (not inspected for this document), and the host that serves the file sees the IP address of your machine, as with any download
- Later runs reuse the cache and make no request
- How to avoid the download: copy a warm cache directory from a connected machine to the same path, build without
ast(cargo install atomwrite --no-default-features --features core), or do not useoutline,queryand--syntax-check transformuses the grammars compiled intoast-grep-languageand does not use this download (measured in ADR-0057)read --ocrneeds two models, and the build ships neither of them: the detection modeltext-detection-ssfbcj81.rtenand the recognition modeltext-rec-checkpoint-s52qdbqt.rtenare fetched the first time OCR runs on a machine whose cache has no copy- The download comes from
huggingface.co/robertknight/ocrs(resolve/main), through theureqclient, with a 64 MiB cap and a 120 second timeout per file, and the files land in$XDG_CACHE_HOME/atomwrite/models/(~/.cache/atomwrite/models/by default) - The OCR request carries no data from your files, the host sees the IP address of your machine as with any download, and later runs reuse the cache and make no request
readwithout--ocr, and every other verb, starts no connection and never touches this path- How to avoid this download: pre-populate
$XDG_CACHE_HOME/atomwrite/models/with both files from a connected machine, or do not useread --ocr - The OCR download is not checksum-verified, unlike the tree-sitter bundle, so a proxy in front of the host can serve a different file and the product will load it
cargo install atomwritedownloads crates from crates.io, and that traffic is between your host and crates.io
- Third-party code reads the process environment in three places, listed in ADR-0057 so that no reader finds them by surprise
sys-localereadsLANGUAGE,LC_ALL,LC_MESSAGESandLANGon Unix to detect the OS language for the UIdirectoriesreadsHOMEandXDG_CONFIG_HOME,XDG_DATA_HOME,XDG_CACHE_HOME,XDG_STATE_HOMEon Linux to place the config, state and data pathstree-sitter-language-packreadsHOMEandXDG_CACHE_HOMEfor the parser cache, andureqreadsALL_PROXY,HTTPS_PROXY,HTTP_PROXYandNO_PROXY(with lowercase variants) when it downloads a parser- None of these values is sent anywhere by atomwrite
- Config:
config.tomlunder$XDG_CONFIG_HOME/atomwrite/(~/.config/atomwrite/on Linux), mode0600on Unix, written only byconfig setandconfig unset - Workspace config:
.atomwrite.tomlat the workspace root, written only byconfig set --scope workspace - Locale preference: the single-line file
localein the same directory, mode0600when the platform allows, written only bylocale --set - Logs: only when
log.fileistrue(defaultfalse), JSON lines under$XDG_STATE_HOME/atomwrite/logs/atomwrite.<date>.jsonl, rotated daily by default (log.rotation) and capped at 7 files - Log lines hold diagnostic events and can include the file paths and the locale of the run, so treat them as sensitive when the paths are
- WAL journals:
.atomwrite.journal.<target>.atomwrite.journal.jsonnext to the target file, removed after a committed write and bywal-heal - Backups:
<file>.bak.<timestamp>next to the file, created by the mutating verbs and removed after a successful write by default (deletecopies only with--backupor[defaults].backup = true,--keep-backupkeeps the copy after success, andprune-backupsremoves old ones, measured on 2026-11-04) - OCR models: the two
.rtenfiles under$XDG_CACHE_HOME/atomwrite/models/, written once byread --ocron first use, and never removed by the product - Session media cache: a
<blake3>marker under$XDG_CACHE_HOME/atomwrite/media-sessions/<session>/, keyed byCLAUDE_CODE_SESSION_ID, so a picture or PDF page is sent once per session and never removed by the product - The advisory lock is taken on the target file itself through
File::try_lock, which isflock(2)on Unix andLockFileExon Windows, so holding it writes nothing - A sidecar
.<target>.atomwrite.lockis created on a best-effort basis next to the target, and the write still proceeds on the inode lock when the directory does not allow creating it - The sidecar keeps the literal name until
.<target>.atomwrite.lockwould pass 255 bytes, and past that it becomes a short BLAKE3 digest in the same directory, so the name holds no path beyond the target name - On Unix the sidecar is unlinked when the last guard drops, a process killed by SIGKILL can leave one behind, and the next writer reuses and removes it; on Windows it is reused instead of unlinked
- Temporary files next to the target during a write
- Staging:
.atomwrite/scratch/in the workspace, created byscratch init - Shell completion scripts when you run
atomwrite completions --install - Crash reports: the
human-panichook writes areport-<uuid>.tomlfile in the OS temporary directory when the program panics, with the OS name, the crate version, the panic message and a backtrace, and it can include paths that appear in them - The crash report is a local file only and is never transmitted, you decide whether to attach it to an issue
- The parser cache described in Network Access
- No analytics, crash-reporting service or usage beacon is embedded in the binary
- NDJSON output can contain file paths and content excerpts that you (or an agent) chose to process, so treat stdout as sensitive if those paths hold secrets
- The detected or chosen locale is treated as potentially personal data
- Minimization: only a language tag (
enorpt-BR) is stored, as a single line in thelocalefile - Retention: the file stays on your disk until you remove it, and atomwrite never copies it elsewhere
- Deletion: run
atomwrite locale --clear, or delete the file at thepreference_paththatatomwrite localeprints - The OS locale is read once per run and is not sent off the host
- Because nothing is sent off the host, atomwrite does not collect personal data in the sense of the GDPR (EU) or the LGPD (Brazil), and this is a description of the design, not legal advice
- Upstream crates are governed by their own licenses (see
deny.toml/cargo deny) - If you enable tooling that calls external services (unrelated wrappers, agent hosts), those systems have separate privacy policies
- Maintainer: see
Cargo.tomlauthors/ repository listed in the package metadata