basic-memory-pi-setup
Set up Basic Memory for a Pi workspace. Use when Basic Memory is not configured, /bm-status…
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
$ npx -y skills add basicmachines-co/basic-memory --skill memory-schema --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/memory-schemaContext preview
The summary Claude sees to decide when to auto-load this skill.
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
name: memory-schema 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."
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.
Schemas are defined in YAML frontmatter using Picoschema — a compact notation for describing note structure.
schema: name: string, person's full name age: integer, age in years score: number, floating-point rating active: boolean, whether currently active
Supported types: `string`, `integer`, `number`, `boolean`.
Append `?` to the field name:
schema: title: string, required field subtitle?: string, optional field
Use `(enum)` with a list of allowed values:
schema: status(enum, current state): [active, blocked, done, abandoned]
Optional enum:
schema: priority?(enum, task priority): [low, medium, high, critical]
Use `(array)` for list fields:
schema: tags(array): string, categorization labels steps?(array): string, ordered steps to complete
Reference other entity types directly:
schema: parent_task?: Task, parent task if this is a subtask attendees?(array): Person, people who attended
Relations create edges in the knowledge graph, linking notes together.
settings: validation: warn # warn (log issues) or strict (errors)
Use `strict` as the canonical enforcing mode. `error` is accepted only as a compatibility alias.
--- title: Meeting type: schema entity: Meeting version: 1 schema: topic: string, what was discussed date: string, when it happened (YYYY-MM-DD) attendees?(array): Person, who attended decisions?(array): string, decisions made action_items?(array): string, follow-up tasks status?(enum, meeting state): [scheduled, completed, cancelled] settings: validation: warn ---
Look for clusters of notes that share structure but have no schema:
1. **Search by type**: `search_notes(note_types=["meeting"])` — if many notes share a `type` but no `schema/Meeting.md` exists, it's a candidate.
2. **Infer a schema**: Use `schema_infer` to analyze existing notes and generate a suggested schema:
schema_infer(note_type="Meeting") schema_infer(note_type="Meeting", threshold=0.5) # fields in 50%+ of notes
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.
3. **Review the suggestion** — the inferred schema shows field names, types, and frequency. Decide which fields to keep, make optional, or drop.
Write the schema note to `schema/<EntityName>`:
write_note(
title="Meeting",
directory="schema",
note_type="schema",
metadata={
"entity": "Meeting",
"version": 1,
"schema": {
"topic": "string, what was discussed",
"date": "string, when it happened",
"attendees?(array)": "Person, who attended",
"decisions?(array)": "string, decisions made"
},
"settings": {"validation": "warn"}
},
content="""# Meeting
Schema for meeting notes.
## Observations
- [convention] Meeting notes live in memory/meetings/ or as daily entries
- [convention] Always include date and topic
- [convention] Action items should become tasks when complex"""
)Check how well existing notes conform to their schema:
# Validate all notes of a type schema_validate(note_type="Meeting") # Validate a single note schema_validate(identifier="meetings/2026-02-10-standup")
**Important:** `schema_validate` checks for schema fields as **observation categories** in the note body — e.g., a `status` field expects `- [status] active` as an observation. Fields stored only in frontmatter metadata won't satisfy validation. To pass cleanly, include schema fields as both frontmatter values (for metadata search) and observations (for schema validation).
Validation reports **missing required fields** (as observation categories, or relations for entity-reference fields) and **invalid enum values**. Undeclared observation categories and relations are listed as informational "unmatched" items. Scalar values are not type-checked.
Over time, notes evolve and schemas lag behind. Use `schema_diff` to find divergence:
schema_diff(note_type="Meeting")
Diff reports:
AI conversations that actually remember. Never re-explain your project to your AI again. Join our Discord: https://discord.gg/tyvKNccgqN
Repo: basicmachines-co/basic-memory
Set up Basic Memory for a Pi workspace. Use when Basic Memory is not configured, /bm-status…
Use Basic Memory from Pi for durable continuity. Capture checkpoints with bm_capture, recall…
Guide Basic Memory setup in Tau. Use when a user wants to install or configure the Tau memory…
Save a deliberate work checkpoint to Basic Memory with the story, changed files,…
Capture a durable engineering decision in Basic Memory with rationale, alternatives,…
Orient Claude from Basic Memory before substantial repo work by reading active tasks, open…