@basicmemory/openclaw-basic-memory 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,250 @@
1
+ ---
2
+ name: memory-notes
3
+ description: "How to write well-structured Basic Memory notes: frontmatter, observations with semantic categories, relations with wiki-links, and best practices for building a rich knowledge graph. Use when creating or improving notes."
4
+ ---
5
+
6
+ # Memory Notes
7
+
8
+ Write well-structured notes that Basic Memory can parse into a searchable knowledge graph. Every note is a markdown file with three key sections: frontmatter, observations, and relations.
9
+
10
+ ## Note Anatomy
11
+
12
+ ```markdown
13
+ ---
14
+ title: API Design Decisions
15
+ tags: [api, architecture, decisions]
16
+ ---
17
+
18
+ # API Design Decisions
19
+
20
+ Background context explaining why this note exists and what it covers.
21
+
22
+ ## Observations
23
+ - [decision] Use REST over GraphQL for simplicity #api
24
+ - [requirement] Must support versioning from day one
25
+ - [risk] Rate limiting needed for public endpoints
26
+
27
+ ## Relations
28
+ - implements [[API Specification]]
29
+ - depends_on [[Authentication System]]
30
+ - relates_to [[Performance Requirements]]
31
+ ```
32
+
33
+ ### Frontmatter
34
+
35
+ Every note starts with YAML frontmatter:
36
+
37
+ ```yaml
38
+ ---
39
+ title: Note Title # required — becomes the entity name in the knowledge graph
40
+ tags: [tag1, tag2] # optional — for organization and filtering
41
+ type: note # optional — defaults to "note", use custom types with schemas
42
+ permalink: custom-path # optional — auto-generated from title if omitted
43
+ ---
44
+ ```
45
+
46
+ - The `title` must match the `# Heading` in the body
47
+ - Tags are searchable and help with discovery
48
+ - Custom `type` values (Task, Meeting, Person, etc.) work with the schema system
49
+ - The `permalink` is auto-generated from the title (e.g., "API Design Decisions" → `api-design-decisions`). It stays stable across file moves and is the basis for `memory://` URLs. You rarely need to set it manually.
50
+
51
+ ### Body / Context
52
+
53
+ Free-form markdown between the heading and the Observations section. Use this for:
54
+ - Background and motivation
55
+ - Summary of the topic
56
+ - Any prose that doesn't fit neatly into categorized observations
57
+
58
+ This content is indexed for full-text search but isn't parsed into structured entities.
59
+
60
+ ## Observations
61
+
62
+ Observations are categorized facts — the atomic units of knowledge. Each one becomes a searchable entity in the knowledge graph.
63
+
64
+ ### Syntax
65
+
66
+ ```
67
+ - [category] Content of the observation #optional-tag
68
+ ```
69
+
70
+ - **Square brackets** define the semantic category
71
+ - **Content** is the fact, decision, insight, or note
72
+ - **Hash tags** (optional) add extra metadata for filtering
73
+
74
+ ### Categories Are Arbitrary
75
+
76
+ The category in brackets is free-form — use whatever label makes sense for the observation. There is no fixed list. The only rule is the `[category] content` syntax. Consistency within a project helps searchability, but invent categories freely.
77
+
78
+ A few examples to illustrate the range:
79
+
80
+ ```
81
+ - [decision] Use PostgreSQL for primary data store
82
+ - [risk] Third-party API has no SLA guarantee
83
+ - [technique] Exponential backoff for retry logic #resilience
84
+ - [question] Should we support multi-tenancy at the DB level?
85
+ - [preference] Use Bun over Node for new projects
86
+ - [lesson] Always validate webhook signatures server-side
87
+ - [status] active
88
+ - [flavor] Ethiopian beans work best with lighter roasts
89
+ ```
90
+
91
+ ### Observation Tips
92
+
93
+ - **One fact per observation.** Don't pack multiple ideas into one line.
94
+ - **Be specific.** `[decision] Use JWT` is less useful than `[decision] Use JWT with 15-minute expiry for API auth`.
95
+ - **Use tags for cross-cutting concerns.** `[risk] Rate limiting needed #api #security` makes this findable under both topics.
96
+ - **Categories are queryable.** `search_notes("[decision]")` finds all decisions across your knowledge base.
97
+
98
+ ## Relations
99
+
100
+ Relations create edges in the knowledge graph, linking notes to each other. They're how you build structure beyond individual notes.
101
+
102
+ ### Syntax
103
+
104
+ ```
105
+ - relation_type [[Target Note Title]]
106
+ ```
107
+
108
+ - **relation_type** is a descriptive verb or phrase (snake_case by convention)
109
+ - **Double brackets** `[[...]]` identify the target note by title or permalink
110
+ - Relations are directional: this note → target note
111
+
112
+ ### Relation Types
113
+
114
+ | Type | Purpose | Example |
115
+ |------|---------|---------|
116
+ | `implements` | One thing implements another | `- implements [[Auth Spec]]` |
117
+ | `requires` | Dependencies | `- requires [[Database Setup]]` |
118
+ | `relates_to` | General connection | `- relates_to [[Performance Notes]]` |
119
+ | `part_of` | Hierarchy/composition | `- part_of [[Backend Architecture]]` |
120
+ | `extends` | Enhancement or elaboration | `- extends [[Base Config]]` |
121
+ | `pairs_with` | Things that work together | `- pairs_with [[Frontend Client]]` |
122
+ | `inspired_by` | Source material | `- inspired_by [[CRDT Research Paper]]` |
123
+ | `replaces` | Supersedes another note | `- replaces [[Old Auth Design]]` |
124
+ | `depends_on` | Runtime/build dependency | `- depends_on [[MCP SDK]]` |
125
+ | `contrasts_with` | Alternative approaches | `- contrasts_with [[GraphQL Approach]]` |
126
+
127
+ ### Inline Relations
128
+
129
+ Wiki-links anywhere in the note body — not just the Relations section — also create graph edges:
130
+
131
+ ```markdown
132
+ We evaluated [[GraphQL Approach]] but decided against it because
133
+ the team has more experience with REST. See [[API Specification]]
134
+ for the full contract.
135
+ ```
136
+
137
+ These create `references` relations automatically. Use the Relations section for explicit, typed relationships; use inline links for natural prose references.
138
+
139
+ ### Relation Tips
140
+
141
+ - **Link liberally.** Relations are what turn isolated notes into a knowledge graph. When in doubt, add the link.
142
+ - **Create target notes if they don't exist yet.** `[[Future Topic]]` is valid — BM will resolve it when that note is created.
143
+ - **Use `build_context` to traverse.** `build_context(url="memory://note-title")` follows relations to gather connected knowledge.
144
+ - **Custom relation types are fine.** `taught_by`, `blocks`, `tested_in` — use whatever is descriptive.
145
+
146
+ ## Memory URLs
147
+
148
+ Every note is addressable via a `memory://` URL, built from its permalink. These URLs are how you navigate the knowledge graph programmatically.
149
+
150
+ ### URL Patterns
151
+
152
+ ```
153
+ memory://api-design-decisions # by permalink (title → kebab-case)
154
+ memory://docs/authentication # by file path
155
+ memory://docs/authentication.md # with extension (also works)
156
+ memory://auth* # wildcard prefix
157
+ memory://docs/* # wildcard suffix
158
+ memory://project/*/requirements # path wildcards
159
+ ```
160
+
161
+ ### Project-Scoped URLs
162
+
163
+ In multi-project setups, prefix with the project name:
164
+
165
+ ```
166
+ memory://main/specs/api-design # "main" project, "specs/api-design" path
167
+ memory://research/papers/crdt # "research" project
168
+ ```
169
+
170
+ The first path segment is matched against known project names. If it matches, it's used as the project scope. Otherwise the URL resolves in the default project.
171
+
172
+ ### Using Memory URLs
173
+
174
+ Memory URLs work with `build_context` to assemble related knowledge by traversing relations:
175
+
176
+ ```
177
+ // Get a note and its connected context
178
+ build_context(url="memory://api-design-decisions")
179
+
180
+ // Wildcard — gather all docs
181
+ build_context(url="memory://docs/*")
182
+
183
+ // Direct read by permalink
184
+ read_note(identifier="memory://api-design-decisions")
185
+ ```
186
+
187
+ ## Writing Notes with Tools
188
+
189
+ ### Creating a Note
190
+
191
+ ```
192
+ write_note(
193
+ title="API Design Decisions",
194
+ folder="architecture", // optional — organizes files on disk
195
+ content="---
196
+ title: API Design Decisions
197
+ tags: [api, architecture]
198
+ ---
199
+
200
+ # API Design Decisions
201
+
202
+ Context about the API design process.
203
+
204
+ ## Observations
205
+ - [decision] Use REST for public API #api
206
+ - [requirement] Support API versioning from v1
207
+
208
+ ## Relations
209
+ - implements [[API Specification]]
210
+ - relates_to [[Backend Architecture]]",
211
+ )
212
+ ```
213
+
214
+ ### Editing an Existing Note
215
+
216
+ Use `edit_note` to append, prepend, or find-and-replace within a note:
217
+
218
+ ```
219
+ // Append new observations
220
+ edit_note(
221
+ identifier="API Design Decisions",
222
+ operation="append",
223
+ heading="Observations",
224
+ content="- [decision] Use OpenAPI 3.1 for spec generation #api",
225
+ )
226
+
227
+ // Add a new relation
228
+ edit_note(
229
+ identifier="API Design Decisions",
230
+ operation="append",
231
+ heading="Relations",
232
+ content="- depends_on [[Rate Limiter]]",
233
+ )
234
+ ```
235
+
236
+ ## Best Practices
237
+
238
+ 1. **Start with context.** Before listing observations, explain *why* this note exists. Future-you (or your AI collaborator) will thank you.
239
+
240
+ 2. **Observations over prose.** Categorized observations are searchable and structured. A paragraph of text is not. Prefer `[decision] X because Y` over burying the same fact in a paragraph.
241
+
242
+ 3. **Build incrementally.** Add to existing notes rather than creating duplicates. Use `edit_note` to append new observations or relations as you learn more.
243
+
244
+ 4. **Review AI-generated content.** When an AI writes notes for you, review them for accuracy. The AI captures structure well but may miss nuance.
245
+
246
+ 5. **Use consistent titles.** Note titles are identifiers in the knowledge graph. `API Design Decisions` and `Api Design decisions` are different entities. Pick a convention and stick with it.
247
+
248
+ 6. **Link related concepts.** The value of a knowledge graph compounds with connections. A note with zero relations is an island — useful, but not as powerful as a connected one.
249
+
250
+ 7. **Let the graph grow naturally.** Don't try to design a perfect taxonomy upfront. Write notes as you work, add relations as connections emerge, and periodically use `/reflect` or `/defrag` to consolidate.
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: memory-reflect
3
+ description: "Sleep-time memory reflection: review recent conversations and daily notes, extract insights, and consolidate into long-term memory. Use when triggered by cron, heartbeat, or explicit request to reflect on recent activity. Runs as background processing to improve memory quality over time."
4
+ ---
5
+
6
+ # Memory Reflect
7
+
8
+ Review recent activity and consolidate valuable insights into long-term memory.
9
+
10
+ Inspired by sleep-time compute — the idea that memory formation happens best *between* active sessions, not during them.
11
+
12
+ ## When to Run
13
+
14
+ - **Cron/heartbeat**: Schedule as a periodic background task (recommended: 1-2x daily)
15
+ - **On demand**: User asks to reflect, consolidate, or review recent memory
16
+ - **Post-compaction**: After context window compaction events
17
+
18
+ ## Process
19
+
20
+ ### 1. Gather Recent Material
21
+
22
+ Read the last 2-3 days of daily notes from `memory/YYYY-MM-DD.md`. Also check:
23
+ - Recent conversation transcripts (if accessible)
24
+ - Any files modified in `memory/` in the last 48 hours
25
+ - Active tasks in `memory/tasks/`
26
+
27
+ ### 2. Evaluate What Matters
28
+
29
+ For each piece of information, ask:
30
+ - Is this a **decision** that affects future work? → Keep
31
+ - Is this a **lesson learned** or mistake to avoid? → Keep
32
+ - Is this a **preference** or working style insight? → Keep
33
+ - Is this a **relationship** detail (who does what, contact info)? → Keep
34
+ - Is this **transient** (weather checked, heartbeat ran, routine task)? → Skip
35
+ - Is this **already captured** in MEMORY.md or another long-term file? → Skip
36
+
37
+ ### 3. Update Long-Term Memory
38
+
39
+ Write consolidated insights to `MEMORY.md` following its existing structure:
40
+ - Add new sections or update existing ones
41
+ - Use concise, factual language
42
+ - Include dates for temporal context
43
+ - Remove or update outdated entries that the new information supersedes
44
+
45
+ ### 4. Log the Reflection
46
+
47
+ Append a brief entry to today's daily note:
48
+ ```markdown
49
+ ## Reflection (HH:MM)
50
+ - Reviewed: [list of files reviewed]
51
+ - Added to MEMORY.md: [brief summary of what was consolidated]
52
+ - Removed/updated: [anything cleaned up]
53
+ ```
54
+
55
+ ## Guidelines
56
+
57
+ - **Be selective.** The goal is distillation, not duplication. MEMORY.md should be curated wisdom, not a copy of daily notes.
58
+ - **Preserve voice.** If the agent has a personality/soul file, reflections should match that voice.
59
+ - **Don't delete daily notes.** They're the raw record. Reflection extracts from them; it doesn't replace them.
60
+ - **Merge, don't append.** If MEMORY.md already has a section about a topic, update it in place rather than adding a duplicate entry.
61
+ - **Flag uncertainty.** If something seems important but you're not sure, add it with a note like "(needs confirmation)" rather than skipping it entirely.
62
+ - **Restructure over time.** If MEMORY.md is a chronological dump, restructure it into topical sections during reflection. Curated knowledge > raw logs.
63
+ - **Check for filesystem issues.** Look for recursive nesting (memory/memory/memory/...), orphaned files, or bloat while gathering material.
@@ -0,0 +1,237 @@
1
+ ---
2
+ name: memory-schema
3
+ description: "Schema lifecycle management for Basic Memory: discover unschemaed notes, infer schemas, create and edit schema definitions, validate notes, and detect drift. Use when working with structured note types (Task, Person, Meeting, etc.) to maintain consistency across the knowledge graph."
4
+ ---
5
+
6
+ # Memory Schema
7
+
8
+ Manage structured note types using Basic Memory's Picoschema system. Schemas define what fields a note type should have, making notes uniform, queryable, and validatable.
9
+
10
+ ## When to Use
11
+
12
+ - **New note type emerging** — you notice several notes share the same structure (meetings, people, decisions)
13
+ - **Validation check** — confirm existing notes conform to their schema
14
+ - **Schema drift** — detect fields that notes use but the schema doesn't define (or vice versa)
15
+ - **Schema evolution** — add/remove/change fields as requirements evolve
16
+ - **On demand** — user asks to create, check, or manage schemas
17
+
18
+ ## Picoschema Syntax Reference
19
+
20
+ Schemas are defined in YAML frontmatter using Picoschema — a compact notation for describing note structure.
21
+
22
+ ### Basic Types
23
+
24
+ ```yaml
25
+ schema:
26
+ name: string, person's full name
27
+ age: integer, age in years
28
+ score: number, floating-point rating
29
+ active: boolean, whether currently active
30
+ ```
31
+
32
+ Supported types: `string`, `integer`, `number`, `boolean`.
33
+
34
+ ### Optional Fields
35
+
36
+ Append `?` to the field name:
37
+
38
+ ```yaml
39
+ schema:
40
+ title: string, required field
41
+ subtitle?: string, optional field
42
+ ```
43
+
44
+ ### Enums
45
+
46
+ Use `(enum)` with a list of allowed values:
47
+
48
+ ```yaml
49
+ schema:
50
+ status(enum): [active, blocked, done, abandoned], current state
51
+ ```
52
+
53
+ Optional enum:
54
+
55
+ ```yaml
56
+ schema:
57
+ priority?(enum): [low, medium, high, critical], task priority
58
+ ```
59
+
60
+ ### Arrays
61
+
62
+ Use `(array)` for list fields:
63
+
64
+ ```yaml
65
+ schema:
66
+ tags(array): string, categorization labels
67
+ steps?(array): string, ordered steps to complete
68
+ ```
69
+
70
+ ### Relations
71
+
72
+ Reference other entity types directly:
73
+
74
+ ```yaml
75
+ schema:
76
+ parent_task?: Task, parent task if this is a subtask
77
+ attendees?(array): Person, people who attended
78
+ ```
79
+
80
+ Relations create edges in the knowledge graph, linking notes together.
81
+
82
+ ### Validation Settings
83
+
84
+ ```yaml
85
+ settings:
86
+ validation: warn # warn (log issues) or error (strict)
87
+ ```
88
+
89
+ ### Complete Example
90
+
91
+ ```yaml
92
+ ---
93
+ title: Meeting
94
+ type: schema
95
+ entity: Meeting
96
+ version: 1
97
+ schema:
98
+ topic: string, what was discussed
99
+ date: string, when it happened (YYYY-MM-DD)
100
+ attendees?(array): Person, who attended
101
+ decisions?(array): string, decisions made
102
+ action_items?(array): string, follow-up tasks
103
+ status?(enum): [scheduled, completed, cancelled], meeting state
104
+ settings:
105
+ validation: warn
106
+ ---
107
+ ```
108
+
109
+ ## Discovering Unschemaed Notes
110
+
111
+ Look for clusters of notes that share structure but have no schema:
112
+
113
+ 1. **Search by type**: `search_notes(query="type:Meeting")` — if many notes share a `type` but no `schema/Meeting.md` exists, it's a candidate.
114
+
115
+ 2. **Infer a schema**: Use `schema_infer` to analyze existing notes and generate a suggested schema:
116
+ ```
117
+ schema_infer(noteType="Meeting")
118
+ schema_infer(noteType="Meeting", threshold=0.5) // fields in 50%+ of notes
119
+ ```
120
+ The threshold (0.0–1.0) controls how common a field must be to be included. Default is usually fine; lower it to catch rarer fields.
121
+
122
+ 3. **Review the suggestion** — the inferred schema shows field names, types, and frequency. Decide which fields to keep, make optional, or drop.
123
+
124
+ ## Creating a Schema
125
+
126
+ Write the schema note to `schema/<EntityName>`:
127
+
128
+ ```
129
+ write_note(
130
+ title="Meeting",
131
+ folder="schema",
132
+ content="---
133
+ title: Meeting
134
+ type: schema
135
+ entity: Meeting
136
+ version: 1
137
+ schema:
138
+ topic: string, what was discussed
139
+ date: string, when it happened
140
+ attendees?(array): Person, who attended
141
+ decisions?(array): string, decisions made
142
+ settings:
143
+ validation: warn
144
+ ---
145
+
146
+ # Meeting
147
+
148
+ Schema for meeting notes.
149
+
150
+ ## Observations
151
+ - [convention] Meeting notes live in memory/meetings/ or as daily entries
152
+ - [convention] Always include date and topic
153
+ - [convention] Action items should become tasks when complex",
154
+ )
155
+ ```
156
+
157
+ ### Key Principles
158
+
159
+ - **Schema notes live in `schema/`** — one note per entity type
160
+ - **`type: schema`** in frontmatter marks it as a schema definition
161
+ - **`entity: Meeting`** names the type it applies to
162
+ - **`version: 1`** — increment when making breaking changes
163
+ - **`settings.validation: warn`** is recommended to start — it logs issues without blocking writes
164
+
165
+ ## Validating Notes
166
+
167
+ Check how well existing notes conform to their schema:
168
+
169
+ ```
170
+ // Validate all notes of a type
171
+ schema_validate(noteType="Meeting")
172
+
173
+ // Validate a single note
174
+ schema_validate(identifier="meetings/2026-02-10-standup")
175
+ ```
176
+
177
+ Validation reports:
178
+ - **Missing required fields** — the note lacks a field the schema requires
179
+ - **Unknown fields** — the note has fields the schema doesn't define
180
+ - **Type mismatches** — a field value doesn't match the expected type
181
+ - **Invalid enum values** — a value isn't in the allowed set
182
+
183
+ ### Handling Validation Results
184
+
185
+ - **`warn` mode**: Review warnings periodically. Fix notes that are clearly wrong; add optional fields to the schema for legitimate new patterns.
186
+ - **`error` mode**: Use for strict schemas where conformance matters (e.g., automated pipelines consuming notes).
187
+
188
+ ## Detecting Drift
189
+
190
+ Over time, notes evolve and schemas lag behind. Use `schema_diff` to find divergence:
191
+
192
+ ```
193
+ schema_diff(noteType="Meeting")
194
+ ```
195
+
196
+ Diff reports:
197
+ - **Fields in notes but not in schema** — candidates for adding to the schema (as optional)
198
+ - **Schema fields rarely used** — consider making optional or removing
199
+ - **Type inconsistencies** — fields used as different types across notes
200
+
201
+ ## Schema Evolution
202
+
203
+ When note structure changes:
204
+
205
+ 1. **Run diff** to see current state: `schema_diff(noteType="Meeting")`
206
+ 2. **Update the schema note** via `edit_note`:
207
+ ```
208
+ edit_note(
209
+ identifier="schema/Meeting",
210
+ operation="find_replace",
211
+ find_text="version: 1",
212
+ content="version: 2",
213
+ expected_replacements=1,
214
+ )
215
+ ```
216
+ 3. **Add/remove/modify fields** in the `schema:` block
217
+ 4. **Re-validate** to confirm existing notes still pass: `schema_validate(noteType="Meeting")`
218
+ 5. **Fix outliers** — update notes that don't conform to the new schema
219
+
220
+ ### Evolution Guidelines
221
+
222
+ - **Additive changes** (new optional fields) are safe — no version bump needed
223
+ - **Breaking changes** (new required fields, removed fields, type changes) should bump `version`
224
+ - **Prefer optional over required** — most fields should be optional to start
225
+ - **Don't over-constrain** — schemas should describe common structure, not enforce rigid templates
226
+ - **Schema as documentation** — even if validation is set to `warn`, the schema serves as living documentation for what notes of that type should contain
227
+
228
+ ## Workflow Summary
229
+
230
+ ```
231
+ 1. Notice repeated note structure → infer schema (schema_infer)
232
+ 2. Review + create schema note → write to schema/ (write_note)
233
+ 3. Validate existing notes → check conformance (schema_validate)
234
+ 4. Fix outliers → edit non-conforming notes (edit_note)
235
+ 5. Periodically check drift → detect divergence (schema_diff)
236
+ 6. Evolve schema as needed → update schema note (edit_note)
237
+ ```