Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Templates and assets remain in the skill folder. Specify the path via env:
export ENGRAM_SKILL_DIR=skills/engram # or absolute path
bun scripts/init.js
Without ENGRAM_SKILL_DIR, scripts look for assets relative to ../ from their location.
Memory System
Three-layer memory architecture for OpenClaw agents: curated long-term memory (MEMORY.md), structured knowledge graph (life/), and session-isolated daily notes (memory/).
Quick Start
# 1. Install QMD (if not installed)
bun skills/engram/scripts/install-qmd.js
# 2. Initialize everything
bun skills/engram/scripts/init.js
# Add a group session
bun skills/engram/scripts/add-session.js --platform telegram --id 3382546134
# Validate integrity
bun skills/engram/scripts/validate.js
# Migrate to v2 schema
bun skills/engram/scripts/migrate-v2.js --dry-run
Knowledge Graph (main session only): run qmd query "<topic of first user message>" -c life
Extract the main topic/entity from the user's first request and query it
If message is a greeting or vague → defer to QMD Query Triggers below
QMD Query Triggers
Apply during a session (after Full Init). Run qmd query whenever a trigger fires.
Main session only — group chats do not have access to the Knowledge Graph (life/).
🔴 Mandatory Triggers (always run)
Trigger
Condition
Query
First substantive request
User's first non-greeting message in a session
qmd query "<topic>" -c life
Named entity appears
Project, person, or system mentioned for the first time in this session
qmd query "<entity name>" -c life
Decision requested
User asks for advice, recommendation, or "what should I do"
qmd query "<topic>" -c life + check memory/domains/ if relevant
🟡 Situational Triggers (use judgment)
Trigger
Condition
Topic shift
Conversation moves to a clearly different domain (e.g. dev → infra → marketing)
Long session + new subject
>20 messages in session and a new subject appears
"We did this before"
Request that could have history in prior sessions/notes
Contradiction detected
Something the user says conflicts with what you believe you know
How to run
# Combined KG + session memory (recommended)
qmd query "topic" -c life -c openclaw-memory-agent-{id}-main
# KG only (when session memory not relevant)
qmd query "topic" -c life
Use the most specific term you can extract. If multiple entities are relevant, run separate queries.
Daily Notes
Path: memory/agent-{id}/{session}/YYYY-MM-DD.md
Header: # YYYY-MM-DD
Three-Layer Rotation (>1000 lines during heartbeat):
Archive — full file moved to archives/YYYY-MM/ (nothing lost)
Stub — auto-summary (10-20 lines) with line refs to archive and KG links
QMD index — archive indexed for granular search via qmd query
Run rotation AFTER KG Extraction to minimize stub duplication
Knowledge Graph (PARA)
Structured memory in life/ using Projects/Areas/Resources/Archives:
life/
├── projects/<name>/ # Active work (summary.md + items.json)
├── areas/people/<name>/ # People (summary.md + items.json)
├── areas/groups/<name>/ # Groups
├── resources/<topic>/ # Reference material
├── archives/ # Inactive entities
└── index.md # Master entity index
During heartbeats, scan daily notes for durable facts:
Watermark-based incremental parsing: Check for <!-- extracted:L{N}:{timestamp} --> at the end of each daily note. If found, only parse lines after the last watermark. No watermark = parse entire file (backward compatible).
Relationships, milestones, status changes, decisions, preferences
Write to entity items.json with confidence and abstraction level
Update summary.md for new Hot facts
Create new entities when creation rules are met
After extraction, append watermark: <!-- extracted:L{lastLine}:{ISO timestamp} -->
Only heartbeat writes watermarks — inline extraction does NOT (dedup handles overlap)
After rotation, watermark moves to archive with the original file; the stub has no watermark and is parsed entirely (cheap, 10-20 lines)
System observes its own friction — what worked, what failed, what patterns emerged — and accumulates these observations for review.
Storage Structure
workspace/ops/
├── observations/ # Operational observations
│ ├── index.json # Registry of all observations
│ └── obs-0001.json # Individual observation files
└── tensions/ # Contradictions between facts
├── index.json # Registry of all tensions
└── tension-0001.json # Individual tension files
Capturing Observations
# Basic observation (friction, surprise, quality)
bun skills/engram/scripts/memory-observe.js --observation "KG extraction missed facts about email" --category friction
# With description
bun skills/engram/scripts/memory-observe.js --observation "..." --category quality --description "Why this matters"# Extended category (requires --extended flag)
bun skills/engram/scripts/memory-observe.js --observation "..." --category process --extended
Categories:
friction — something that slowed work down
surprise — unexpected outcome
quality — code/content quality issue
process, methodology — requires --extended flag
Capturing Tensions
bun skills/engram/scripts/memory-tension.js \
--tension "Two facts contradict each other" \
--fact1 "sergey-001" \
--fact2 "sergey-005" \
--description "Context about the contradiction"
Threshold Alerts
Heartbeat checks pending counts:
>20 pending observations → alert
>5 pending tensions → alert
Alerts appear in daily note report.
Observation Schema
{"id":"obs-0001","observation":"KG extraction missed facts about email","category":"friction","description":"Why this matters","status":"pending","createdAt":"2026-02-25T12:00:00.000Z","promotedAt":null,"archivedAt":null,"accessCount":0}
Rules
Novelty check: Jaccard similarity >0.7 with recent observations → rejected as duplicate
Review loop: observations stay pending until reviewed → promoted to life/ or archived
Content promotion: durable observations → promoted to Knowledge Graph as patterns/principles
No-Deletion Rule: Facts are NEVER deleted. Set status: "superseded" and link via supersededBy.
Write Pipeline Rule: NEVER write items.json directly. Always use bun skills/engram/scripts/memory-write.js. Direct writes bypass dedup, validation, and hash registration, causing schema mismatches (e.g., content vs fact, created vs timestamp). This applies to heartbeats, inline extraction, and entity creation. No exceptions.
Pattern for subagents with cleanup: "delete" and long-term memory via domains.
Quick Start
# Create a domain
bun skills/engram/scripts/add-domain.js --domain monitoring --description "Server monitoring"# Configure rules in decisions.md# Launch subagent with prompt from templates/spawn-prompt.md
Domain Structure
memory/domains/{domain}/
├── decisions.md # Rules (read-only for subagent)
├── workflow.md # HOW the domain works: scripts, scope, tools (optional)
├── status.md # Current state (written by subagent)
├── changelog.md # Append-only log (written by subagent)
├── archives/ # Changelog rotation
└── README.md
workflow.md — optional file describing the domain's infrastructure (scripts, API, task scope, wiki links). Recommended for domains with 2+ task types. Simple domains (single task) can work without it.
Separation of concerns:
decisions.md — WHAT can be done (rules, thresholds, constraints)
workflow.md — HOW the domain works (scripts, API, scope, links)
Template (spawn-prompt) — WHICH specific task to execute
Rules
One domain = one active subagent at any given time
decisions.md — read-only for subagents; changes via PROPOSAL in changelog
Subagent does NOT write to daily notes or life/
QMD: one domains collection for all domains
Heartbeat: review PROPOSAL, rotate changelog, optionally KG extraction
Project Domains
Domains can be linked to projects in the Knowledge Graph (life/projects/). This provides a two-way binding:
KG entity (life/projects/{name}/) — what the bot knows about the project (facts, summary)
Domain (memory/domains/{name}/) — context for the subagent (decisions, status, changelog)
The binding is defined via the domain registry (memory/domains/registry.json):
dev-project — development, linked to KG entity, subagent on demand
cron-task — periodic tasks, subagent on schedule
Spawn Templates
Rule: always use a template. Don't write prompts manually — use spawnTemplate from the registry. This ensures the subagent receives the Domain Lifecycle (paths to decisions, status, changelog).
Templates are in templates/spawn-prompts/:
dev-project.md — for development (decisions + status + changelog tail)
cron-task.md — for periodic tasks (decisions + status)
Templates use placeholders: {{domain}}, {{task}}, {{workflow}}, {{decisions}}, {{status}}, {{changelog_tail}}.
# Intra-entity (fast, no QMD)
bun scripts/memory-contradict.js --fact "Uses Node.js" --entity "areas/people/sergey"# Cross-entity (via QMD BM25, searches all entities)
bun scripts/memory-contradict.js --fact "Uses Node.js" --entity "areas/people/sergey" \
--cross-entity --collections "life,openclaw-memory-agent-main-main"
Rules for Inline Extraction
Only in main session (group chats don't touch KG)
HIGH signal → extract immediately via memory-write.js
LOW signal → daily note only (heartbeat extracts later)
Do NOT write extraction watermarks during inline extraction (heartbeat only)
Dedup is automatic — duplicates from inline + heartbeat silently skipped
Session Recording
Daily notes capture session activity. Without explicit recording, notes remain empty despite active work.
Trigger Rules
Record to daily note when:
Topic completed — a task/discussion block finishes (every 5-10 messages)
Decision made — any explicit decision → --section decisions
Topic shift — conversation moves to a new subject
Significant result — something was built, fixed, or discovered
Recording Script
bun skills/engram/scripts/daily-note-append.js \
--session main --section events --text "Fixed 44 semantic duplicates in KG"
bun skills/engram/scripts/daily-note-append.js \
--session main --section decisions --text "Jaccard ≥ 0.5 now blocks writes (was warning-only)"
Rules
Keep entries brief (1-2 lines each)
Record facts, not feelings ("Fixed X" not "Had a great session")
bun skills/engram/scripts/add-domain.js --domain <name> [--description "Description"]
Creates memory/domains/{domain}/ with decisions.md, status.md, changelog.md, README.md. Registers QMD collection domains (one for all domains). Warns if >20 domains.
validate.js — Check integrity
bun skills/engram/scripts/validate.js [--fix] [--agent-id main]
Checks directory structure, required files, items.json validity, v2 schema compliance, ID uniqueness, supersededBy references. Use --fix to auto-repair.
migrate-v2.js — Migrate to v2 schema
bun skills/engram/scripts/migrate-v2.js [--dry-run]
Adds missing v2 fields (confidence, abstractionLevel, tags) to all items.json files with sensible defaults.
memory-signal.js — Signal detection
bun skills/engram/scripts/memory-signal.js --text "I prefer TypeScript"
Classifies text as high/low/none signal. Regex-based, no LLM, <10ms. Returns categories, keywords, confidence.
Single entry point for all KG writes. Handles dedup, validation, QMD update, optional contradiction/semantic checks. Use --entity-create to create new entities on the fly. Use --access mode to bump a fact's recency (important for decay tiers).
memory-dedup.js — Deduplication index
bun skills/engram/scripts/memory-dedup.js --seed # Index all existing facts
bun skills/engram/scripts/memory-dedup.js --check --hash <sha256> # Check if exists
Manages workspace/memory-state/fact-hashes.json. Run --seed after initial setup or weekly synthesis.
memory-contradict.js — Contradiction detection
bun skills/engram/scripts/memory-contradict.js --fact <text> --entity <path> \
[--cross-entity] [--collections "life,other"]
Finds conflicting facts via Jaccard similarity. Intra-entity by default; --cross-entity discovers related entities via QMD BM25.
Captures tensions between two facts. Validates that both fact IDs exist in KG before creating tension. Includes Jaccard novelty check (>0.7 similarity → skips duplicate).
daily-note-append.js — Record session activity to daily note
bun skills/engram/scripts/daily-note-append.js \
--session main --agent-id main --section events --text "Fixed 44 semantic duplicates in KG"
Atomically appends a bullet entry to a named section of today's daily note. Creates the note from template if it doesn't exist. Sections: events, decisions, learnings, threads, next. Never overwrites existing content, never touches watermarks or Heartbeat Report.
rebuild-summaries.js — Rebuild summary.md from items.json
bun skills/engram/scripts/rebuild-summaries.js [--dry-run] [--entity areas/people/sergey] [--apply-decay]
Deterministically regenerates summary.md for all entities in life/ from their items.json. No LLM involved.
Without --apply-decay: groups active facts by category, lists top 5 by confidence, shows counts per category and superseded stats. Outputs { "updated": N, "skipped": N, "errors": N }.
With --apply-decay: applies Memory Decay tiers (Hot/Warm/Cold) based on lastAccessed/createdAt/source date. Summary format changes to tiered sections: ## Current (Hot), ## Background (Warm), ## Enduring (Principles). Cold facts (except principles) are excluded from summary but remain in items.json. Outputs { "updated": N, "skipped": N, "errors": N, "hot": N, "warm": N, "coldExcluded": N }.
Decay algorithm: see references/decay-rules.md. Used by HB-SYNTHESIS.md subagent during Monday heartbeat.
Use --dry-run to preview diffs without writing. Use --entity to process one entity.
rotate-notes.js — Three-Layer Rotation
bun skills/engram/scripts/rotate-notes.js --check --session main # Check if daily note needs rotation
bun skills/engram/scripts/rotate-notes.js --check-domains # Check all domain changelogs
bun skills/engram/scripts/rotate-notes.js --rotate --file <path> --type daily # Rotate daily note (>1000 lines)
bun skills/engram/scripts/rotate-notes.js --rotate --file <path> --type changelog # Rotate changelog# exit 0: nothing to rotate / done | exit 10: needs rotation (--check mode)
Handles Three-Layer Rotation for daily notes (archive + stub + QMD index) and simple rotation for domain changelogs. Called by heartbeat Phase 0.5. Daily note stubs contain a <!-- STUB: ... --> marker for the agent to fill with a summary later.
heartbeat-state.js — State management
bun skills/engram/scripts/heartbeat-state.js --get-all
bun skills/engram/scripts/heartbeat-state.js --set pendingObservations 5
Atomic read/write of memory/heartbeat-state.json. All heartbeat phase trackers (lastExtraction, lastDomainScan, subagentRuns, etc.) must be updated via this script — never edit the JSON directly.
Creates or updates ## Heartbeat Report section in a daily note. Called by heartbeat orchestrator in Phase 6 (initial write) and by process-handoff.js (status update after subagent handoff). Omit any flag to preserve its current value.