The Failure Mode
.substrate/boards/*.json — your workflow — is committed to git and travels with every checkout.
.substrate/data.sqlite — your tasks, comments, and event log — is gitignored and does not.
A git worktree or fresh clone checks out the board files but not the database. libsql creates a fresh, empty database on open. An agent working in that checkout silently operates on its own empty board rather than the one in your main checkout.
The Warning Substrate Emits
Substrate detects this specific shape — a.substrate/ directory that has board files but whose data.sqlite did not exist and was just created — and warns loudly on startup:
This .substrate/ has boards but no task database — a fresh EMPTY one was just created at … If this is a git worktree or fresh clone, its task state is NOT shared with your main checkout.
A genuine first substrate init has no committed boards yet, so it does not trip the check.
What to Do
1
Stick to one checkout per project
The simplest answer, and the recommended approach for v0.7.0. Drive Substrate from the main checkout and let worktrees be for code only.
2
Or point the process at the main checkout
substrate mcp and substrate serve read the .substrate/ directory in their working directory. Run them with the working directory set to the main checkout and every agent shares one board, regardless of which worktree the code edits happen in.3
Or move state deliberately
If you need to migrate task state between checkouts, export from the source and import into the target:This is explicit, one-directional, and safe as long as you know which side is authoritative. See Backup and Restore for full details.
A shared-database pointer that lets several checkouts address one substrate is planned. It is not available in v0.7.0.