Feature: Git-Native Spaces & OpenMorph Protocol
ARCHIVE — This document is historical reference only. It may contain outdated information. See docs/status.md for current project state.
Date: 2026-02-16 Status: Investigation Phase: 3i (expanded) — Git-Native Spaces Effort: XL (10-14 weeks)
1. Context & Motivation
Problem Statement
Morphee currently has three separate but related systems that need to be unified:
- Git-backed memory (Phase 2, DONE) — Stores conversations/facts/preferences in git repos
- Git branching (Phase 3i, PLANNED) — Temporal navigation, experimental timelines
- PostgreSQL-backed Spaces (current) — Tasks, skills, schedules stored in database
This creates:
- Data fragmentation — some data in Git, some in PostgreSQL
- Limited portability — can't easily export/share a complete Space
- No version control for tasks/skills — only memory is versioned
- Vendor lock-in — Spaces tied to Morphee's PostgreSQL instance
Vision: OpenMorph Protocol
Transform Morphee from a centralized app to a protocol + reference implementation:
┌─────────────────────────────────────────────────────────┐
│ OpenMorph Protocol │
│ Specification for .morph/ directories │
│ (Any directory with .morph/ becomes a Morph Space) │
└─────────────────────────────────────────────────────────┘
↓ implements
┌─────────────────────────────────────────────────────────┐
│ Morphee.app │
│ Reference implementation: AI layer for .morph/ spaces │
│ Makes directories alive, interactive, explainable │
└─────────────────────────────────────────────────────────┘
↓ works with
┌─────────────────────────────────────────────────────────┐
│ User's Filesystem │
│ ~/Projects/TechCorp/.morph/ │
│ ~/School/Math101/.morph/ │
│ ~/Family/meal-planning/.morph/ │
└─────────────────────────────────────────────────────────┘
Key insight: Just like .git/ makes any directory version-controllable, .morph/ makes any directory AI-augmentable.
2. Options Investigated
Option A: Keep Fragmented (Status Quo)
- Memory in Git, tasks/skills in PostgreSQL
- Implement Phase 3i branching for memory only
- Pros: No migration, simpler short-term
- Cons: Data fragmentation continues, no portability, limited vision
Option B: Migrate Everything to Git (All-In)
- ALL Space data (tasks, conversations, skills, config, ACL, vault) lives in Git
- PostgreSQL only for identity (users, groups, group_members)
.morph/directory structure becomes canonical- Pros: Complete portability, version control for everything, federation-ready
- Cons: Large migration, PostgreSQL becomes cache (complexity)
Option C: Hybrid with Sync Layer
- Git is source of truth, PostgreSQL is read cache
- Bidirectional sync: writes go to Git, reads from PostgreSQL for speed
.morph/directories can be local-only OR synced to backend- Pros: Best of both worlds, performance + portability
- Cons: Sync complexity, conflict resolution needed
Option D: Phased Rollout (Recommended)
Incrementally migrate to Git-native Spaces over multiple sub-phases:
- Phase 3i.1 — Git branching for memory (as planned)
- Phase 3i.2 — Define OpenMorph spec +
.morph/structure - Phase 3i.3 — Extend GitStore for tasks/conversations/skills
- Phase 3i.4 — Local discovery + sync modes
- Phase 3i.5 — Migration tools + backward compatibility
Pros: Incremental delivery, testable steps, lower risk Cons: Longer timeline, temporary complexity during transition
3. Decision
Chosen approach: Option B (Migrate Everything to Git) - Aggressive Timeline
Reasoning:
- No users yet → can do breaking changes without impact
- Faster to full vision (8 weeks vs 10-14 weeks)
- No backward compatibility burden → cleaner codebase
- Forced migration → everyone on same system from day one
Trade-offs accepted:
- Higher risk (all-in migration, no fallback)
- Breaking change for development database (acceptable)
- Must get it right first time (thorough testing required)
4. Architecture Design
4.1 OpenMorph Directory Structure
any-directory/ # User's actual project/folder
├── .morph/ # ← Presence = Morph Space
│ ├── config.yaml # REQUIRED: Space metadata
│ ├── acl.yaml # OPTIONAL: Access control rules
│ ├── vault.enc # OPTIONAL: Encrypted secrets
│ ├── tasks/ # REQUIRED: Tasks as Markdown
│ │ └── task-001.md
│ ├── conversations/ # REQUIRED: AI chat history
│ │ └── conv-001.md
│ ├── memory/ # REQUIRED: Facts, preferences, events
│ │ ├── facts/
│ │ ├── preferences/
│ │ ├── events/
│ │ └── notes/
│ ├── skills/ # OPTIONAL: Dynamic skills
│ │ └── daily-briefing.yaml
│ ├── schedules/ # OPTIONAL: Cron schedules
│ │ └── weekly-backup.yaml
│ └── .git/ # OPTIONAL: Version control
├── src/ # User's files (unchanged)
├── docs/
└── README.md
Key principles:
.morph/is ALONGSIDE user's files, not replacing them- Works with existing projects (drop
.morph/into any directory) - Git-friendly (designed to version well)
- Tool-agnostic (any tool can read/write
.morph/if it follows spec)
4.2 config.yaml Schema
# .morph/config.yaml
openmorph_version: "0.1.0"
space:
id: "uuid-or-slug"
name: "TechCorp API Project"
type: "project" # project | personal | team | family | classroom
created_at: "2026-02-16T10:00:00Z"
created_by: "alice@example.com"
# Parent space (for nested spaces)
parent:
path: "../.morph" # Relative path to parent
inherit_acl: true
inherit_integrations: true
# Group (links to Morphee.app backend identity)
group:
id: "group-uuid-123"
name: "TechCorp Engineering"
sync_url: "https://api.morphee.app/sync/group-uuid-123"
# Git configuration
git:
enabled: true
remote_url: "git@gitlab.com:techcorp/api-project.git"
branch: "main"
auto_commit: true
auto_push: false
# Sync mode
sync:
mode: "local-only" # local-only | morphee-hosted | git-remote
backend_url: null
encryption: "group-key"
# Active integrations
integrations:
- llm
- memory
- tasks
- google-calendar
4.3 Three Sync Modes
| Mode | Description | Backend | Git Remote | Use Case |
|---|---|---|---|---|
| local-only | Never leaves device | None | Optional (user manages) | Privacy-focused users, offline work |
| morphee-hosted | Synced to Morphee backend | api.morphee.app | Morphee's GitLab | Default for new users, easiest |
| git-remote | User's Git server | None | User-provided | Power users, self-hosting, teams |
4.4 Database Changes
New table: morph_spaces
CREATE TABLE morph_spaces (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
group_id UUID REFERENCES groups(id) ON DELETE SET NULL,
-- Filesystem location (if user syncs with backend)
local_path TEXT, -- e.g., "/Users/alice/Projects/TechCorp"
-- Git repository URL
git_repo_url TEXT, -- Morphee-hosted OR user's remote
-- Sync mode
sync_mode TEXT CHECK (sync_mode IN ('local-only', 'morphee-hosted', 'git-remote')),
-- Config snapshot (for fast queries)
config JSONB NOT NULL,
-- Status
last_synced_at TIMESTAMPTZ,
sync_status TEXT DEFAULT 'ok', -- ok | syncing | conflict | error
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, local_path)
);
-- Git commit metadata (for semantic search over history)
CREATE TABLE git_commit_metadata (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
space_id UUID NOT NULL REFERENCES morph_spaces(id) ON DELETE CASCADE,
commit_hash VARCHAR(40) NOT NULL,
branch VARCHAR(100) NOT NULL DEFAULT 'main',
message TEXT NOT NULL,
timestamp TIMESTAMPTZ NOT NULL,
changed_files JSONB NOT NULL DEFAULT '[]',
embedding vector(384), -- For semantic commit search
UNIQUE(space_id, commit_hash)
);
Migration strategy:
- BREAKING CHANGE: Force migration of all existing Spaces
- Migration script runs on deploy, converts all Spaces to
.morph/format spacestable deprecated, replaced bymorph_spaces
4.5 Backend Components
New modules:
# backend/morph/discovery.py
class MorphDiscoveryService:
async def scan_directory(base_path: str, max_depth: int = 5) → list[MorphSpace]
async def register_morph_space(user: User, local_path: str, sync_mode: str) → MorphSpace
async def sync_local_to_backend(space_id: UUID) → SyncResult
# backend/morph/sync.py
class MorphSyncService:
async def sync_git_to_postgres(space_id: UUID) → None # For fast queries
async def sync_postgres_to_git(space_id: UUID) → None # On user edits
async def resolve_conflicts(space_id: UUID, strategy: str) → ConflictResolution
# backend/morph/exporter.py
class MorphExporter:
async def export_space_to_morph(space_id: UUID, target_path: str) → Path
async def import_morph_to_space(morph_path: str) → UUID
Extended GitStore:
# backend/memory/git_store.py (extended)
class GitStore:
# Existing: save_conversation, save_memory, sync
# NEW: Branching (Phase 3i.1)
async def create_branch(group_id, space_id, name, from_commit=None) → str
async def switch_branch(group_id, space_id, name) → str
async def list_branches(group_id, space_id) → list[BranchInfo]
async def merge_branch(group_id, space_id, source, target) → MergeResult
# NEW: Extended data types (Phase 3i.3)
async def save_task(group_id, space_id, task_id, task_data) → str
async def save_skill(group_id, space_id, skill_id, skill_data) → str
async def save_config(group_id, space_id, config) → str
async def save_acl(group_id, space_id, acl) → str
4.6 Tauri Commands
// frontend/src-tauri/src/commands/morph_commands.rs
#[tauri::command]
async fn morph_init(path: String, config: MorphConfig) → Result<(), MorpheeError>
#[tauri::command]
async fn morph_discover(base_path: String, max_depth: u32) → Result<Vec<MorphSpace>, MorpheeError>
#[tauri::command]
async fn morph_read_config(morph_path: String) → Result<MorphConfig, MorpheeError>
#[tauri::command]
async fn morph_register(local_path: String, sync_mode: String) → Result<String, MorpheeError>
4.7 Frontend UI
New pages:
-
Space Discovery (
pages/SpaceDiscovery.tsx)- Scan filesystem for
.morph/directories - Show list of discovered Spaces
- Option to register with backend or keep local
- Scan filesystem for
-
Morph Init Dialog (
components/morph/MorphInitDialog.tsx)- Choose directory
- Configure sync mode
- Initialize
.morph/structure
-
Sync Settings (
pages/settings/SyncTab.tsx)- Per-Space sync mode
- Conflict resolution UI
- Sync status indicators
5. Implementation Plan (Aggressive - 8 weeks)
Phase 3i.1: Git Branching + OpenMorph Spec — 2 weeks
Goal: Branching for memory + define .morph/ structure (parallel work).
| Step | Description | Effort | Dependencies |
|---|---|---|---|
| 1.1 | Backend: Extend GitStore with branch operations | M | None |
| 1.2 | Backend: git_commit_metadata table + migration | XS | Step 1.1 |
| 1.3 | Backend: MemoryIntegration branch actions | M | Step 1.1 |
| 1.4 | Tauri: git2 branch operations in Rust | M | Step 1.1 |
| 1.5 | Write SPECIFICATION.md (in docs/features/) | S | Parallel |
| 1.6 | Define JSON Schemas for config/acl/tasks | S | Step 1.5 |
| 1.7 | Create example .morph/ directories | XS | Step 1.6 |
| 1.8 | Tests: Branching operations | M | Steps 1.1-1.4 |
Deliverable: Git branching works + OpenMorph spec defined.
Phase 3i.2: Full GitStore Migration (BREAKING) — 3 weeks
Goal: ALL Space data (tasks, skills, config, ACL) in Git. PostgreSQL = cache only.
| Step | Description | Effort | Dependencies |
|---|---|---|---|
| 2.1 | Define task Markdown schema | S | Phase 3i.1 |
| 2.2 | Define skill/schedule YAML schemas | S | Step 2.1 |
| 2.3 | Backend: GitStore save_task/skill/config/acl | L | Step 2.2 |
| 2.4 | Tauri: Rust GitStore extensions | M | Step 2.3 |
| 2.5 | Backend: Sync layer (Git → Postgres cache) | M | Step 2.3 |
| 2.6 | Backend: Sync layer (Postgres → Git write) | M | Step 2.5 |
| 2.7 | Database migration: morph_spaces table | S | Step 2.3 |
| 2.8 | Migration script: Convert all existing Spaces | M | Step 2.7 |
| 2.9 | Update all services (TaskService, SkillService, etc.) | L | Step 2.8 |
| 2.10 | Tests: Full CRUD cycle for all data types | L | All above |
Deliverable: Complete Spaces stored in Git, PostgreSQL is cache.
Phase 3i.3: Discovery + Sync Modes — 2 weeks
Goal: Morphee.app discovers .morph/ on filesystem, supports 3 sync modes.
| Step | Description | Effort | Dependencies |
|---|---|---|---|
| 3.1 | Backend: MorphDiscoveryService | M | Phase 3i.2 |
| 3.2 | Backend: Register/sync endpoints | M | Step 3.1 |
| 3.3 | Tauri: morph_discover command | M | Step 3.1 |
| 3.4 | Tauri: morph_init command | M | Step 3.3 |
| 3.5 | Frontend: SpaceDiscovery page | M | Step 3.3 |
| 3.6 | Frontend: MorphInitDialog | M | Step 3.4 |
| 3.7 | Backend: Sync modes (local/hosted/remote) | M | Step 3.2 |
| 3.8 | Tests: Discovery + sync flows | M | All above |
Deliverable: Users can drop .morph/ anywhere, choose sync mode.
Phase 3i.4: Polish + Timeline UI — 1 week
Goal: Timeline visualization, conflict resolution, final cleanup.
| Step | Description | Effort | Dependencies |
|---|---|---|---|
| 4.1 | Frontend: TimelineRenderer component | M | Phase 3i.3 |
| 4.2 | Frontend: MemoryTimeline page | M | Step 4.1 |
| 4.3 | Frontend: Branch selector UI | S | Step 4.2 |
| 4.4 | Frontend: Conflict resolution dialog | M | Step 4.3 |
| 4.5 | Backend: Commit embedding pipeline | S | Phase 3i.2 |
| 4.6 | Documentation: User guide + API docs | S | All above |
| 4.7 | Final integration tests | M | All above |
Deliverable: Production-ready Git-native Spaces with full UI.
6. Effort Summary
| Phase | Size | Duration |
|---|---|---|
| 3i.1 (Branching + Spec) | M | 2 weeks |
| 3i.2 (Full Migration) | L | 3 weeks |
| 3i.3 (Discovery + Sync) | M | 2 weeks |
| 3i.4 (Polish + UI) | M | 1 week |
| TOTAL | L-XL | 8 weeks |
7. Questions & Answers
Q1: Should we rename Phase 3i?
A: Yes. Rename from "Memory Enhancement" to "Git-Native Spaces & OpenMorph" to reflect broader scope.
Q2: Should OpenMorph spec be a separate repository?
A: No, not initially. Keep in docs/features/openmorph/ until implementation proven. Public repo later when ready for partners.
Q3: Priority: Memory branching or .morph/ first?
A: Memory branching first (Phase 3i.1). It's smaller, delivers value immediately, builds foundation for later phases.
Q4: Migration: Convert existing Spaces automatically?
A: YES. Force migration on deploy. No users yet, so acceptable breaking change. Migration script converts all Spaces automatically.
Q5: What happens to PostgreSQL?
A: Becomes identity layer (users, groups) + read cache for fast queries. Git is source of truth for Space data.
Q6: Can users manually edit .morph/ files?
A: YES! This is a key feature. Power users can vim tasks/task-001.md, commit with git, Morphee syncs it.
Q7: What about real-time collaboration?
A: Not in this phase. Future: operational transforms or CRDT layer on top of Git. For now: last-write-wins + conflict UI.
Q8: GPG signing (from earlier discussion)?
A: Phase 3i.6 (future). Add signed commits, ACL in Git, vault encryption. Don't block this phase on crypto.
8. Risks & Mitigations
| Risk | Mitigation |
|---|---|
| Git conflicts too complex | Start with simple strategies (last-write-wins, ours/theirs). Manual resolution UI in Phase 3i.5 |
| Sync performance | PostgreSQL cache for reads. Only sync on write. Background job for conflict-free sync |
| User confusion (Git concepts) | Hide Git details in UI. Show "timeline", "experimental ideas", not "branches" |
| Data loss during migration | Extensive testing. Backup before convert. Rollback option. Export tool always available |
| OpenMorph fragmentation | Strict semver. Breaking changes only in major versions. Reference implementation (Morphee.app) sets standard |
9. Open Items
- Decide on conflict resolution strategy — last-write-wins, manual UI, or AI-mediated?
- Define OpenMorph versioning policy — semver, deprecation timeline
- Partner outreach — which tools to target first (VS Code, Obsidian, Notion)?
- Performance benchmarks — how big can .morph/ get before slowdown?
- Mobile considerations — does .morph/ work on iOS/Android filesystem?
10. Success Metrics
| Metric | Target |
|---|---|
| Adoption | 50% of new Spaces created as .morph/ within 3 months |
| Migration | 25% of existing Spaces converted within 6 months |
| Partners | 2+ third-party tools implementing OpenMorph within 1 year |
| Performance | Space sync <5s for typical Space (~100 tasks, 50 conversations) |
| Reliability | <1% data loss rate during sync/migration |
11. References
Internal
- Phase 2 GitStore Implementation
- Phase 3i Memory Branching Design
- ROADMAP.md (Phase 3i archived, see current V1.0 OpenMorph layer)
External
Next Steps:
- Review this proposal with team
- Get approval on phased approach
- Start Phase 3i.1 (Git Branching) implementation
- Draft OpenMorph SPECIFICATION.md during Phase 3i.1
- Publish spec, announce to community
Last Updated: 2026-02-16