The Memory: Self-Learning Memory System
This skill teaches the methodology for persistent preference learning across sessions. The Memory enables STUDIO to remember user preferences, project conventions, and technical constraints without requiring a database.
The Core Philosophy
"What is written shall be remembered. What is remembered shall guide."
Most AI assistants suffer from session amnesia - they learn preferences during a session only to forget them completely the next time. The Memory addresses this through file-based long-term memory.
Traditional Approach: The Memory Approach:
────────────────────── ──────────────────────
Session 1: Learn preference Session 1: Learn preference
Session 2: Forget, relearn ↓ Write to rules/
Session 3: Forget, relearn Session 2: Read rules, apply
↑________| ↓ No relearning
(amnesia loop) Session N: Read rules, apply
(persistent memory)
The Two Operations
The Memory performs exactly two operations:
1. Context Injection (Reading)
Before any agent work begins, The Memory:
- •Detects relevant domains from the task goal
- •Reads the global rules and domain-specific rules
- •Injects these rules into the agent's working context
- •Enforces that rules are treated as mandatory preferences
2. Learning Loop (Writing)
After user feedback occurs, The Memory:
- •Detects a learning trigger (rejection, correction, explicit teaching)
- •Prompts the user to confirm if this is a permanent preference
- •Classifies which domain the rule belongs to
- •Writes the rule to the appropriate file
The Rules Directory
All preferences are stored in studio/rules/ as human-readable Markdown:
studio/rules/ ├── global.md Project-wide patterns, tone, conventions ├── frontend.md UI/UX preferences, component patterns ├── backend.md Architecture, API, data patterns ├── testing.md QA requirements, coverage rules ├── security.md Security constraints, auth patterns ├── devops.md Deployment, infrastructure preferences └── .memory-meta.json Metadata and history
Why Markdown?
Human-Readable: Users can read, edit, and understand their rules directly Version Controllable: Rules can be committed to git and shared across teams No Dependencies: No database, no external services, just files Debuggable: When something goes wrong, users can inspect the rules
Rule File Format
Each domain file follows a consistent structure:
# Frontend Rules > Last updated: 2025-01-31T14:30:22Z > Rule count: 5 ## Component Patterns - Use functional components with hooks exclusively - Prefer composition over inheritance for reuse ## State Management - Use React Query for server state - Use Zustand for client state only ## Styling - Use Tailwind CSS; no CSS modules or inline styles
Domain Detection
The Memory automatically detects which domains are relevant based on goal keywords:
Detection Matrix
| Domain | Signal Keywords |
|---|---|
| Frontend | react, vue, component, ui, ux, css, styling, view, jsx, tsx, tailwind |
| Backend | api, database, service, model, controller, schema, endpoint, rest, graphql |
| Testing | test, spec, coverage, mock, jest, pytest, e2e, integration |
| Security | auth, token, jwt, permission, encryption, cors, password, credential |
| DevOps | deploy, docker, ci/cd, pipeline, kubernetes, aws, terraform |
Detection Examples
Goal: "Create a React component for user profile" Detected: frontend Goal: "Add JWT authentication to the API" Detected: backend, security Goal: "Build user registration with tests" Detected: frontend, backend, testing
Context Injection Protocol
When injecting rules into agent context:
1. Read Rules
# Always read global rules cat studio/rules/global.md # Read detected domain rules cat studio/rules/frontend.md cat studio/rules/backend.md
2. Build Injection Block
═══════════════════════════════════════════════════════════════════════════════
MANDATORY USER PREFERENCES
(From The Memory's Memory)
═══════════════════════════════════════════════════════════════════════════════
## Global Rules
- Use TypeScript strict mode for all files
- Prefer explicit types over inference
## Frontend Rules
- Use functional components with hooks
- Use Tailwind CSS exclusively
═══════════════════════════════════════════════════════════════════════════════
IMPORTANT: These rules are NON-NEGOTIABLE. They represent user preferences
learned from previous sessions. Always follow these rules unless the user
explicitly overrides them for this specific task.
═══════════════════════════════════════════════════════════════════════════════
3. Acknowledge to User
[Memory] Loaded 4 global rules + 3 frontend rules
Learning Triggers
The Memory activates learning when it detects:
Trigger 1: User Rejects Proposal
When the Verifier returns UNSTABLE or FAILED and the user provides feedback:
[Verifier] Verdict: UNSTABLE - Component uses class-based pattern
[Memory] You indicated a preference. Is this a permanent rule?
"Use functional components instead of class components"
[y/N]:
Trigger 2: User Manually Edits Output
When a user edits a file that was just generated:
[Memory] Change detected in src/components/Profile.tsx You changed: class ProfileComponent extends React.Component To: function Profile(): JSX.Element Is this a new permanent rule? [y/N]:
Trigger 3: Explicit Language
When user uses teaching language:
| Phrase | Interpretation |
|---|---|
| "Always use X" | Add rule: "Use X for [context]" |
| "Never do Y" | Add rule: "Avoid Y; prefer [alternative]" |
| "I prefer X over Y" | Add rule: "Prefer X over Y" |
| "We use X here" | Add rule: "Use X for [purpose]" |
| "Remember this" | Prompt for rule specification |
Trigger 4: Explicit Teaching
When user says "remember" or "add rule":
User: Remember that we always use Prisma for database access
[Memory] Got it. Adding to backend rules:
"Use Prisma for all database access"
Category? [1] Data Layer [2] General [3] Other:
The Learning Loop Flow
┌─────────────────────────────────────────────────────────────────┐
│ 📜 THE MEMORY - LEARNING LOOP │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [Memory] Change detected. Is this a new permanent rule? │
│ │
│ Context: You changed `useState` to `useReducer` in │
│ UserProfile.tsx │
│ │
│ [y] Yes, remember this [n] No, one-time change │
│ │
└─────────────────────────────────────────────────────────────────┘
│
│ If 'Y'
▼
┌─────────────────────────────────────────────────────────────────┐
│ [Memory] Which domain does this rule belong to? │
│ │
│ [1] Global (all code) [4] Security │
│ [2] Frontend [5] DevOps │
│ [3] Backend [6] Testing │
│ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ [Memory] Please dememory this rule concisely: │
│ │
│ > Use useReducer instead of useState for complex state │
│ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ [Memory] ✓ Rule added to frontend.md │
│ │
│ "Use useReducer instead of useState for complex state" │
│ │
│ This preference will be applied to all future tasks. │
│ │
└─────────────────────────────────────────────────────────────────┘
Rule Writing Guidelines
When writing rules, follow these principles:
Be Concise
Bad: "When creating React components you should always make sure
to use functional components with hooks instead of the older
class-based component pattern because..."
Good: "Use functional components with hooks; avoid class components"
Be Specific
Bad: "Use good patterns" Good: "Use repository pattern for data access layer"
Be Actionable
Bad: "Performance matters" Good: "Use React.memo for components receiving stable props"
Include Context
Bad: "Use Prisma" Good: "Use Prisma for database access; avoid raw SQL queries"
Rule Precedence
When rules potentially conflict:
- •Domain-specific beats global for that domain's work
- •More specific beats less specific in same domain
- •User override beats stored rule for current task only
- •Newer rules beat older rules if directly contradictory
Example
# Global Rules - Use explicit return types on functions # Frontend Rules - Infer return types for simple component functions
For a frontend component, the frontend rule applies (infer types). For a backend service, the global rule applies (explicit types).
Override Syntax
Users can override rules for a specific task:
/task:ignore-rules Create a quick prototype component [Memory] Rules suspended for this task only
Or inline:
User: Create a component [override: can use inline styles for this one]
Metadata Tracking
The .memory-meta.json tracks:
- •Version: Schema version for migrations
- •Created/Modified: Timestamps for auditing
- •Rule Counts: Per-domain counts for quick reference
- •History: Audit trail of all rule changes
History Entry
{
"timestamp": "2025-01-31T14:30:22Z",
"domain": "frontend",
"action": "add",
"rule": "Use useReducer for complex state",
"category": "State Management",
"task_id": "task_20250131_143022",
"trigger": "user_correction"
}
Integration with Agents
Each STUDIO agent must:
- •Check for Memory rules before beginning work
- •Acknowledge loaded rules in output
- •Follow rules as mandatory unless overridden
- •Prompt for learning after significant corrections
Agent Integration Code
## Before You Begin 1. Check if `studio/rules/` exists 2. Detect relevant domains from task 3. Read global.md + detected domain files 4. If rules found, prepend to working context 5. Acknowledge: "[Memory] Loaded X global + Y domain rules"
The Memory Color
The Memory uses Magenta for all output. Use the output.sh script:
# Display memory messages
"${CLAUDE_PLUGIN_ROOT}/scripts/output.sh" agent memory "Loaded 5 global rules + 3 frontend rules"
"${CLAUDE_PLUGIN_ROOT}/scripts/output.sh" agent memory "Change detected. Is this a new permanent rule?"
"${CLAUDE_PLUGIN_ROOT}/scripts/output.sh" agent memory "Rule added to frontend.md"
Shell Utilities
The scripts/memory.sh provides command-line access. Use the plugin root path and set STUDIO_DIR to point to the local rules directory:
# Initialize rules directory
STUDIO_DIR=studio "${CLAUDE_PLUGIN_ROOT}/scripts/memory.sh" init
# Add a rule
STUDIO_DIR=studio "${CLAUDE_PLUGIN_ROOT}/scripts/memory.sh" add frontend "Use Tailwind" "Styling"
# List all rules
STUDIO_DIR=studio "${CLAUDE_PLUGIN_ROOT}/scripts/memory.sh" list
# Generate injection block
STUDIO_DIR=studio "${CLAUDE_PLUGIN_ROOT}/scripts/memory.sh" inject frontend backend
# Detect domains from goal
STUDIO_DIR=studio "${CLAUDE_PLUGIN_ROOT}/scripts/memory.sh" detect "Create a React login form"
# View history
STUDIO_DIR=studio "${CLAUDE_PLUGIN_ROOT}/scripts/memory.sh" history 10
Common Patterns
Pattern 1: Technology Preferences
## Technology Stack - Use TypeScript for all code - Use Prisma for database access - Use React Query for server state - Use Tailwind CSS for styling
Pattern 2: Code Style
## Code Style - Use explicit return types on exported functions - Prefer named exports over default exports - Use descriptive variable names; avoid abbreviations
Pattern 3: Architecture Rules
## Architecture - Use repository pattern for data access - Keep controllers thin; logic in services - One file per component/class
Pattern 4: Quality Requirements
## Quality - All exported functions must have JSDoc comments - Test coverage minimum 80% for new code - No console.log in production code
Verification Questions
Before adding a rule, consider:
- • Is this preference consistent across the project?
- • Would this rule help future sessions?
- • Is the rule specific enough to be actionable?
- • Does this conflict with existing rules?
- • Is this a project convention or personal preference?
If all answers are "yes" or "project convention," the rule should be recorded.
"The Memory remembers so you don't have to repeat." - The Memory Principle