Storage Layout¶
This document describes grite's storage organization on disk.
Overview¶
Grite stores data in two locations:
- Git refs: Source of truth (
refs/grite/*) - Local files: Materialized view and config (
.git/grite/)
Directory Structure¶
.git/
├── grite/
│ ├── config.toml # Repository configuration
│ └── actors/
│ └── <actor_id>/
│ ├── config.toml # Actor configuration
│ ├── sled/ # Materialized view database
│ ├── sled.lock # Filesystem lock
│ ├── daemon.lock # Daemon ownership marker
│ └── keys/
│ └── signing.key # Ed25519 private key (optional)
│
└── refs/
└── grite/
├── wal # Append-only event log
├── snapshots/
│ └── <timestamp> # Periodic snapshots
└── locks/
└── <resource_hash> # Distributed locks
Repository Files¶
.git/grite/config.toml¶
Repository-wide configuration.
default_actor = "64d15a2c383e2161772f9cea23e87222"
lock_policy = "warn"
[snapshot]
max_events = 10000
max_age_days = 7
| Field | Description |
|---|---|
default_actor |
Default actor ID for commands |
lock_policy |
Lock enforcement: off, warn, require |
snapshot.max_events |
Snapshot threshold (event count) |
snapshot.max_age_days |
Snapshot threshold (age) |
Actor Files¶
Each actor has an isolated directory under .git/grite/actors/<actor_id>/.
config.toml¶
Actor identity and settings.
actor_id = "64d15a2c383e2161772f9cea23e87222"
label = "work-laptop"
created_ts = 1700000000000
public_key = "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"
key_scheme = "ed25519"
| Field | Description |
|---|---|
actor_id |
Actor identifier (required) |
label |
Human-friendly name (optional) |
created_ts |
Creation timestamp (optional) |
public_key |
Ed25519 public key (optional) |
key_scheme |
Signature scheme (optional) |
sled/¶
The sled embedded database containing the materialized view.
Internal structure (managed by sled):
This is expendable and can be rebuilt from the WAL.
sled.lock¶
Filesystem lock (flock) for exclusive database access.
- CLI acquires this lock before opening sled
- Daemon holds it for its lifetime
- Prevents concurrent access corruption
daemon.lock¶
JSON file indicating daemon ownership.
{
"pid": 12345,
"started_ts": 1700000000000,
"repo_root": "/path/to/repo",
"actor_id": "64d15a2c383e2161772f9cea23e87222",
"host_id": "my-laptop",
"ipc_endpoint": "ipc:///tmp/grite-daemon.sock",
"lease_ms": 30000,
"last_heartbeat_ts": 1700000000000,
"expires_ts": 1700000030000
}
| Field | Description |
|---|---|
pid |
Daemon process ID |
started_ts |
Daemon start time |
repo_root |
Repository path |
actor_id |
Actor this daemon serves |
host_id |
Host identifier |
ipc_endpoint |
IPC socket path |
lease_ms |
Lease duration |
last_heartbeat_ts |
Last heartbeat time |
expires_ts |
Lease expiration time |
keys/signing.key¶
Ed25519 private key for event signing.
Warning
This file contains sensitive cryptographic material. Never share or commit it.
Git Refs¶
refs/grite/wal¶
The append-only event log. See Git WAL for format details.
refs/grite/snapshots/¶
Point-in-time snapshots for fast rebuilds.
- Timestamp is Unix milliseconds
- Contains consolidated events up to that point
- Multiple snapshots may exist
- Old snapshots removed by
grite snapshot gc
refs/grite/locks/¶
Distributed lease locks.
- Resource hash is SHA-256 of resource name
- Contains lock metadata (owner, expiry)
- Deleted on release or expiration
Materialized View Keys¶
The sled database uses these key patterns:
| Key Pattern | Value | Purpose |
|---|---|---|
event/<event_id> |
Archived Event | Event storage |
issue_state/<issue_id> |
IssueProjection | Current issue state |
issue_events/<issue_id>/<ts>/<event_id> |
Empty | Event index per issue |
label_index/<label>/<issue_id> |
Empty | Label-to-issue index |
dep_forward/<source_id>/<target_id>/<type> |
Empty | Dependency: source → target |
dep_reverse/<target_id>/<source_id>/<type> |
Empty | Dependency: target → source (reverse lookup) |
context_files/<path> |
FileContext (JSON) | File context with symbols |
context_symbols/<symbol_name>/<path> |
Empty | Symbol-to-file inverted index |
context_project/<key> |
ProjectContextEntry (JSON) | Project key/value metadata |
meta/last_rebuild_ts |
u64 | Last rebuild timestamp |
meta/wal_head |
String | Last processed WAL commit |
Storage Size¶
Git Refs¶
- WAL size grows with event count
- Each event is ~100-500 bytes CBOR
- Snapshots compress old events
Sled Database¶
- Size depends on issue count and event count
- Typical: 1-10 MB for thousands of issues
- Compacted on rebuild
Estimating Size¶
# Check sled database size
grite db stats --json | jq '.data.size_bytes'
# Check git ref sizes
git for-each-ref --format='%(refname) %(objectsize)' refs/grite/
Cleanup¶
Rebuild Database¶
Recompute materialized view from events:
Delete and Rebuild¶
For a fresh start:
Garbage Collection¶
Remove old snapshots:
Clean expired locks:
Multi-Actor Scenarios¶
Each actor has isolated storage:
.git/grite/actors/
├── actor-a/
│ ├── config.toml
│ ├── sled/
│ └── ...
├── actor-b/
│ ├── config.toml
│ ├── sled/
│ └── ...
└── actor-c/
└── ...
- Each has its own materialized view
- No conflicts between concurrent actors
- Shared WAL in git refs
Backup Considerations¶
What to Backup¶
- Always: Git refs (
refs/grite/*) - contains all state - Optional: Actor configs - can be recreated
- Skip: sled databases - can be rebuilt
Backup Commands¶
# Backup WAL (git refs are included in normal git backup)
git push backup refs/grite/*:refs/grite/*
# Export for external backup
grite export --format json
Security Considerations¶
Sensitive Files¶
| File | Sensitivity |
|---|---|
keys/signing.key |
High - private key |
daemon.lock |
Low - runtime info |
config.toml files |
Low - no secrets |
sled/ |
Medium - contains issue content |
Permissions¶
Next Steps¶
- Git WAL - WAL format details
- Configuration - Config options
- Operations - Maintenance tasks