Team Sync via .engrams/
In v1.4, Engrams uses a filesystem-first architecture for team knowledge.
Decisions, patterns, and shared data are written as human-readable markdown files in
.engrams/ — committed to Git and shared automatically. The SQLite database
is a derived cache that can always be rebuilt.
.engrams/ directory replaces the older
engrams-export/ hook-based workflow. Team items are now written to disk
immediately when created — no export step needed.
How it works
When your AI logs a decision, pattern, or custom data item with visibility=team,
Engrams performs a guaranteed write-through:
- SQLite first — the item is written to the local database to acquire a numeric ID.
- Filesystem write — a markdown file is written to
.engrams/using the pattern{nnn}-{slug}.md. This write is guaranteed — if it fails, the entire operation fails. - Embedding (best-effort) — a vector embedding is created for semantic search. This step is non-blocking; if it fails, the item is still saved.
Directory structure
your-project/
├── .engrams/ # ← Committed to Git
│ ├── config_seed.json # Team/solo visibility default
│ ├── decisions/
│ │ ├── 001-use-postgresql.md
│ │ ├── 002-jwt-authentication.md
│ │ └── 003-react-query-for-server-state.md
│ ├── patterns/
│ │ ├── 001-repository-pattern.md
│ │ └── 002-error-handling-middleware.md
│ └── shared-data/
│ └── ProjectGlossary/
│ └── notification_channel.md
├── engrams/
│ └── context.db # ← In .gitignore (local cache)
└── ... .engrams/→ committed to Git — team decisions, patterns, shared dataengrams/context.db→ in .gitignore — local cache (progress, active context, individual notes)
Setting up team sync
Step 1 — Initialize as a team project
When you run engrams init, choose Team when prompted (or pass --team):
engrams init --tool roo --team
# Or interactively:
engrams init --tool roo
# → "Project classification:"
# → [1] Team project — decisions shared via .engrams/ for git sync
# → [2] Solo project — decisions stay in local database only
# → Choose [1/2] (default: 1 for team): 1
This creates the .engrams/ directory structure and writes a
config_seed.json that sets the default visibility to team.
Step 2 — Commit .engrams/ to Git
git add .engrams/
git commit -m "chore: initialize Engrams team sync" Step 3 — Teammates clone and init
When a teammate clones the repo, they already get the .engrams/ directory with
all team decisions. They just need to run:
pip install engrams-mcp
engrams init --tool roo --team
On first MCP tool call, Engrams reads the .engrams/ markdown files and populates
the local SQLite cache automatically via TeamContentIndexer.scan_and_sync().
The filesystem-first invariant
This is the core architectural guarantee of Engrams v1.4:
.engrams/ markdown files are the authoritative
source of truth for team items. SQLite is always a derived, rebuildable cache.
If the database is deleted, all team knowledge can be reconstructed from the filesystem.
This means:
- Human-readable — open any file in
.engrams/decisions/with a text editor - Git-mergeable — markdown files support standard 3-way merge (unlike binary SQLite)
- Auditable — use
git log .engrams/to see who changed what and when - Portable — copy the directory to any machine and Engrams rebuilds its index
How decisions are shared
The team sync workflow is fully automatic once .engrams/ is in your repo:
Her AI calls log_decision. Engrams writes to SQLite and creates
.engrams/decisions/004-use-redis-caching.md
git add .engrams/ && git commit && git push
git pull — Bob now has the new markdown file in .engrams/decisions/
On the next MCP tool call, TeamContentIndexer detects the new file and imports
it into Bob's local SQLite cache.
Content-addressed deduplication
Decisions are identified across machines by a content-addressed slug — a 12-character SHA-256 hash of the summary text. This means:
- The same decision created on two machines produces the same slug
- Import/sync recognizes identical decisions and skips them (no duplicates)
- Patterns are matched by name, custom data by
category + key
Rebuilding the database from .engrams/
If the SQLite database is lost or corrupted, Engrams automatically rebuilds it from the filesystem. You can also force a full re-index:
# Delete the local cache
rm engrams/context.db
# The MCP server rebuilds on next tool call automatically.
# Or trigger it manually:
engrams migrate Visibility levels
| Visibility | Stored in .engrams/? | Committed to Git? |
|---|---|---|
team | ✅ Yes — write-through guaranteed | ✅ Yes |
individual | ❌ No — SQLite only | ❌ No |
proposed | ❌ No — SQLite only until accepted | ❌ No |
workspace | ✅ Yes | ✅ Yes |
Recommended .gitignore
# Engrams local database (rebuildable from .engrams/)
engrams/
# Do NOT ignore .engrams/ — it contains team knowledge
# .engrams/ ← WRONG — never ignore this Legacy: engrams-export/ hook-based sync
Prior to v1.4, team sync used Git hooks that exported to engrams-export/ on commit
and imported on pull. This approach still works via engrams install-hooks and is
useful as a backup/snapshot mechanism, but the .engrams/ write-through is now the
primary team sync method.
See Batch & Export for details on the hook-based approach.
MCP tools
log_decision— withvisibility=team, writes through to.engrams/decisions/log_system_pattern— withvisibility=team, writes through to.engrams/patterns/log_custom_data— withvisibility=team, writes through to.engrams/shared-data/export_engrams_to_markdown— full export for backup (separate from write-through)import_markdown_to_engrams— import withmerge=Truefor safe additive sync