claude-configs/skills/cognitive-memory/SCHEMA.md
Cal Corum a2d18ef0c2 Cognitive Memory v3.0: rich edges, hybrid embeddings, MCP server
Add first-class edge files in graph/edges/ with bidirectional frontmatter
refs, hybrid Ollama/OpenAI embedding providers with fallback chain, and
native MCP server (18 tools) for direct Claude Code integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 14:11:18 -06:00

422 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Cognitive Memory Schema
## Memory File Format
Each memory is a markdown file with YAML frontmatter. Filename format: `{slugified-title}-{6char-uuid}.md`
Example: `graph/solutions/fixed-redis-connection-timeouts-a1b2c3.md`
```markdown
---
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
type: solution
title: "Fixed Redis connection timeouts"
tags: [redis, timeout, production, homelab]
importance: 0.8
confidence: 0.8
created: 2025-12-06T16:25:58+00:00
updated: 2025-12-06T16:25:58+00:00
relations:
- target: def789ab-...
type: SOLVES
direction: outgoing
strength: 0.8
context: "Keepalive prevents idle disconnections"
---
Added socket_keepalive=True and socket_timeout=300 to Redis connection configuration.
```
### Frontmatter Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | string (UUID) | Yes | Unique identifier |
| `type` | string | Yes | Memory type (see below) |
| `title` | string (quoted) | Yes | Descriptive title |
| `tags` | list[string] | No | Categorization tags (inline YAML list) |
| `importance` | float 0.0-1.0 | Yes | Importance score |
| `confidence` | float 0.0-1.0 | No | Confidence score (default 0.8) |
| `steps` | list[string] | No | Ordered steps (procedure type only) |
| `preconditions` | list[string] | No | Required preconditions (procedure type only) |
| `postconditions` | list[string] | No | Expected postconditions (procedure type only) |
| `created` | string (ISO 8601) | Yes | Creation timestamp |
| `updated` | string (ISO 8601) | Yes | Last update timestamp |
| `relations` | list[Relation] | No | Relationships to other memories |
### Memory Types
| Type | Directory | Description |
|------|-----------|-------------|
| `solution` | `graph/solutions/` | Fix or resolution to a problem |
| `fix` | `graph/fixes/` | Code-level fix or patch |
| `decision` | `graph/decisions/` | Architecture or design choice |
| `configuration` | `graph/configurations/` | Working configuration |
| `problem` | `graph/problems/` | Issue or challenge |
| `workflow` | `graph/workflows/` | Process or sequence |
| `code_pattern` | `graph/code-patterns/` | Reusable code pattern |
| `error` | `graph/errors/` | Specific error condition |
| `general` | `graph/general/` | General learning |
| `procedure` | `graph/procedures/` | Structured workflow with steps/preconditions/postconditions |
| `insight` | `graph/insights/` | Cross-cutting pattern from reflection cycles |
### Relation Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `target` | string (UUID) | Yes | Target memory ID |
| `type` | string | Yes | Relationship type |
| `direction` | string | Yes | `outgoing` or `incoming` |
| `strength` | float 0.0-1.0 | No | Relationship strength |
| `context` | string (quoted) | No | Context description |
| `edge_id` | string (UUID) | No | Link to edge file for rich description |
### Relationship Types
`SOLVES`, `CAUSES`, `BUILDS_ON`, `ALTERNATIVE_TO`, `REQUIRES`, `FOLLOWS`, `RELATED_TO`
### Edge File Format
Edge files live in `graph/edges/` with full descriptions. Filename: `{from-slug}--{TYPE}--{to-slug}-{6char}.md`
```markdown
---
id: <uuid>
type: SOLVES
from_id: <uuid>
from_title: "Fixed Redis connection timeouts"
to_id: <uuid>
to_title: "Redis connection drops under load"
strength: 0.8
created: <iso>
updated: <iso>
---
The keepalive fix directly resolves the idle disconnection problem because...
```
Edge frontmatter fields: id, type, from_id, from_title, to_id, to_title, strength, created, updated.
---
## _index.json
Computed index for fast lookups. Rebuilt by `reindex` command. **Source of truth: markdown files.**
```json
{
"version": 2,
"updated": "2025-12-13T10:30:00+00:00",
"count": 313,
"edges": {
"<edge-uuid>": {
"type": "SOLVES",
"from_id": "<uuid>",
"to_id": "<uuid>",
"strength": 0.8,
"path": "graph/edges/fixed-redis--SOLVES--redis-drops-a1b2c3.md"
}
},
"entries": {
"a1b2c3d4-e5f6-7890-abcd-ef1234567890": {
"title": "Fixed Redis connection timeouts",
"type": "solution",
"tags": ["redis", "timeout", "production", "homelab"],
"importance": 0.8,
"confidence": 0.8,
"created": "2025-12-06T16:25:58+00:00",
"updated": "2025-12-06T16:25:58+00:00",
"path": "graph/solutions/fixed-redis-connection-timeouts-a1b2c3.md",
"relations": [
{
"target": "def789ab-...",
"type": "SOLVES",
"direction": "outgoing",
"strength": 0.8,
"context": "Keepalive prevents idle disconnections"
}
]
}
}
}
```
**Notes:**
- `_index.json` is gitignored (derived data)
- Can be regenerated at any time with `python client.py reindex`
- Entries mirror frontmatter fields for fast search without opening files
---
## _state.json
Mutable runtime state tracking access patterns and decay scores. **Kept separate from frontmatter to avoid churning git history with access-count updates.**
```json
{
"version": 1,
"updated": "2025-12-13T10:30:00+00:00",
"entries": {
"a1b2c3d4-e5f6-7890-abcd-ef1234567890": {
"access_count": 5,
"last_accessed": "2025-12-13T10:15:00+00:00",
"decay_score": 0.75
}
}
}
```
**Notes:**
- `_state.json` is gitignored (mutable, session-specific data)
- Access count increments on `get` operations
- Decay scores recalculated by `python client.py decay`
---
## Episode File Format
Daily markdown files in `episodes/` directory. Append-only, one file per day.
Filename format: `YYYY-MM-DD.md`
```markdown
# 2025-12-13
## 10:30 - Fixed Discord bot reconnection
- **Type:** fix
- **Tags:** major-domo, discord, python
- **Memory:** [discord-bot-reconnection](../graph/fixes/discord-bot-reconnection-a1b2c3.md)
- **Summary:** Implemented exponential backoff for reconnections
## 11:15 - Chose websocket over polling
- **Type:** decision
- **Tags:** major-domo, architecture
- **Memory:** [websocket-over-polling](../graph/decisions/websocket-over-polling-d4e5f6.md)
- **Summary:** WebSocket provides lower latency for real-time game state updates
```
**Notes:**
- Episodes are chronological session logs
- Entries link back to graph memories when available
- Append-only (never edited, only appended)
- Useful for reflection and session review
---
## CORE.md Format
Auto-generated summary of highest-relevance memories. Loaded into system prompt at session start.
```markdown
# Memory Core (auto-generated)
> Last updated: 2025-12-13 | Active memories: 180/313 | Next refresh: daily (systemd timer)
## Critical Solutions
- [title](relative/path.md) (tag1, tag2)
## Active Decisions
- [title](relative/path.md) (tag1, tag2)
## Key Fixes
- [title](relative/path.md) (tag1, tag2)
## Configurations
- [title](relative/path.md) (tag1, tag2)
## Patterns & Workflows
- [title](relative/path.md) (tag1, tag2)
```
**Notes:**
- Budget: ~3K tokens (~12,000 chars)
- Regenerated by `python client.py core`
- Memories included based on decay_score (must be >= 0.2)
- Grouped by type category, sorted by decay score within each group
- Capped at 15 entries per section
---
## Decay Model
```
decay_score = importance × e^(-λ × days_since_access) × log2(access_count + 1) × type_weight
```
Where:
- `λ = 0.03` (half-life ~23 days)
- `days_since_access` = days since `_state.json` `last_accessed`
- `access_count` = from `_state.json`
- `type_weight` = per-type multiplier (see below)
- For `access_count == 0`, `usage_factor = 0.5` (new memories start at half strength)
### Type Weights
| Type | Weight |
|------|--------|
| `procedure` | 1.4 |
| `decision` | 1.3 |
| `insight` | 1.25 |
| `solution` | 1.2 |
| `code_pattern` | 1.1 |
| `configuration` | 1.1 |
| `fix` | 1.0 |
| `workflow` | 1.0 |
| `problem` | 0.9 |
| `error` | 0.8 |
| `general` | 0.8 |
### Thresholds
| Range | Status |
|-------|--------|
| 0.5+ | Active |
| 0.2-0.5 | Fading |
| 0.05-0.2 | Dormant |
| <0.05 | Archived |
### Vault
Pinned memories (in `vault/`) have a decay score of 999.0 (effectively infinite).
---
## REFLECTION.md Format
Auto-generated summary of memory themes, cross-project patterns, and access statistics. Generated by `python client.py reflection` or automatically during `reflect`.
```markdown
# Reflection Summary (auto-generated)
> Last updated: 2026-02-13 | Last reflection: 2026-02-13 | Total reflections: 2
## Themes
Top tag co-occurrences revealing recurring themes:
- **fix + python**: 52 memories ("Fix S3 upload...", "fix_cardpositions.py...")
## Cross-Project Patterns
Tags that span multiple projects:
- **fix**: appears in major-domo (38), vagabond-rpg (22), paper-dynasty (19)
## Most Accessed
Top 10 memories by access count:
1. [Title](graph/type/filename.md) - N accesses
## Recent Insights
Insight-type memories:
- [Title](graph/insights/filename.md) - content preview...
## Consolidation History
- Total merges performed: 0
```
**Sections:**
1. **Themes** - Top 8 tag co-occurrences with example memory titles (top 3)
2. **Cross-Project Patterns** - Tags spanning 2+ known projects with per-project counts
3. **Most Accessed** - Top 10 memories ranked by `_state.json` access_count
4. **Recent Insights** - Latest insight-type memories with 80-char content preview
5. **Consolidation History** - Merge count from episode files
**Known projects:** major-domo, paper-dynasty, homelab, vagabond-rpg, foundryvtt, strat-gameplay-webapp
---
## _embeddings.json
Ollama embedding vectors for semantic search. **Gitignored** (derived, regenerated by `python client.py embed`).
```json
{
"model": "nomic-embed-text",
"updated": "2026-02-13T12:00:00+00:00",
"entries": {
"a1b2c3d4-e5f6-7890-abcd-ef1234567890": [0.0123, -0.0456, ...],
...
}
}
```
**Notes:**
- Vectors generated from `"{title}. {content_preview}"` per memory
- Uses Ollama `nomic-embed-text` model at `http://localhost:11434`
- Batched in groups of 50, 300-second timeout for first-time model pull
- Falls back gracefully if Ollama is unavailable
- Must be refreshed after adding new memories (`python client.py embed`)
---
## Procedure Memory Format
Procedure-type memories have additional frontmatter fields for structured steps:
```markdown
---
id: a1b2c3d4-...
type: procedure
title: "Deploy Major Domo to production"
tags: [major-domo, deploy, docker]
importance: 0.8
confidence: 0.8
steps:
- "Run tests"
- "Build docker image"
- "Push to registry"
- "Deploy to LXC"
preconditions:
- "All tests pass"
- "On main branch"
postconditions:
- "Service healthy"
- "Discord bot online"
created: 2026-02-13T12:00:00+00:00
updated: 2026-02-13T12:00:00+00:00
---
Standard deploy workflow for the Major Domo Discord bot.
```
**Notes:**
- `steps`, `preconditions`, `postconditions` are optional lists
- Values are quoted YAML strings in the list
- Procedures have the highest decay weight (1.4) - they persist longest
---
## _config.json
Embedding provider configuration. **Gitignored** (may contain API key).
```json
{
"embedding_provider": "ollama",
"openai_api_key": null,
"ollama_model": "nomic-embed-text",
"openai_model": "text-embedding-3-small"
}
```
**Notes:**
- `embedding_provider`: `"ollama"` (default) or `"openai"`
- Provider changes trigger automatic re-embedding (dimension mismatch safety: ollama=768, openai=1536)
- Configure via: `claude-memory config --provider openai --openai-key "sk-..."`
---
## .gitignore
```
_state.json
_index.json
_embeddings.json
_config.json
```
Only markdown files (memories, CORE.md, REFLECTION.md, episodes) are git-tracked. Index, state, embeddings, and config are derived/mutable data that can be regenerated.
---
*Schema version: 3.0.0 | Created: 2026-02-13 | Updated: 2026-02-19*