Physical Files And Volumes
The easiest mental model is:
app.db path repository path and worktree entryGraft Volume mutable page store used by the Graft VFSsnapshot immutable point-in-time view of a Volumephysical .db file optional materialized copy for external SQLite toolsapp.db is the name users work with, but the Graft VFS reads and writes pages through a Volume. A SQLite transaction advances that Volume to a new snapshot. The snapshot becomes part of repository history only after graft add and graft commit.
Is app.db A Snapshot?
Section titled “Is app.db A Snapshot?”Not exactly.
When you run:
graft sql "INSERT INTO users(name) VALUES ('Alice');"the current app.db worktree path points at a writable Graft Volume. That Volume now has a newer snapshot, but no repository commit has been created yet.
When you run:
graft add app.dbgraft commit -m "add alice"the repository commit records a sqlite-snapshot-v1 object for app.db. That object describes how to reconstruct the database snapshot from Graft page/log storage.
Why There May Be No app.db File
Section titled “Why There May Be No app.db File”With the Graft VFS, the operating-system file does not have to exist. The path is still meaningful because SQLite opens:
file:/project/app.db?vfs=graftGraft maps that path to the repo-local store under .graft/. In a fresh repository, you can have committed data for app.db even if ls app.db shows no ordinary file.
Exporting For SQLite Tools
Section titled “Exporting For SQLite Tools”Use graft export when you want a normal SQLite database file for tools such as sqlite3, DB Browser for SQLite, Datasette, or application debuggers.
Export the current worktree Volume:
graft export --output app.inspect.db app.dbsqlite3 app.inspect.dbExport a committed revision:
graft export --source HEAD --output app.head.db app.dbgraft export --source HEAD~1 --output app.previous.db app.dbThe exported file is a regular SQLite database. It is not connected to the Graft Volume after export.
Round-Tripping External Edits
Section titled “Round-Tripping External Edits”If you edit the exported file with an ordinary SQLite tool, Graft will not automatically see those edits.
To import an edited physical file back into the repository, stage it as a physical SQLite file:
sqlite3 app.inspect.db "INSERT INTO users(name) VALUES ('Bob');"cp app.inspect.db app.dbgraft --db .graft-control.db add app.dbgraft commit -m "import sqlite tool edits"The --db .graft-control.db part matters when app.db is a physical file you want to import. It lets the CLI enter the repository through a separate control database, so app.db is treated as a physical worktree file rather than as the current Graft VFS Volume.
Practical Rules
Section titled “Practical Rules”- Use
graft sqlor avfs=graftSQLite connection for normal Graft-managed writes. - Use
graft exportfor read-only inspection in standard SQLite tools. - Treat exported files inside the project directory as untracked files unless you intentionally import them.
- Commit exported files only if they are fixtures or artifacts you really want in the repository.