Skip to content

ALP Specification — Memory Model

Version: 80.0.0 Status: Stable


1. Memory Model Overview

mermaid
flowchart TD
    Memory[Memory System] --> Types[Memory Types]
    Types --> Project[project]
    Types --> Architecture[architecture]
    Types --> Feature[feature]
    Types --> Task[task]
    Types --> Decision[decision]
    Types --> Error[error]
    Types --> Agent[agent]
    Types --> Knowledge[knowledge]
    Types --> Conversation[conversation]
    Types --> Context[context]
    
    Memory --> Scoping[Scoping]
    Scoping --> Global[Global]
    Scoping --> Scoped[Scoped to Object]
    
    Memory --> TTL[TTL Expiry]

2. Overview

ALP Memory is a persistent, scoped key-value storage system that allows agents to retain knowledge across sessions. Memory eliminates the need for agents to re-derive information they have already discovered.

Core principle: An agent should never have to figure out the same thing twice.


2. Memory Types

TypePurposeExample
projectProject-wide knowledge"This project uses npm workspaces"
architectureArchitectural decisions and patterns"We use a layered architecture: API → Service → Repository"
featureFeature-specific knowledge"Auth uses JWT with refresh tokens"
taskTask-specific notes"The login form needs to handle OAuth redirect"
decisionWhy something was decided"Chose PostgreSQL over MongoDB for ACID compliance"
errorKnown bugs, workarounds, gotchas"Prisma migration fails if DB timezone isn't UTC"
agentAgent-specific preferences or state"Agent-frontend prefers functional components"
knowledgeGeneral technical knowledge"Next.js 14 App Router uses server components by default"
conversationKey takeaways from agent interactions"User wants dark mode as default"
contextContextual information for tasks"This component must match the Figma mockup at /designs/login.fig"

3. Memory Entry Structure

Every @memory object has:

FieldTypeRequiredDescription
idStringYesUnique identifier
typeEnumYesOne of the 10 memory types
keyStringYesLookup key (unique within type + scope)
valueStringYesThe stored knowledge
scopeRefNoObject this memory is scoped to (feature, task, etc.)
importanceEnumNocritical, high, medium, low (default: medium)
sourceStringNoWhat created this entry (agent ID or process)
ttlDurationNoTime-to-live before auto-expiry
createdDateTimeNoWhen created
updatedDateTimeNoWhen last updated

4. Memory Storage

Memory is stored in .alp/memory.alp:

!alp-version: 80.0.0

// Project-level memories
@memory
  id: mem-001
  type: project
  key: "package-manager"
  value: "This project uses pnpm, not npm"
  importance: high
  source: "agent-planner"

---

@memory
  id: mem-002
  type: architecture
  key: "api-pattern"
  value: |
    All API routes follow the pattern:
    /api/v1/{resource}
    Controllers → Services → Repositories
    Validation happens at the controller level using Zod schemas.
  importance: critical
  source: "agent-architect"

---

@memory
  id: mem-003
  type: error
  key: "prisma-timezone-bug"
  value: "Prisma migrations fail if DATABASE_TIMEZONE != UTC. Set it in .env."
  scope: -> task-db-setup
  importance: high
  source: "agent-backend"
  ttl: 90d

---

@memory
  id: mem-004
  type: decision
  key: "state-management"
  value: "Using Zustand for client state. Server state via React Query. No Redux."
  scope: -> feat-dashboard
  importance: critical
  source: "agent-architect"

5. Memory Operations

5.1 Write

Agents write memory when they discover something worth remembering:

TriggerMemory TypeExample
Making a decisiondecision"Chose Zustand over Redux"
Encountering an errorerror"Port 3000 conflict with existing process"
Learning about architecturearchitecture"DB uses soft deletes, never hard delete"
Completing a tasktask"Login form uses react-hook-form v7"
User provides informationconversation"User wants SSO support in phase 2"

5.2 Read

Agents read memory when starting work:

1. Load all memory where scope matches current task
2. Load all memory where scope matches current feature
3. Load all memory with type = "project" or type = "architecture"
4. Load all memory with importance = "critical"
5. Filter by relevance to current task context

5.3 Query

Memory can be queried by:

QuerySyntaxExample
By typememory.type == "error"Get all known errors
By scopememory.scope == feat-authGet all auth-related memory
By importancememory.importance == "critical"Get critical knowledge
By keymemory.key == "api-pattern"Get specific entry
By sourcememory.source == "agent-backend"Get backend agent's memories
CombinedType + scopeErrors related to auth feature

5.4 Update

When knowledge changes, agents SHOULD update the existing memory entry rather than creating a new one:

@memory
  id: mem-004
  type: decision
  key: "state-management"
  value: "Using Zustand for client state. Server state via TanStack Query v5. No Redux."
  scope: -> feat-dashboard
  importance: critical
  source: "agent-architect"
  updated: 2026-07-23T10:00:00Z    // Updated

5.5 Delete / Prune

  • Entries with ttl are automatically expired after the duration
  • Agents MAY explicitly delete memory entries that are no longer relevant
  • The prune operation removes all expired entries

6. Memory Scoping Rules

6.1 Scope Hierarchy

Project (global)
  └── Feature
       └── Task

Memory scoped to a task is visible to:

  • That task only

Memory scoped to a feature is visible to:

  • That feature and all its tasks

Memory with no scope (or scoped to project) is visible to:

  • Everything in the project

6.2 Scope Inheritance

When querying memory for a task, an agent receives:

  1. Memory scoped directly to the task
  2. Memory scoped to the task's parent feature
  3. Memory scoped to the project (no scope / scope = project)
  4. Memory with importance: critical regardless of scope

6.3 Scope Conflicts

If two memory entries have the same key at different scopes, the narrower scope wins:

// Project-level
@memory
  type: architecture
  key: "database"
  value: "PostgreSQL"

// Feature-level (narrower scope wins for this feature)
@memory
  type: architecture
  key: "database"
  value: "SQLite for local caching"
  scope: -> feat-offline-mode

7. Memory Best Practices

7.1 When to Create Memory

  • Always after making a non-obvious decision
  • Always after encountering and solving an error
  • Always when user provides project-specific information
  • Consider after learning something about the codebase
  • Consider after discovering a pattern or convention

7.2 When NOT to Create Memory

  • Information already in the @context object
  • Information derivable from the code itself
  • Temporary debugging notes (use ttl if needed)
  • Duplicate of existing memory

7.3 Key Naming Convention

Memory keys SHOULD use kebab-case and be descriptive:

GoodBad
authentication-strategyauth
database-migration-workarounddb-fix
api-rate-limit-configlimits
user-preference-dark-modedm

7.4 Value Quality

Memory values SHOULD be:

  • Complete enough to be useful without additional context
  • Concise enough to not waste context window
  • Actionable — telling the agent what to do, not just what happened
  • Updated when the information changes

8. Memory Limits

To prevent unbounded memory growth:

LimitDefaultDescription
Max entries per project500Total memory entries
Max value length2000 charsLength of a single value
Default TTLNoneEntries persist indefinitely unless TTL set
Max TTL365dMaximum time-to-live

When the entry limit is reached, agents SHOULD:

  1. Prune expired entries
  2. Remove low importance entries
  3. Merge related entries
  4. Archive old entries to a separate file