Skip to content

Memory Layer

The Memory Layer preserves context across sessions, enabling AI agents and humans to resume work without losing track.

Without memory:

  • “What was I working on?”
  • “Why did I make this decision?”
  • “Where did I leave off?”

With memory:

  • Automatic checkpoints capture state
  • Session context is recoverable
  • Decisions are documented
  • Discoveries become WUs
Session Start
     |
mem:ready (check pending work)
     |
Work (changes, decisions)
     |
mem:checkpoint (periodic save)
     |
Session End
     |
Next Session: mem:ready (resume)
pnpm mem:init

Creates .lumenflow/memory/ with memory.jsonl and config.yaml.

pnpm mem:start --wu WU-001

Start a new memory session linked to a WU.

pnpm mem:ready --wu WU-001

Shows what’s in progress and any pending decisions.

pnpm mem:checkpoint --wu WU-042

Saves current session state:

  • Active WU
  • Recent changes
  • Decision context
pnpm mem:signal "Completed validation logic" --wu WU-001

Send a progress signal that other sessions can see.

pnpm mem:inbox

Check for signals from other sessions or agents.

pnpm mem:create "Found a bug in auth flow" --type discovery --wu WU-001
pnpm mem:create "API changed" --discovered-from mem-abc123 --tags api,breaking

Create a memory node with provenance tracking:

FlagDescription
--typesession, discovery, checkpoint, note, summary
--discovered-fromParent node ID for provenance chain
--wuLink to WU
--sessionLink to session
--tagsComma-separated tags
--priorityP0-P3
pnpm mem:triage --list                     # List open discoveries
pnpm mem:triage --promote mem-abc --lane "Framework: Core" --title "Fix auth bug"
pnpm mem:triage --archive mem-def --reason "Duplicate of WU-100"

Review discovery nodes and either:

  • Promote to a new WU
  • Archive if not actionable
pnpm mem:summarize --wu WU-001
pnpm mem:summarize --wu WU-001 --dry-run

Roll up older memory nodes into summary nodes. Use when context is getting large.

pnpm mem:cleanup                      # Cleanup based on lifecycle policy
pnpm mem:cleanup --dry-run            # Preview without changes
pnpm mem:cleanup --ttl 30d            # Remove nodes older than 30 days
pnpm mem:cleanup --session-id <uuid>  # Close specific session

Prune memory nodes based on lifecycle policy.

.lumenflow/
├── memory/
│   ├── memory.jsonl
│   ├── config.yaml
│   └── signals.jsonl
├── sessions/
│   └── current.json
├── stamps/
│   └── WU-041.done
└── locks/
    └── core.lock

Each session captures:

{
  "session_id": "abc123",
  "started_at": "2026-01-18T10:00:00Z",
  "active_wu": "WU-042",
  "lane": "Framework: Core",
  "files_touched": ["src/utils/validation.ts", "src/components/LoginForm.tsx"],
  "decisions": [
    {
      "question": "Use Zod or custom validation?",
      "answer": "Zod - better TypeScript integration",
      "timestamp": "2026-01-18T10:15:00Z"
    }
  ]
}

A common scenario: one agent works on a WU, hits context limits, and hands off to a fresh agent.

Agent 1 (hitting context limits):

# Agent 1 is running low on context
# Save state before ending session
pnpm mem:checkpoint --wu WU-042

# Signal where we left off
pnpm mem:signal "Tests written for auth flow, starting integration tests" --wu WU-042

# Document the key decision made
pnpm mem:create "Decision: Token refresh uses silent retry queue" \
  --type note \
  --wu WU-042 \
  --tags decision,auth \
  --priority P2

Agent 2 (resuming):

# New agent checks what's pending
pnpm mem:ready --wu WU-042

# Output:
# Session: abc123
# WU: WU-042 (in_progress)
# Lane: Framework: Core
# Last signal: "Tests written for auth flow, starting integration tests"
# Files touched:
#   - src/utils/auth.ts
#   - src/components/LoginForm.tsx
#   - tests/auth.test.ts
#
# Pending decisions: 1
#   - Token refresh: Silent refresh with retry queue

# Resume work with full context
cd worktrees/framework-core-wu-042

Finding bugs or improvements during work and converting them to WUs.

# During WU-042, agent finds a bug in unrelated code
pnpm mem:create "Found race condition in session manager" \
  --type discovery \
  --wu WU-042 \
  --priority P1 \
  --tags bug,auth,race-condition

# Later, triage the discovery
pnpm mem:triage --list
# Output:
# mem-def456: Found race condition in session manager
#   Type: discovery
#   Priority: P1
#   Discovered during: WU-042
#   Tags: bug, auth, race-condition

# Promote to a new WU
pnpm mem:triage --promote mem-def456 \
  --lane "Framework: Core" \
  --title "BUG: Fix race condition in session manager"

# Creates WU-043 with:
# - Type: bug
# - Priority: P1
# - discovered_in: WU-042
# - Linked to memory node for context

For discovery or research WUs that span multiple days.

# Day 1: Start research
pnpm mem:start --wu WU-050

# Make progress, save decisions
pnpm mem:create "Decision: OpenTelemetry + Grafana" \
  --type note \
  --wu WU-050 \
  --tags observability,decision

pnpm mem:signal "Evaluated 3 platforms, OTel winning" --wu WU-050
pnpm mem:checkpoint --wu WU-050

# Day 2: Continue
pnpm mem:ready --wu WU-050
# Shows: Last checkpoint from Day 1, decision context preserved

# Add more findings
pnpm mem:create "OTel has better trace propagation" \
  --type note \
  --wu WU-050 \
  --tags observability,decision

# Day 3: Wrap up
pnpm mem:summarize --wu WU-050
# Creates summary node:
# "Research on observability platforms. Decision: OpenTelemetry + Grafana.
#  Key factors: vendor neutral, trace propagation, ecosystem maturity."

Multiple agents working on related WUs in different lanes.

# Agent A working on Core (WU-100)
pnpm mem:signal "New validation port added: ValidationService" --wu WU-100

# Agent B working on UI (WU-101) checks inbox
pnpm mem:inbox
# Output:
# From: session-abc (WU-100, Framework: Core)
#   Signal: "New validation port added: ValidationService"
#   Time: 5 minutes ago

# Agent B can now use the new port
# No need for synchronous coordination

Example 5: Checkpoint Before Context Limit

Section titled “Example 5: Checkpoint Before Context Limit”
# Agent detects high context usage
# Before spawning new agent:

# 1. Checkpoint current state
pnpm mem:checkpoint

# 2. Signal detailed progress
pnpm mem:signal "Auth flow 80% complete. Remaining: integration tests for refresh token. Files ready: src/auth/*.ts" --wu WU-042

# 3. Document any in-progress decisions
pnpm mem:create "Decision pending: error handling strategy (throw vs Result type)" \
  --type note \
  --wu WU-042 \
  --tags decision,pending

# 4. Now safe to spawn fresh agent
# New agent will have full context via mem:ready

For AI agents, memory is critical:

# Agent starts session
pnpm mem:start --wu WU-042

# Agent checks what's pending
pnpm mem:ready --wu WU-042

# During work, agent signals progress
pnpm mem:signal "Completed validation logic, starting tests" --wu WU-042

# Agent creates checkpoint before pause
pnpm mem:checkpoint --wu WU-042

# Later, agent resumes
pnpm mem:ready --wu WU-042
# Shows: "WU-042 in progress, last: 'starting tests'"

Capture why decisions were made:

pnpm mem:create "Decision: use Zod for validation" \
  --type note \
  --wu WU-042 \
  --tags decision

This creates an audit trail for future reference.

# workspace.yaml
memory:
  checkpoint_interval: 30 # minutes
  max_checkpoints: 10 # per WU
  auto_checkpoint: true # on significant changes

For sub-agent coordination, configure when agents must signal their progress:

# workspace.yaml
memory:
  progress_signals:
    enabled: true # When true, signals become mandatory
    frequency: 25 # Signal every N tool calls (0 = disabled)
    on_milestone: true # Signal after each acceptance criterion
    on_tests_pass: true # Signal when tests first pass
    before_gates: true # Signal before running gates
    on_blocked: true # Signal when blocked or waiting
    auto_checkpoint: false # Create checkpoint with each signal
FieldDefaultDescription
enabledfalseWhen true, signals are required at trigger points
frequency0Tool calls between auto-signals (0 = no frequency)
on_milestonetrueSignal after completing each acceptance criterion
on_tests_passtrueSignal when tests first pass
before_gatestrueSignal before running quality gates
on_blockedtrueSignal when blocked or waiting on dependencies
auto_checkpointfalseAutomatically create checkpoint with each signal

When to use:

  • Parallel WUs: When multiple agents work on related WUs, signals prevent redundant work
  • Long-running tasks: For complex WUs, signals provide progress visibility
  • Orchestrator patterns: Parent agents can monitor child progress without context overhead

When configured, LumenFlow can create checkpoints automatically via Claude Code hooks, removing the need for manual mem:checkpoint calls during active work.

PostToolUse hook fires
     |
Counter increments (per-WU)
     |
Counter reaches interval?
     ├─ YES → Create checkpoint (backgrounded)
     └─ NO  → Continue
SubagentStop hook fires
     |
Always create checkpoint (sub-agent completed work)

The PostToolUse hook tracks a per-WU counter in .lumenflow/state/hook-counters/<WU_ID>.json and creates a checkpoint when the counter reaches the configured interval (default: 30 tool calls). The SubagentStop hook always checkpoints because a sub-agent finishing represents a natural milestone.

Both checkpoint writes are backgrounded in a defensive subshell so the hook returns quickly and does not block the agent.

wu:done can optionally verify that at least one checkpoint exists for the WU:

ModeBehavior
offNo checkpoint check
warnPrint a warning if no checkpoints (default)
blockBlock wu:done until a checkpoint exists

On completion, wu:done cleans up the per-WU hook counter file.

# workspace.yaml
memory:
  enforcement:
    auto_checkpoint:
      enabled: true # Generate PostToolUse + SubagentStop hooks
      interval_tool_calls: 30 # Checkpoint every N tool calls
    require_checkpoint_for_done: warn # off | warn | block

After changing configuration, regenerate hooks:

pnpm lumenflow:integrate --client claude-code

Previously, marking a signal as read required rewriting the entire signals.jsonl file. When multiple agents ran concurrently, this caused lost updates (one agent’s read-mark overwritten by another).

Signal receipts solve this by using append-only writes:

  • Reading signals (mem:inbox): Appends receipt entries instead of modifying the original signal
  • Loading signals (loadSignals): Merges effective read state from inline read: true (legacy) and appended receipts
  • Cleanup (signal:cleanup): Receipt-aware; removes orphaned receipts for deleted signals
  • No-mark mode (mem:inbox --no-mark): Read signals without generating receipts

Existing inline read: true flags in signals.jsonl are honored. All new read-marking uses the receipt mechanism. No migration is required.

Memory nodes accumulate over time. Without cleanup, stale nodes consume storage and slow context loading. The decay lifecycle provides automated archival based on a time-based relevance score.

Each memory node receives a decay score based on its age and the configured half-life:

score = 2^(-age_in_days / half_life_days)
  • A node created today has score 1.0
  • After half_life_days (default: 30), score drops to 0.5
  • After two half-lives (60 days), score drops to 0.25

Nodes with a score below the threshold (default: 0.1) are archived.

TriggerWhen decay runs
on_doneAutomatically during wu:done (after gates pass)
manualOnly via pnpm mem:cleanup (explicit operator control)

When trigger: on_done, decay archival runs as part of the wu:done lifecycle. Errors never block completion (fail-open). When decay is disabled, existing wu:done behavior is unchanged.

# workspace.yaml
memory:
  decay:
    enabled: true # Enable decay-based archival
    threshold: 0.1 # Archive nodes below this score (0-1)
    half_life_days: 30 # Days until relevance halves
    trigger: on_done # on_done | manual

Manual cleanup remains available regardless of configuration:

pnpm mem:cleanup              # Run cleanup
pnpm mem:cleanup --dry-run    # Preview without changes
  1. Run mem:ready --wu <WU-ID> at session start
  2. Create checkpoints before long breaks
  3. Log non-obvious decisions
  4. Triage discoveries weekly
  1. Always start with mem:start --wu <WU-ID>
  2. Signal progress frequently
  3. Checkpoint before context limits
  4. Use discoveries for out-of-scope findings

Create a checkpoint when:

  • Completing a significant milestone
  • Before switching to a different task
  • Before a long break or end of day
  • When context usage is high
  • Before spawning a sub-agent

Use discoveries for:

  • Bugs found in unrelated code
  • Improvement ideas outside current scope
  • Technical debt observations
  • Questions for later research

Do NOT use discoveries for:

  • Things you’ll fix in the current WU
  • Obvious next steps already in backlog
  • Personal notes (use --type note instead)

Lifecycle Stages

Active (during WU work)

  • Checkpoints created automatically (if enforcement enabled) or manually
  • Signals sent on milestones with append-only receipts
  • Decisions logged as made

Decay (after WU completion, if memory.decay.enabled)

  • Decay scores computed from node age and half-life
  • Nodes below threshold are archived automatically
  • Triggered by wu:done (fail-open) or manual cleanup

Archive (after WU completion)

  • Checkpoints summarized
  • Discoveries triaged
  • Session closed

Cleanup (periodic maintenance)

  • Old checkpoints pruned via TTL
  • Archived sessions cleaned
  • Orphaned signal receipts removed
  • Summary nodes preserved