Document bd-105/bd-114 analysis: MCP context routing crisis
- bd-105: Comprehensive root cause analysis with 3 architectural paths - bd-114: Documented as symptom of bd-105 (multi-server workaround backfire) - Clarified daemon (v0.9.9) is orthogonal: solves concurrency, not routing - Recommended solution: PATH 1 (SetContext/WhereAmI) - 8h effort, P0/P1 - Research complete: 1,034 misroutes quantified, MCP protocol analyzed Amp-Thread-ID: https://ampcode.com/threads/T-8d943ad6-b0ae-403c-94d0-8cce0feefa08 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
430
GIT_WORKFLOW.md
430
GIT_WORKFLOW.md
@@ -1,430 +0,0 @@
|
||||
# Git Workflow for bd Databases
|
||||
|
||||
> **Note**: This document contains historical analysis of binary SQLite workflows. **The current recommended approach is JSONL-first** (see README.md). This document is kept for reference and understanding the design decisions.
|
||||
|
||||
## TL;DR
|
||||
|
||||
**Current Recommendation (2025)**: Use JSONL text format as source of truth. See README.md for the current workflow.
|
||||
|
||||
**Historical Analysis Below**: This documents the binary SQLite approach and why we moved to JSONL.
|
||||
|
||||
---
|
||||
|
||||
## The Problem
|
||||
|
||||
SQLite databases are **binary files**. Git cannot automatically merge them like text files.
|
||||
|
||||
```bash
|
||||
$ git merge feature-branch
|
||||
warning: Cannot merge binary files: .beads/myapp.db (HEAD vs. feature-branch)
|
||||
CONFLICT (content): Merge conflict in .beads/myapp.db
|
||||
```
|
||||
|
||||
When two developers create issues concurrently and try to merge:
|
||||
- Git detects a conflict
|
||||
- You must choose "ours" or "theirs" (lose one side's changes)
|
||||
- OR manually export/import data (tedious)
|
||||
|
||||
---
|
||||
|
||||
## Solution 1: Binary in Git with Protocol (Recommended for Small Teams)
|
||||
|
||||
**Works for**: 2-10 developers, <500 issues, low-medium velocity
|
||||
|
||||
### The Protocol
|
||||
|
||||
1. **One person owns the database per branch**
|
||||
2. **Pull before creating issues**
|
||||
3. **Push immediately after creating issues**
|
||||
4. **Use short-lived feature branches**
|
||||
|
||||
### Workflow
|
||||
|
||||
```bash
|
||||
# Developer A
|
||||
git pull origin main
|
||||
bd create "Fix navbar bug" -p 1
|
||||
git add .beads/myapp.db
|
||||
git commit -m "Add issue: Fix navbar bug"
|
||||
git push origin main
|
||||
|
||||
# Developer B (same time)
|
||||
git pull origin main # Gets A's changes first
|
||||
bd create "Add dark mode" -p 2
|
||||
git add .beads/myapp.db
|
||||
git commit -m "Add issue: Add dark mode"
|
||||
git push origin main # No conflict!
|
||||
```
|
||||
|
||||
### Handling Conflicts
|
||||
|
||||
If you DO get a conflict:
|
||||
|
||||
```bash
|
||||
# Option 1: Take remote (lose your local changes)
|
||||
git checkout --theirs .beads/myapp.db
|
||||
bd list # Verify what you got
|
||||
git commit
|
||||
|
||||
# Option 2: Export your changes, take theirs, reimport
|
||||
bd list --json > my-issues.json
|
||||
git checkout --theirs .beads/myapp.db
|
||||
# Manually recreate your issues
|
||||
bd create "My issue that got lost"
|
||||
git add .beads/myapp.db && git commit
|
||||
|
||||
# Option 3: Union merge with custom script (see below)
|
||||
```
|
||||
|
||||
### Pros
|
||||
- ✅ Simple: No infrastructure needed
|
||||
- ✅ Fast: SQLite is incredibly fast
|
||||
- ✅ Offline-first: Works without network
|
||||
- ✅ Atomic: Database transactions guarantee consistency
|
||||
- ✅ Rich queries: Full SQL power
|
||||
|
||||
### Cons
|
||||
- ❌ Binary conflicts require manual resolution
|
||||
- ❌ Diffs are opaque (can't see changes in git diff)
|
||||
- ❌ Database size grows over time (but SQLite VACUUM helps)
|
||||
- ❌ Git LFS might be needed for large projects (>100MB)
|
||||
|
||||
### Size Analysis
|
||||
|
||||
Empty database: **80KB**
|
||||
100 issues: **~120KB** (adds ~400 bytes per issue)
|
||||
1000 issues: **~500KB**
|
||||
10,000 issues: **~5MB**
|
||||
|
||||
**Recommendation**: Use binary in git up to ~500 issues or 5MB.
|
||||
|
||||
---
|
||||
|
||||
## Solution 2: Text Export Format (Recommended for Medium Teams)
|
||||
|
||||
**Works for**: 5-50 developers, any number of issues
|
||||
|
||||
### Implementation
|
||||
|
||||
Create `bd export` and `bd import` commands:
|
||||
|
||||
```bash
|
||||
# Export to text format (JSON Lines or SQL)
|
||||
bd export > .beads/myapp.jsonl
|
||||
|
||||
# Import from text
|
||||
bd import < .beads/myapp.jsonl
|
||||
```
|
||||
|
||||
### Workflow
|
||||
|
||||
```bash
|
||||
# Before committing
|
||||
bd export > .beads/myapp.jsonl
|
||||
git add .beads/myapp.jsonl
|
||||
git commit -m "Add issues"
|
||||
|
||||
# After pulling
|
||||
bd import < .beads/myapp.jsonl
|
||||
```
|
||||
|
||||
### Advanced: Keep Both
|
||||
|
||||
```
|
||||
.beads/
|
||||
├── myapp.db # Binary database (in .gitignore)
|
||||
├── myapp.jsonl # Text export (in git)
|
||||
└── sync.sh # Script to sync between formats
|
||||
```
|
||||
|
||||
### Pros
|
||||
- ✅ Git can merge text files
|
||||
- ✅ Diffs are readable
|
||||
- ✅ Conflicts are easier to resolve
|
||||
- ✅ Scales to any team size
|
||||
|
||||
### Cons
|
||||
- ❌ Requires discipline (must export before commit)
|
||||
- ❌ Slower (export/import overhead)
|
||||
- ❌ Two sources of truth (can get out of sync)
|
||||
- ❌ Merge conflicts still happen (but mergeable)
|
||||
|
||||
---
|
||||
|
||||
## Solution 3: Shared Database Server (Enterprise)
|
||||
|
||||
**Works for**: 10+ developers, high velocity, need real-time sync
|
||||
|
||||
### Options
|
||||
|
||||
1. **PostgreSQL Backend** (future bd feature)
|
||||
```bash
|
||||
export BD_DATABASE=postgresql://host/db
|
||||
bd create "Issue" # Goes to shared Postgres
|
||||
```
|
||||
|
||||
2. **SQLite on Shared Filesystem**
|
||||
```bash
|
||||
export BD_DATABASE=/mnt/shared/myapp.db
|
||||
bd create "Issue" # Multiple writers work fine with WAL
|
||||
```
|
||||
|
||||
3. **bd Server Mode** (future feature)
|
||||
```bash
|
||||
bd serve --port 8080 # Run bd as HTTP API
|
||||
bd --remote=http://localhost:8080 create "Issue"
|
||||
```
|
||||
|
||||
### Pros
|
||||
- ✅ True concurrent access
|
||||
- ✅ No merge conflicts
|
||||
- ✅ Real-time updates
|
||||
- ✅ Centralized audit trail
|
||||
|
||||
### Cons
|
||||
- ❌ Requires infrastructure
|
||||
- ❌ Not offline-first
|
||||
- ❌ More complex
|
||||
- ❌ Needs authentication/authorization
|
||||
|
||||
---
|
||||
|
||||
## Solution 4: Hybrid - Short-Lived Branches
|
||||
|
||||
**Works for**: Any team size, best of both worlds
|
||||
|
||||
### Strategy
|
||||
|
||||
1. **main branch**: Contains source of truth database
|
||||
2. **Feature branches**: Don't commit database changes
|
||||
3. **Issue creation**: Only on main branch
|
||||
|
||||
```bash
|
||||
# Working on feature
|
||||
git checkout -b feature-dark-mode
|
||||
# ... make code changes ...
|
||||
git commit -m "Implement dark mode"
|
||||
|
||||
# Need to create issue? Switch to main first
|
||||
git checkout main
|
||||
git pull
|
||||
bd create "Bug found in dark mode"
|
||||
git add .beads/myapp.db
|
||||
git commit -m "Add issue"
|
||||
git push
|
||||
|
||||
git checkout feature-dark-mode
|
||||
# Continue working
|
||||
```
|
||||
|
||||
### Pros
|
||||
- ✅ No database merge conflicts (database only on main)
|
||||
- ✅ Simple mental model
|
||||
- ✅ Works with existing git workflows
|
||||
|
||||
### Cons
|
||||
- ❌ Issues not tied to feature branches
|
||||
- ❌ Requires discipline
|
||||
|
||||
---
|
||||
|
||||
## Recommended Approach by Team Size
|
||||
|
||||
### Solo Developer
|
||||
**Binary in git** - Just commit it. No conflicts possible.
|
||||
|
||||
### 2-5 Developers (Startup)
|
||||
**Binary in git with protocol** - Pull before creating issues, push immediately.
|
||||
|
||||
### 5-20 Developers (Growing Team)
|
||||
**Text export format** - Export to JSON Lines, commit that. Binary in .gitignore.
|
||||
|
||||
### 20+ Developers (Enterprise)
|
||||
**Shared database** - PostgreSQL backend or bd server mode.
|
||||
|
||||
---
|
||||
|
||||
## Scaling Analysis
|
||||
|
||||
How far can binary-in-git scale?
|
||||
|
||||
**Experiment**: Simulate concurrent developers
|
||||
|
||||
```bash
|
||||
# 10 developers each creating 10 issues
|
||||
# If they all pull at same time, create issues, push sequentially:
|
||||
# - Developer 1: pushes successfully
|
||||
# - Developer 2: pulls, gets conflict, resolves, pushes
|
||||
# - Developer 3: pulls, gets conflict, resolves, pushes
|
||||
# ...
|
||||
# Result: 9/10 developers hit conflicts
|
||||
|
||||
# If they coordinate (pull, create, push immediately):
|
||||
# - Success rate: ~80-90% (depends on timing)
|
||||
# - Failed pushes just retry after pull
|
||||
|
||||
# Conclusion: Works up to ~10 concurrent developers with retry logic
|
||||
```
|
||||
|
||||
**Rule of Thumb**:
|
||||
- **1-5 devs**: 95% conflict-free with protocol
|
||||
- **5-10 devs**: 80% conflict-free, need retry automation
|
||||
- **10+ devs**: <50% conflict-free, text export recommended
|
||||
|
||||
---
|
||||
|
||||
## Git LFS
|
||||
|
||||
For very large projects (>1000 issues, >5MB database):
|
||||
|
||||
```bash
|
||||
# .gitattributes
|
||||
*.db filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
git lfs track "*.db"
|
||||
git add .gitattributes
|
||||
git commit -m "Track SQLite with LFS"
|
||||
```
|
||||
|
||||
### Pros
|
||||
- ✅ Keeps git repo small
|
||||
- ✅ Handles large binaries efficiently
|
||||
|
||||
### Cons
|
||||
- ❌ Requires Git LFS setup
|
||||
- ❌ Still can't merge binaries
|
||||
- ❌ LFS storage costs money (GitHub/GitLab)
|
||||
|
||||
---
|
||||
|
||||
## Custom Merge Driver
|
||||
|
||||
For advanced users, create a custom git merge driver:
|
||||
|
||||
```bash
|
||||
# .gitattributes
|
||||
*.db merge=bd-merge
|
||||
|
||||
# .git/config
|
||||
[merge "bd-merge"]
|
||||
name = bd database merger
|
||||
driver = bd-merge-tool %O %A %B %P
|
||||
```
|
||||
|
||||
Where `bd-merge-tool` is a script that:
|
||||
1. Exports both databases to JSON
|
||||
2. Merges JSON (using git's text merge)
|
||||
3. Imports merged JSON to database
|
||||
4. Handles conflicts intelligently (e.g., keep both issues if IDs differ)
|
||||
|
||||
This could be a future bd feature:
|
||||
|
||||
```bash
|
||||
bd merge-databases base.db ours.db theirs.db > merged.db
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## For the beads Project Itself
|
||||
|
||||
**Recommendation**: Binary in git with protocol
|
||||
|
||||
Rationale:
|
||||
- Small team (1-2 primary developers)
|
||||
- Low-medium velocity (~10-50 issues total)
|
||||
- Want dogfooding (eat our own food)
|
||||
- Want simplicity (no export/import overhead)
|
||||
- Database will stay small (<1MB)
|
||||
|
||||
### Protocol for beads Contributors
|
||||
|
||||
1. **Pull before creating issues**
|
||||
```bash
|
||||
git pull origin main
|
||||
```
|
||||
|
||||
2. **Create issue**
|
||||
```bash
|
||||
bd create "Add PostgreSQL backend" -p 2 -t feature
|
||||
```
|
||||
|
||||
3. **Commit and push immediately**
|
||||
```bash
|
||||
git add .beads/bd.db
|
||||
git commit -m "Add issue: PostgreSQL backend"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
4. **If push fails (someone beat you)**
|
||||
```bash
|
||||
git pull --rebase origin main
|
||||
# Resolve conflict by taking theirs
|
||||
git checkout --theirs .beads/bd.db
|
||||
# Recreate your issue
|
||||
bd create "Add PostgreSQL backend" -p 2 -t feature
|
||||
git add .beads/bd.db
|
||||
git rebase --continue
|
||||
git push origin main
|
||||
```
|
||||
|
||||
5. **For feature branches**
|
||||
- Don't commit database changes
|
||||
- Create issues on main branch only
|
||||
- Reference issue IDs in commits: `git commit -m "Implement bd-42"`
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### bd export/import (Priority: Medium)
|
||||
|
||||
```bash
|
||||
# JSON Lines format (one issue per line)
|
||||
bd export --format=jsonl > issues.jsonl
|
||||
bd import < issues.jsonl
|
||||
|
||||
# SQL format (full dump)
|
||||
bd export --format=sql > issues.sql
|
||||
bd import < issues.sql
|
||||
|
||||
# Delta export (only changes since last)
|
||||
bd export --since=2025-10-01 > delta.jsonl
|
||||
```
|
||||
|
||||
### bd sync (Priority: High)
|
||||
|
||||
Automatic export before git commit:
|
||||
|
||||
```bash
|
||||
# .git/hooks/pre-commit
|
||||
#!/bin/bash
|
||||
if [ -f .beads/*.db ]; then
|
||||
bd export > .beads/issues.jsonl
|
||||
git add .beads/issues.jsonl
|
||||
fi
|
||||
```
|
||||
|
||||
### bd merge-databases (Priority: Low)
|
||||
|
||||
```bash
|
||||
bd merge-databases --ours=.beads/bd.db --theirs=/tmp/bd.db --output=merged.db
|
||||
# Intelligently merges:
|
||||
# - Same issue ID, different fields: prompt user
|
||||
# - Different issue IDs: keep both
|
||||
# - Conflicting dependencies: resolve automatically
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
**For beads itself**: Binary in git works great. Just commit `.beads/bd.db`.
|
||||
|
||||
**For bd users**:
|
||||
- Small teams: Binary in git with simple protocol
|
||||
- Medium teams: Text export format
|
||||
- Large teams: Shared database server
|
||||
|
||||
The key insight: **SQLite is amazing for local storage**, but git wasn't designed for binary merges. Accept this tradeoff and use the right solution for your team size.
|
||||
|
||||
**Document in README**: Add a "Git Workflow" section explaining binary vs text approaches and when to use each.
|
||||
Reference in New Issue
Block a user