Skip to main content
graph stores its runtime state as plain JSON and JSONL files under the data directory (~/.local/share/graph/ by default). Zero setup, human-readable, and safe under concurrent graph processes.

What’s stored

Layout

Everything is directly inspectable with cat and jq, and graph threads / graph shapes render the same data from the CLI. Shape filenames percent-encode characters outside [A-Za-z0-9_.-]; the authoritative tool name lives inside the file.

Concurrency

Multiple graph processes — parallel CI jobs, simultaneous one-shots — can share one data_dir:
  • Whole files (meta.json, shapes) are written to a temp file and atomically renamed into place, so readers never observe a partial write.
  • Message appends go through O_APPEND as a single write, serialized per thread by an advisory lock so metadata stays consistent with the log.
  • Shape writes are last-writer-wins. seen_count is advisory and may lose increments under contention; schema and example converge regardless.
The advisory locks assume a local filesystem — don’t point data_dir at NFS.

Backends

Storage resolves through a backend abstraction, selected by [storage].backend or GRAPH_STORAGE: The runtime depends only on a narrow storage trait (Store), so centralized backends (e.g. Postgres, with a shared shape cache every CI job inherits) can slot in without re-architecture.

Operational notes

  • Back up by copying data_dir — it’s just files.
  • Deleting a thread directory by hand is equivalent to graph threads rm.
  • Deleting shapes/ only costs learned planning hints; the cache rebuilds as tools run.