Overview
sudocode uses a 3-layer storage architecture that combines the best of human-editable files, version control, and fast database queries. This “distributed git database” approach makes context durable, queryable, and fully version-controlled alongside your code.Git-Native Storage Philosophy
Traditional issue trackers store context in centralized databases:- GitHub Issues - Hosted database, accessed via API
- Jira - Cloud or self-hosted database
- Linear - Centralized SaaS database
- Version controlled alongside code
- Branches include their context
- Works offline
- Queryable locally
- Distributed by default
Context-as-Code Principle
Just as you version control your code, sudocode version controls your development context:- Context travels with code through branches
- Full git history of decisions and changes
- Merge conflicts are git merge conflicts
- Works offline, no API required
- Fast local queries via SQLite
The 3-Layer Architecture
sudocode uses three storage layers, each serving a specific purpose:Layer 1: Markdown
- Editable files
.mdformat- YAML frontmatter
- Git-tracked
Layer 2: JSONL
- Structured data
- Line-delimited JSON
- Git-friendly diffs
- Append-only log
Layer 3: SQLite
- Fast lookups
- Relational queries
- Graph traversal
- Gitignored, rebuilt
Why Three Layers?
Each layer optimizes for different needs:| Need | Layer | Why |
|---|---|---|
| Human editing | Markdown | Familiar format, readable diffs |
| Git tracking | JSONL | Structured, line-based diffs |
| Fast queries | SQLite | Relational queries, indexes |
| Relationships | SQLite | Graph traversal, joins |
| Offline work | All layers | Local-first design |
| Distribution | JSONL + Markdown | Git push/pull |
Layer 1: Markdown Files
Purpose
Markdown files provide a human-editable interface to specs and issues. Developers can edit context using their favorite text editor, just like editing code.Location
Format
Markdown files use YAML frontmatter for metadata plus markdown body for content: Example spec file (.sudocode/specs/authentication-system.md):
.sudocode/issues/ISSUE-042.md):
Frontmatter Fields
Specs:id- Unique identifier (SPEC-001, SPEC-002, etc.)title- Human-readable titlepriority- 0-4 (0=highest)status- draft, review, approved, deprecatedtags- Array of tagscreated_at- ISO 8601 timestampupdated_at- ISO 8601 timestampparent_id- Parent spec ID (optional)
id- Unique identifier (ISSUE-001, ISSUE-002, etc.)title- Human-readable titlestatus- open, in_progress, blocked, closedpriority- 0-4 (0=highest)tags- Array of tagsassignee- Assigned user (optional)created_at- ISO 8601 timestampupdated_at- ISO 8601 timestampclosed_at- ISO 8601 timestamp (if closed)parent_id- Parent issue ID (optional)
When to Edit Markdown
Manual editing:- Creating new specs
- Updating spec content
- Refining requirements
- Adding cross-references with
[[SPEC-ID]]syntax
- CLI operations sync back to markdown
sudocode sync --to-markdownregenerates from database
Layer 2: JSONL Files (Source of Truth)
Purpose
JSONL (JSON Lines) files are the source of truth for all sudocode data. These files are:- Git-tracked (committed to repository)
- Line-delimited (one JSON object per line)
- Merge-friendly (line-based diffs)
- Complete (includes all metadata, relationships, tags)
Location
Format
Each line is a complete JSON object representing one entity: Example specs.jsonl:JSONL Structure
Spec JSONL object:Why JSONL?
Git-friendly diffs:- New entities are appended
- Updates replace entire line
- Git shows clear line-by-line changes
- All relationships embedded
- All tags embedded
- All feedback embedded
- Single file per entity type
When JSONL is Updated
Automatic export (debounced):- After any CLI command that modifies data
- Debounce: 5 seconds (batches rapid changes)
- Triggered by:
sudocode issue create,sudocode spec update, etc.
Layer 3: SQLite Database (Query Cache)
Purpose
SQLite provides fast queries and relational operations:- Complex filters (status, priority, tags)
- Graph queries (find blockers, find ready work)
- Relationship traversal
- Full-text search
- Aggregations and statistics
Location
sudocode.db to git! It’s a cache that should be rebuilt locally from JSONL files. Add .sudocode/sudocode.db to your .gitignore.Schema
The database uses the following tables: Core entity tables:Why SQLite?
Fast local queries:- Indexed lookups: O(log n)
- Complex joins: Optimized by SQLite
- View queries: Precomputed logic
- Works offline: No API calls
When Database is Rebuilt
After git pull:Data Flow
Bidirectional Sync
Data flows between layers depending on the operation:Direction 1: Markdown → Database → JSONL
Triggered by: Manual markdown edits,sudocode sync --from-markdown
Parse markdown file
- Read frontmatter (YAML)
- Extract content (markdown body)
- Parse cross-references
[[SPEC-ID]]
Update database
- Upsert spec/issue record
- Create relationships from cross-references
- Update tags
- Update timestamps
Export to JSONL (debounced)
- Wait 5 seconds for more changes
- Query all entities from database
- Write complete JSONL files
- Include embedded relationships and tags
Git commit (manual)
- Commit markdown + JSONL changes together
- Context travels with code
Direction 2: Database → JSONL → Markdown
Triggered by: CLI operations,sudocode sync --to-markdown
CLI modifies database
sudocode issue create→ INSERT into issues tablesudocode spec update→ UPDATE specs tablesudocode link→ INSERT into relationships table
Export to JSONL (auto, debounced)
- Wait 5 seconds after last change
- Query all entities
- Write complete JSONL files
Sync to markdown (optional)
sudocode sync --to-markdownregenerates markdown files- Frontmatter updated from database
- Content preserved
Git commit (manual)
- Commit JSONL + markdown changes
Direction 3: JSONL → Database (After Git Pull)
Triggered by:git pull, sudocode sync, sudocode import
Git pull updates JSONL
- Teammate committed changes
- JSONL files updated
- Local markdown may be stale
Detect changes
- Compare JSONL modification time vs database
- JSONL is newer → import needed
Import to database
- Parse JSONL files line by line
- Upsert each entity (insert or update)
- Rebuild relationships table
- Rebuild tags table
- Handle feedback anchors
Sync to markdown (optional)
- Update markdown files from database
- Preserve content, update frontmatter
- Create new markdown files if needed
Auto-Sync Mechanisms
File Watching
sudocode can watch for file changes and auto-sync:- Watches
.sudocode/specs/and.sudocode/issues/directories - Detects markdown file changes
- Debounces changes (2 seconds)
- Auto-syncs to database
- Auto-exports to JSONL
Debouncing
To avoid excessive writes, sudocode debounces exports: Export debounce: 5 seconds- Waits 5 seconds after last database change
- Batches multiple rapid changes
- Writes JSONL once
- Waits 2 seconds after last file change
- Prevents sync on every keystroke
- Syncs once after editing
Manual Sync
For explicit control:- Compare markdown file modification times
- Compare JSONL file modification times
- Determine which is newer
- Sync in that direction
Git Distribution
Team Collaboration Workflow
JSONL files enable seamless team collaboration through git:Developer A creates spec
Developer B pulls changes
Developer B creates issues
Developer A pulls and sees new work
Merge Conflicts
JSONL conflicts:- Manual: Choose one version or merge fields
- AI-assisted: Ask AI to merge based on semantics
- Import after resolution:
Branching Strategy
Context travels with code branches:- Experimental specs in feature branches
- Merge specs with code when merging branch
- Context and code always in sync
Best Practices
Do’s
✓ Commit JSONL with code
✓ Commit JSONL with code
.sudocode/ changes alongside related code:- Context travels with implementation
- Code review includes design decisions
- Git history is complete
✓ Run sync after git pull
✓ Run sync after git pull
✓ Use watch mode during active development
✓ Use watch mode during active development
✓ Gitignore the database
✓ Gitignore the database
.gitignore:✓ Use branches for experimental specs
✓ Use branches for experimental specs
Don’ts
✗ Don't commit sudocode.db
✗ Don't commit sudocode.db
✗ Don't manually edit JSONL files
✗ Don't manually edit JSONL files
✗ Don't skip sync after git pull
✗ Don't skip sync after git pull
✗ Don't force-resolve merge conflicts
✗ Don't force-resolve merge conflicts
Troubleshooting
Database out of sync after git pull
Database out of sync after git pull
sudocode list shows stale dataCause: Pulled JSONL changes not imported to databaseSolution:Markdown files missing after git pull
Markdown files missing after git pull
JSONL changes not committed
JSONL changes not committed
Database corrupted or locked
Database corrupted or locked
Error: database is locked or database disk image is malformedCause: Concurrent access or corruptionSolution:Merge conflict in JSONL
Merge conflict in JSONL
specs.jsonl or issues.jsonlCause: Two branches modified same entitySolution:Option 1: Manual resolutionArchitecture Diagrams
3-Layer Architecture
Data Flow
Related Documentation
Sync Commands
Export Command
Import Command
Specs Concept
Issues Concept
Relationships
Next Steps
Initialize sudocode
Verify .gitignore
Create first spec
- Markdown file created
- Database updated
- JSONL exported
Commit to git
Set up sync hook (optional)

