Multi-User Sync
The deciduous database (.deciduous/deciduous.db) is local and gitignored. When teams need to share decisions, the events system provides append-only sync via git.
How It Works
Each user writes to their own event log file at .deciduous/sync/events/<username>.jsonl. These files are git-tracked and merge cleanly because each user writes to a separate file. When a teammate pulls, they rebuild their local database from all event logs.
The model:
- Every
add,link, andstatuscommand emits an event to your personal log - Events are identified by
change_id(UUID), not local integer IDs - Rebuilding replays all events from all users, deduplicating by
change_id - Checkpoints snapshot the current state so old events can be cleared
Initializing Sync
Set up the sync directory with deciduous events init.
Initialized sync directory at .deciduous/sync/
Created events directory at .deciduous/sync/events/
Author: alice
Next steps:
1. Add .deciduous/sync/ to git tracking
2. Team members pull and run 'deciduous events rebuild'
After initializing, events are automatically emitted whenever you create nodes, link edges, or update status.
Checking Status
View the current state of sync with deciduous events status.
Sync: Event-based sync status
Author: alice
Events directory: .deciduous/sync/events/
Event files:
alice.jsonl — 24 events
bob.jsonl — 18 events
Checkpoint: .deciduous/sync/checkpoint.json (42 nodes)
Local database: 42 nodes, 38 edges
Rebuilding from Events
After pulling changes from teammates, rebuild your local database.
Updating a1b2c3d..f4e5d6c
.deciduous/sync/events/bob.jsonl | 12 +++
$ deciduous events rebuild
Sync: Rebuilding database from events...
Loaded checkpoint: 42 nodes
Replaying events from alice.jsonl (24 events)
Replaying events from bob.jsonl (18 events)
Applied 12 new events (30 already present)
Database now has 54 nodes, 47 edges
You can preview what would change without modifying the database:
Sync: Dry run — no changes will be made
Would apply 12 new events from bob.jsonl
Would create 12 nodes, 9 edges
Checkpointing
As event logs grow, create a checkpoint to snapshot the current state. This speeds up future rebuilds.
Created checkpoint at .deciduous/sync/checkpoint.json (54 nodes, 47 edges)
$ deciduous events checkpoint --clear-events
Created checkpoint at .deciduous/sync/checkpoint.json (54 nodes, 47 edges)
Cleared event logs (events are now in the checkpoint)
Use --clear-events to remove old event log files after checkpointing. The checkpoint contains everything needed for a full rebuild.
Emitting Events Manually
If you created nodes before sync was initialized, emit them manually:
Emitted event for node 42 to alice.jsonl
PR Workflow for Sharing Decisions
The recommended team workflow:
.deciduous/sync/events/alice.jsonl | 8 +++
$ deciduous events rebuild
Replaying events from alice.jsonl (8 events)
Applied 8 new events
Database now has 50 nodes, 44 edges
Since each user writes to their own .jsonl file, git merges happen automatically with no conflicts.
The Dual-ID Model
Every node has two identifiers:
| ID | Scope | Purpose |
|---|---|---|
id (integer) | Local database | Primary key, different on each machine |
change_id (UUID) | Global | Stable across all databases |
Event logs and patches reference nodes by change_id, so they work correctly even when local id values differ between machines.
If your database predates the sync system, run deciduous migrate to add change_id columns.