Skip to main content

Git Memory Branching & Commit Search — Design Document

ARCHIVE — This document is historical reference only. It may contain outdated information. See docs/status.md for current project state.

Created: February 13, 2026 Status: Planned Phase: 3i (Memory Enhancement)


Overview

Extend Morphee's git-backed memory system (Phase 2) with branching, visualization, and searchable commit history. Enables temporal navigation ("what did I know last month?"), experimental timelines ("vacation planning branch"), and semantic search over memory evolution.


Motivation

Problem: The current memory system (Phase 2) is linear — memories accumulate chronologically in a single git timeline. Users can't:

  • Explore "what-if" scenarios without affecting their main memory
  • Easily navigate to past memory states
  • Search for when they last discussed a topic

Solution: Add git branching + commit search:

  1. Branches — Create parallel memory timelines (main, experiments, archives)
  2. Commit search — Embed commits in LanceDB, search by semantic query + time
  3. Branch visualization — Timeline UI showing branch divergence, merge points
  4. Temporal RAG — Query memory as it existed at a specific point in time

Use Cases

UserScenario
Parent (Sophie)"Show me my main schedule" vs "Show me the vacation planning timeline" — separate work from exploration
Teacher (Emma)Create a "Fall 2026 semester" branch, experiment with lesson plans, merge selected ones to main after testing
Manager (Julie)"Create a branch for Project Phoenix planning" — iterate on ideas without cluttering team's main memory
Grandparent (Jeanne)"What did I know about Christmas planning last month?" — temporal navigation to see past state

Architecture

Backend: GitStore Extension

Current (backend/memory/git_store.py):

class GitStore:
async def init_repo(group_id) → Path
async def save_conversation(group_id, conversation_id, messages, title)str
async def save_memory(group_id, memory_id, content, memory_type, scope)str
async def delete_memory(group_id, memory_id, memory_type, scope)bool
async def sync(group_id) → SyncResult # push/pull if remote configured

Phase 3i additions:

class GitStore:
# Branch operations
async def create_branch(group_id: UUID, branch_name: str, from_commit: str | None = None)str
async def switch_branch(group_id: UUID, branch_name: str)str # returns commit hash
async def list_branches(group_id: UUID)list[BranchInfo]
async def merge_branch(group_id: UUID, source: str, target: str, strategy: str = "manual") → MergeResult
async def get_commit_history(group_id: UUID, branch: str | None = None, limit: int = 50)list[CommitInfo]

# Commit metadata
async def get_commit_diff(group_id: UUID, commit_hash: str) → DiffResult
async def checkout_commit(group_id: UUID, commit_hash: str)str # detached HEAD for temporal queries

Data models:

class BranchInfo(BaseModel):
name: str
commit: str # HEAD commit hash
is_active: bool
created_at: datetime

class CommitInfo(BaseModel):
hash: str
message: str
timestamp: datetime
branch: str
changed_files: list[str]
author: str = "Morphee"

class MergeResult(BaseModel):
merged: bool
commit: str | None # merge commit hash if successful
conflicts: list[ConflictInfo]
merged_count: int

Database: Commit Metadata Table

CREATE TABLE git_commit_metadata (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
group_id UUID NOT NULL REFERENCES groups(id) ON DELETE CASCADE,
commit_hash VARCHAR(40) NOT NULL,
branch VARCHAR(100) NOT NULL,
message TEXT NOT NULL,
timestamp TIMESTAMPTZ NOT NULL,
changed_files JSONB NOT NULL DEFAULT '[]',
embedding vector(384), -- LanceDB embedding for semantic search
created_at TIMESTAMPTZ DEFAULT NOW(),

UNIQUE(group_id, commit_hash)
);

CREATE INDEX idx_commit_metadata_group_branch ON git_commit_metadata(group_id, branch);
CREATE INDEX idx_commit_metadata_timestamp ON git_commit_metadata(group_id, timestamp DESC);
CREATE INDEX idx_commit_embedding ON git_commit_metadata USING ivfflat (embedding vector_cosine_ops);

Memory Integration Extension

New actions:

class MemoryIntegration(BaseInterface):
# ... existing: search, store, recall, forget

async def create_branch(self, ctx: ExecutionContext, name: str, from_commit: str | None = None)
async def switch_branch(self, ctx: ExecutionContext, name: str)
async def search_history(self, ctx: ExecutionContext, query: str, time_range: dict | None, branch: str | None, limit: int = 10)
async def merge_branch(self, ctx: ExecutionContext, source: str, target: str, strategy: str = "manual")

Frontend: Timeline UI

New page: frontend/src/pages/MemoryTimeline.tsx

Components:

  1. TimelineRenderer (Tier 2 component) — Visual git log with branch graph
  2. CommitDetailDialog — Shows commit message, changed files, diff view
  3. BranchSelector (dropdown) — Shows current branch + all branches
  4. Historical context badge — "Viewing: 2 weeks ago (detached)"

Tauri Rust: git2 Branching

Extensions to frontend/src-tauri/src/git_store.rs:

impl GitStore {
pub fn create_branch(&self, group_id: &str, branch_name: &str, from_commit: Option<&str>)Result<String>
pub fn switch_branch(&self, group_id: &str, branch_name: &str)Result<String>
pub fn list_branches(&self, group_id: &str)Result<Vec<BranchInfo>>
pub fn merge_branch(&self, group_id: &str, source: &str, target: &str, strategy: &str)Result<MergeResult>
}

API Endpoints

EndpointMethodDescription
/api/memory/branchesPOSTCreate branch
/api/memory/branches/switchPOSTSwitch active branch
/api/memory/branchesGETList all branches
/api/memory/search-historyPOSTSearch commits semantically
/api/memory/branches/mergePOSTMerge branches
/api/memory/commits/{hash}GETGet commit details + diff
/api/memory/checkout/{hash}POSTCheckout commit (detached HEAD)

Effort Estimation

TaskSizeNotes
Backend: GitStore branching (Python)Mcreate, switch, list, merge, checkout
Backend: git_commit_metadata table + migrationXSSQL schema
Backend: Commit embedding pipelineSExtend MemorySyncScheduler
Backend: MemoryIntegration actionsM4 new actions + tests
Backend: Branch-aware RAGSAdd branch param to search()
Tauri: git_store.rs branching (Rust)Mgit2 branch operations
Frontend: TimelineRenderer componentMGit graph visualization
Frontend: MemoryTimeline pageMCommit list, detail, navigation
Frontend: Branch selector UISDropdown in chat/memory views
Tests: Backend + Tauri + FrontendM50+ tests total

Total: Large (3-4 weeks)


Risks & Mitigations

RiskMitigation
Git conflicts too complex for AI/userStart with simple strategies ("ours", "theirs"), defer manual conflict resolution UI to later iteration
Detached HEAD confusionClear UI indicator ("Viewing past memory — Back to present" button)
Branch proliferation clutterAdd archive/delete branch actions, suggest cleanup in onboarding
Performance: embedding all commitsBackground job, rate-limited. Only embed commits since last sync

Future Enhancements

Core Features

  • Automatic branching — AI suggests creating a branch when user says "let's explore this idea"
  • Branch templates — Pre-configured branches for common scenarios (vacation, project, semester)
  • Cross-branch diff view — Compare memory state across branches visually
  • Conflict resolution UI — Side-by-side diff editor for manual merge
  • Branch search — "Find branches related to vacation" → semantic search across branch names and commit history
  • Branch lifecycle — Auto-archive branches after inactivity, scheduled cleanup

ACL & Permission Enhancements

Branch Permissions (leveraging existing PermissionPolicy):

class BranchPermission(BaseModel):
branch_pattern: str # "main", "personal/*", "experiments/*"
can_create: list[str] # ["parent", "teacher"]
can_merge: list[str] # ["parent"]
can_delete: list[str] # ["parent"]
can_view: list[str] # ["parent", "child", "guest"]
require_approval: bool # Merge requires approval from approvers list
approvers: list[str] # User IDs or roles who can approve merges

Use cases:

  1. Family scenario:

    • Kids can create branches under personal/{kid_name}/* but only read from main
    • Parents can merge any branch to main
    • Family decisions require parent approval before merging
  2. Classroom scenario:

    • Students create branches per assignment: students/{name}/assignment-1
    • Teacher can view all student branches (read-only)
    • Students can't see other students' branches
    • Teacher merges approved work to class-main
  3. Team scenario:

    • Developers create feature branches: features/{feature-name}
    • Any team member can merge to develop
    • Manager approval required to merge to main

Branch Visibility:

  • Private branches: Only creator + admins can see (e.g., "Mom's surprise party planning")
  • Shared branches: Visible to group members based on roles
  • Public branches: Visible to all group members (default)

Audit Trail:

  • Log all branch operations with attribution: who created, who merged, who deleted
  • Stored in git_branch_operations table: {user_id, branch, operation, timestamp, approved_by?, commit_hash}
  • Query: "Who merged the vacation branch last week?" → shows audit trail

Advanced Memory Features

Memory Permissions Per Branch:

  • Different RAG contexts per user role within same branch
  • Example: Kid sees age-appropriate memories, parent sees everything
  • Implemented via PermissionPolicy on MemoryIntegration.search with branch + role context

Branch-Specific Retention:

  • Automatic memory decay on experimental branches (older than 30 days deleted)
  • Main branch has indefinite retention
  • Archive branches compressed (embeddings removed, only Markdown kept)

Collaborative Branching:

  • Multiple users can work on same branch simultaneously
  • Real-time conflict detection: "Mom is editing vacation plans on this branch right now"
  • Merge conflict resolution via AI mediation: "Mom wants Paris, Dad wants Rome — let's discuss"

Memory Branch Notifications:

  • "Your vacation planning branch has 3 new commits from Mom"
  • "Experimental meal plan branch ready for review — merge to main?"
  • Integration with NotificationsIntegration

Branch Subscriptions:

  • Subscribe to branch changes (like GitHub watch)
  • Receive notification when branch is updated
  • User table: branch_subscriptions JSONB[{branch: "vacation", notify: true}]

AI-Powered Enhancements

Smart Merge Suggestions:

  • AI analyzes two branches and suggests best merge strategy
  • "These memories are complementary — safe auto-merge"
  • "Conflict detected: Mom scheduled dentist Tuesday 2pm, you have soccer practice same time"

Branch Summarization:

  • "Summarize what changed in vacation-planning branch" → AI reads commits, generates summary
  • Useful before merging: "Review changes before merging to main"

Temporal Queries Across Branches:

  • "Compare my main timeline vs experimental timeline 2 weeks ago"
  • "Show me all branches where we discussed Christmas planning"

Branch Recommendations:

  • AI suggests creating a branch: "This seems like a big decision — want to explore in a separate branch?"
  • AI suggests merging: "Your meal prep experiments look good — ready to merge to main?"

Integration with Existing Systems

Branch-Aware Skills (Phase 3b.1 Dynamic Skills):

  • Skills can specify which branch to use: {branch: "experiments"}
  • Cron jobs can run on specific branches: "Daily backup skill runs on main only"

Branch-Aware Spaces (existing Space system):

  • Each Space can have a default branch: "Homework space always uses student's personal branch"
  • Space inheritance: sub-Space inherits parent's branch unless overridden

Branch-Based Sandboxing:

  • Test AI changes in a branch before applying to main
  • "Try this new scheduling algorithm in experimental branch first"

Last Updated: February 13, 2026