Where Heph Keeps Things
Heph writes to three places, and only the first is yours.
Your project
Heph writes into the project directory only what you accept in review, and one
config edit: A on a permission prompt appends to .heph/config.toml. It never
runs git commit, git add, or anything else against your repository; it reads
your repository's refs and your working tree, and nothing more.
Your config
~/.config/heph/config.toml (or under $XDG_CONFIG_HOME), written once on the
first run if it did not exist, and never rewritten.
The data directory
Everything else is under ~/.local/share/heph/ (or $XDG_DATA_HOME/heph, or
--data-root DIR, or $HEPH_DATA_ROOT), keyed by a hash of the project's
canonical path so two checkouts of the same repository in different places are
two projects.
| Path | Contents |
|---|---|
db/<hash>.sqlite | The project's conversations: every turn, message, tool call with its parameters and result, API call with its token counts and cost, and the conversation names and drafts. SQLite in WAL mode; -shm and -wal files sit beside it. |
git/<hash>/ | The shadow repository, a bare git repository heph owns. Snapshots of your tree under refs/heph/user; every turn's per-call commits under refs/heph/turns/<turn>/; a mirror of your repository's branches and tags fetched at each turn; pending applies under refs/heph/pending/ until they finish. |
wt/<hash>/<conversation-id>/ | One worktree per conversation, checked out from the shadow repository. A .heph-ref file inside names the conversation. This is where the model's tools run and where an external review tool opens. |
target/<hash>/ | The shared CARGO_TARGET_DIR for the project's worktrees, when [worktree] shared_target is on. |
log/heph.log | The interactive session's log, appended to by every session on every project. |
Pending adoption is recorded in adoptions/<conversation-id>.json under the
effective data root. It contains the frozen source/destination and private-state
manifest and blocks ordinary resume until transfer finishes. Retry
heph --adopt FULL-UUID from the same destination; do not delete the journal or
either project's storage while adoption is pending. Source shared history,
request audits, ignored files, and private resources remain after transfer.
The process's control socket is elsewhere: $XDG_RUNTIME_DIR/heph/<pid>.sock,
removed on exit.
Database upgrades
Heph applies pending schema migrations when it opens a project database. Each migration is tracked separately, so switching to a merged branch build applies older pending migrations even if newer ones have already run. A failed upgrade rolls back its pending batch rather than recording a partial success.
Opening with the timestamp-ledger runner converts older databases. After that, old sequential-version builds refuse the database. A newer build also refuses opening if it lacks any migration already applied by another branch. Use a merged build containing all applied migrations; do not delete the database or edit its migration records to work around the refusal. There is no automatic schema downgrade.
Deleting
Deleting ~/.local/share/heph/ forgets every conversation on every project and
every worktree; your repositories and files are untouched. Deleting one
project's four entries (the hash is the same across db, git, wt, and
target) forgets that project. Deleting only target/<hash>/ costs a rebuild
and nothing else.
Do not delete a project's git/<hash>/ while an apply might be in flight: the
journal that finishes an interrupted apply lives there.
Looking inside
The shadow repository is ordinary git.
git -C ~/.local/share/heph/git/<hash> log refs/heph/user shows the snapshots
of your tree; git ... log refs/heph/turns/<turn>/chain shows a turn's per-call
commits with the model's rationale as each message. The database is ordinary
SQLite; sqlite3 ~/.local/share/heph/db/<hash>.sqlite '.tables' lists turn,
message, tool_call, api_call, ref, process, tool_catalog, and the
full-text index over messages.
Logs
Heph logs at WARN by default; -v raises it, and RUST_LOG overrides it.
Subcommands such as heph exec log to stderr. The interactive session owns the
terminal, so it appends its log to log/heph.log under the data directory
instead, and shows each warning and error in the conversation as a -- warning:
or -- error: line, except those it already reports another way, such as a
failed turn.