Skip to main content

OpenMorph Specification v0.1.0

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

Status: Draft (Private) Last Updated: 2026-02-16


Abstract

OpenMorph is a specification for augmenting directories with AI-native metadata. Any directory containing a .morph/ subdirectory becomes a "Morph Space" — a context-aware, AI-augmentable workspace.

Key insight: Just like .git/ makes any directory version-controllable, .morph/ makes any directory AI-augmentable.


Design Principles

  1. Filesystem-native.morph/ is just a directory, works with any OS
  2. Git-friendly — Designed to version well with Git
  3. Tool-agnostic — Any tool can implement OpenMorph
  4. Privacy-first — Local-only by default, sync is opt-in
  5. Portable — Copy .morph/ = copy the entire Space
  6. Human-readable — All files are Markdown/YAML (no binary formats)

Directory Structure

Required Files

.morph/
├── config.yaml # REQUIRED: Space metadata
├── tasks/ # REQUIRED: Can be empty
├── conversations/ # REQUIRED: Can be empty
└── memory/ # REQUIRED: Can be empty
├── facts/
├── preferences/
├── events/
└── notes/

Optional Files

.morph/
├── acl.yaml # Access control rules (for shared spaces)
├── vault.enc # Encrypted secrets (interface credentials)
├── skills/ # Dynamic AI skills
├── schedules/ # Cron schedules
└── .git/ # Version control (recommended)

Reserved Names

The following names are RESERVED and MUST NOT be used for user-created files:

  • .morph/config.yaml
  • .morph/acl.yaml
  • .morph/vault.enc
  • .morph/.git/
  • .morph/.gitignore
  • .morph/.morphee/ (tool-specific cache, not part of spec)

File Formats

config.yaml

Location: .morph/config.yaml Required: YES Format: YAML

Schema:

# OpenMorph version (semver)
openmorph_version: "0.1.0"

# Space metadata
space:
id: string # UUID or human-readable slug
name: string # Display name
type: enum # project | personal | team | family | classroom
created_at: datetime # ISO 8601
created_by: string # Email or identifier

# Parent space (for nested spaces)
parent:
path: string # Relative path to parent .morph/
inherit_acl: boolean # Inherit parent's access control
inherit_integrations: boolean # Inherit parent's integrations

# Group (links to identity system)
group:
id: string # Group UUID (optional)
name: string # Group name
sync_url: string # Backend sync endpoint (optional)

# Git configuration
git:
enabled: boolean # Whether git is used
remote_url: string # Git remote URL (optional)
branch: string # Default branch (default: "main")
auto_commit: boolean # Auto-commit changes
auto_push: boolean # Auto-push commits

# Sync configuration
sync:
mode: enum # local-only | morphee-hosted | git-remote
backend_url: string # Backend API URL (null for local-only)
encryption: enum # none | group-key | user-key

# Active integrations
integrations:
- string[] # List of integration names

# Metadata
metadata:
tags: string[] # Tags for categorization
description: string # Space description
icon: string # Emoji or icon identifier

Example:

openmorph_version: "0.1.0"

space:
id: "techcorp-api-refactor"
name: "TechCorp API Refactor"
type: "project"
created_at: "2026-02-16T10:00:00Z"
created_by: "alice@techcorp.com"

git:
enabled: true
remote_url: "git@gitlab.com:techcorp/api-refactor.git"
branch: "main"
auto_commit: true
auto_push: false

sync:
mode: "git-remote"
backend_url: null
encryption: "none"

integrations:
- llm
- memory
- tasks
- slack

metadata:
tags: ["engineering", "backend", "api"]
description: "Refactoring the core API layer"
icon: "🚀"

acl.yaml (Optional)

Location: .morph/acl.yaml Required: NO (only for shared Spaces) Format: YAML

Schema:

version: string              # ACL schema version

# Role assignments
roles:
[role_name]:
- string[] # List of user emails/identifiers

# Permission matrix
permissions:
[resource]:
[action]:
- string[] # List of roles allowed

# Audit settings
audit:
enabled: boolean
require_signatures: boolean
log_acl_changes: boolean

Example:

version: "1.0"

roles:
admin:
- alice@techcorp.com
developer:
- bob@techcorp.com
- charlie@techcorp.com
viewer:
- manager@techcorp.com

permissions:
tasks:
create: [admin, developer]
update_own: [admin, developer]
update_any: [admin]
delete: [admin]

conversations:
read: [admin, developer, viewer]
create: [admin, developer]
delete: [admin]

acl:
read: [admin, developer, viewer]
modify: [admin]

audit:
enabled: true
require_signatures: false
log_acl_changes: true

Tasks (Markdown)

Location: .morph/tasks/*.md Format: Markdown with YAML frontmatter

Schema:

---
title: string # Task title
status: enum # pending | in_progress | completed | failed | cancelled
priority: enum # low | medium | high | urgent
created_by: string # User email/identifier
created_at: datetime # ISO 8601
due_at: datetime # ISO 8601 (optional)
assigned_to: string # User email/identifier (optional)
parent_task_id: string # Parent task UUID (optional)
tags: string[] # Tags
metadata: object # Custom metadata
---

Task description in Markdown.

- Checklist items
- Can use **formatting**
- Can include [links](https://example.com)

Example:

---
title: "Refactor authentication layer"
status: "in_progress"
priority: "high"
created_by: "alice@techcorp.com"
created_at: "2026-02-16T10:00:00Z"
due_at: "2026-02-20T18:00:00Z"
assigned_to: "bob@techcorp.com"
tags: ["backend", "security", "api"]
---

Refactor the authentication layer to use JWT tokens instead of session cookies.

**Requirements:**
- Implement JWT generation/validation
- Update middleware
- Migrate existing sessions
- Update documentation

**Notes:**
- See [RFC 7519](https://tools.ietf.org/html/rfc7519) for JWT spec
- Consult with security team before deploying

Conversations (Markdown)

Location: .morph/conversations/*.md Format: Markdown with YAML frontmatter

Schema:

---
conversation_id: string # UUID
title: string # Conversation title
created_at: datetime # ISO 8601
user_id: string # User identifier
space_id: string # Space identifier
---

# [Role] — [Timestamp]

Message content...

---

# [Role] — [Timestamp]

Message content...

Example:

---
conversation_id: "conv-abc-123"
title: "API authentication strategy"
created_at: "2026-02-16T10:00:00Z"
user_id: "alice@techcorp.com"
space_id: "techcorp-api-refactor"
---

# User — 2026-02-16T10:00:00Z

What's the best approach for API authentication: JWT or OAuth2?

---

# Assistant — 2026-02-16T10:00:15Z

Both are valid, but for different use cases:

**JWT (JSON Web Tokens):**
- Best for stateless APIs
- Self-contained (no server-side session storage)
- Good for microservices

**OAuth2:**
- Best for third-party integrations
- Supports delegated access
- More complex to implement

For your internal API refactor, I'd recommend **JWT** because...

---

# User — 2026-02-16T10:05:00Z

Great! Let's go with JWT. Can you help me implement it?

Skills (YAML)

Location: .morph/skills/*.yaml Format: YAML

Schema:

name: string                 # Skill name
description: string # What the skill does
enabled: boolean # Is this skill active
parameters: # Input parameters
[param_name]:
type: enum # string | number | boolean | object | array
description: string
required: boolean
default: any

steps: # Execution steps
- id: string # Step identifier
interface: string # Interface name
action: string # Action name
params: object # Action parameters (supports {{templates}})
on_error: enum # fail | continue

Example:

name: "Daily Project Sync"
description: "Syncs project tasks with Slack and creates a daily summary"
enabled: true

parameters:
channel:
type: "string"
description: "Slack channel to post summary"
required: true
default: "#engineering"

steps:
- id: "fetch_tasks"
interface: "tasks"
action: "list"
params:
status: "in_progress"
limit: 50
on_error: "fail"

- id: "generate_summary"
interface: "llm"
action: "complete"
params:
prompt: "Summarize these tasks:\n{{steps.fetch_tasks.result}}"
on_error: "fail"

- id: "post_slack"
interface: "slack"
action: "send_message"
params:
channel: "{{params.channel}}"
text: "{{steps.generate_summary.result}}"
on_error: "continue"

Validation Rules

File Size Limits

  • config.yaml: Max 10 KB
  • acl.yaml: Max 5 KB
  • Task files: Max 100 KB each
  • Conversation files: Max 500 KB each
  • Skill files: Max 50 KB each

Naming Conventions

  • File names: lowercase, alphanumeric, hyphens only ([a-z0-9-]+)
  • UUIDs: Standard UUID v4 format
  • Dates: ISO 8601 format with timezone

Security

  • NO executable files in .morph/
  • NO symlinks outside .morph/ directory
  • vault.enc MUST be encrypted (implementation-specific)

Version Compatibility

OpenMorph follows semantic versioning (semver):

  • v0.x.x — Draft, breaking changes possible
  • v1.0.0 — Stable, backward compatible
  • v2.0.0+ — Major version, breaking changes allowed

Tools MUST check openmorph_version in config.yaml and:

  • Compatible: Same major version → proceed
  • Incompatible: Different major version → warn user
  • Unknown: Version not recognized → fail gracefully

Implementation Notes

Git Integration

If .morph/.git/ exists, tools SHOULD:

  • Use git for version control
  • Commit changes atomically
  • Support branching/merging
  • Enable temporal navigation

If .morph/.git/ does NOT exist:

  • Tools MAY initialize git automatically
  • Tools MAY work without git (degraded experience)

Encryption

vault.enc encryption is implementation-defined. Recommended approaches:

  • AES-256 with group symmetric key
  • Per-user encryption with GPG
  • Key management via vault provider (OS keychain, 1Password, etc.)

Extensions

Tools MAY add custom directories/files, but MUST:

  • Prefix with tool name: .morph/.toolname/
  • NOT conflict with reserved names
  • Document extensions clearly

Example: Morphee.app caches data in .morph/.morphee/ (not part of spec).


Reference Implementation

Morphee.app is the reference implementation of OpenMorph v0.1.0.

Repository: github.com/morphee/morphee-beta (private during development)


Last Updated: 2026-02-16