Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ npx skills add basicmachines-co/basic-memory-skills --skill memory-tasks
# Install all skills for a specific agent
npx skills add basicmachines-co/basic-memory-skills --agent claude

# Install for GitHub Copilot CLI
npx skills add basicmachines-co/basic-memory-skills --agent github-copilot

# List available skills without installing
npx skills add basicmachines-co/basic-memory-skills --list

Expand All @@ -73,7 +76,7 @@ Claude Desktop loads skills through **Settings > Capabilities**:

Repeat for each skill you want. Custom uploaded skills are private to your account.

> **Tip:** Start with **memory-notes** (core note-writing patterns) and add others as needed. You don't need all 9 at once.
> **Tip:** Start with **memory-notes** (core note-writing patterns) and add others as needed. You don't need all 10 at once.

See [Using Skills in Claude](https://support.claude.com/en/articles/12512180-using-skills-in-claude) for more details.

Expand All @@ -96,12 +99,13 @@ cp -r memory-tasks <agent-skills-dir>/

### Bundled with OpenClaw plugin

All 9 skills are also bundled in the [`@basicmemory/openclaw-basic-memory`](https://github.com/basicmachines-co/openclaw-basic-memory) plugin — no extra install step needed if you use OpenClaw.
All 10 skills are also bundled in the [`@basicmemory/openclaw-basic-memory`](https://github.com/basicmachines-co/openclaw-basic-memory) plugin — no extra install step needed if you use OpenClaw.
Comment thread
tyler555g marked this conversation as resolved.

## Compatible Agents

These skills work with any AI coding agent that supports the SKILL.md format:

- **GitHub Copilot CLI** — `npx skills add basicmachines-co/basic-memory-skills --agent github-copilot` installs to `~/.copilot/skills/`
- **Claude Desktop** — upload skill ZIPs via Settings > Capabilities
- **Claude Code** — loads skills from `~/.claude/skills/` or `.claude/skills/`
- **Cursor** — AI-powered coding with skill support
Expand Down
42 changes: 37 additions & 5 deletions memory-defrag/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "Defragment and reorganize agent memory files: split bloated files,

# Memory Defrag

Reorganize memory files for clarity, efficiency, and relevance. Like filesystem defragmentation but for knowledge.
Reorganize memory files for clarity, efficiency, and relevance. Defrag combats [context rot and context distraction](https://github.com/tyler555g/best-practices/blob/main/packages/content/technology_and_information/data_science_and_ai/context-engineering.md) — stale or noisy entries that degrade agent behavior when notes are retrieved.

## When to Run

Expand Down Expand Up @@ -35,18 +35,47 @@ Look for these common issues:
| **Bloated file** | >300 lines, covers many topics | Split into focused files |
| **Duplicate info** | Same fact in multiple places | Consolidate to one location |
| **Stale entries** | References to completed work, old dates, resolved issues | Remove or archive |
| **Orphan files** | Files in memory/ never referenced or updated | Review, merge, or remove |
| **Resolved error traces** | Debugging logs, failed-attempt history, closed-issue workarounds | Remove — context noise once resolved |
| **Orphan files** | Files in memory/ that are never referenced or updated | Review, merge, or remove |
| **Inconsistencies** | Contradictory information across files | Resolve to ground truth |
| **Poor organization** | Related info scattered across files | Restructure by topic |
| **Recursive nesting** | `memory/memory/memory/...` directories | Delete nested dirs (indexer bug artifact) |

### Resolved Error Traces

Resolved error traces deserve special attention:
- Debugging step-by-step logs from incidents that are now closed
- "Tried X, failed because Y" histories where the issue is resolved
- Workaround instructions for bugs that have been fixed
- Error symptoms and their old diagnoses when the root cause is gone

**Why they're harmful:** When retrieved as context, they look like current problems. A fresh agent reading "reconnect loop crashes the server — workaround: restart manually" doesn't know it was fixed last week. This creates false alerts and wastes context budget on phantom issues.

**The rule:** Once an issue is resolved and the fix is documented or deployed, remove the error trace. If there's a lesson worth preserving, distill it to a `[lesson]` observation — one line, not a log.

```python
# Before: three lines of stale error context
# - [issue] MCP server crashes on reconnect — repro: disconnect and reconnect rapidly
# - [workaround] Restart the MCP server manually after each disconnect
# - [status] investigating

# After: one line of distilled lesson
edit_note(
identifier="MEMORY",
operation="find_replace",
find_text="- [issue] MCP server crashes on reconnect — repro: disconnect and reconnect rapidly\n- [workaround] Restart the MCP server manually after each disconnect\n- [status] investigating",
content="- [lesson] MCP reconnect stability: fixed in v2.1.0 — upgrade if seeing crashes #mcp"
)
```

### 3. Plan Changes

Before making edits, write a brief plan:
```markdown
## Defrag Plan
- [ ] Split MEMORY.md "Key People" section → memory/people.md
- [ ] Remove completed tasks older than 30 days from memory/tasks/
- [ ] Remove resolved error traces from MEMORY.md
- [ ] Move completed tasks older than 30 days from memory/tasks/ to archive
- [ ] Merge memory/bm-marketing-ideas.md into memory/competitive/
- [ ] Update stale project status entries in MEMORY.md
```
Expand All @@ -59,11 +88,12 @@ Apply changes one at a time:
- **Prune**: Remove information that is no longer relevant or accurate
- **Restructure**: Move files to appropriate directories, rename for clarity
- **Update**: Fix outdated facts, dates, statuses
- **Strip error traces**: Remove resolved debugging history — leave only lessons

### 5. Verify & Log

After changes:
- Verify no information was lost (compare before/after)
- Verify no valuable information was lost (compare before/after)
- Update any cross-references between files
- Log what was done in today's daily note:

Expand All @@ -73,6 +103,7 @@ After changes:
- Split: [list]
- Merged: [list]
- Pruned: [list]
- Error traces removed: [count]
- Net result: X files, Y total lines (was Z lines)
```

Expand All @@ -82,5 +113,6 @@ After changes:
- **Target 15-25 focused files.** Too few means bloated files; too many means fragmentation. Aim for the sweet spot.
- **File names should be scannable.** Use descriptive names: `people.md`, `project-status.md`, `competitive-landscape.md` — not `notes-2.md`.
- **Don't over-organize.** One level of directories is usually enough. `memory/tasks/` and `memory/competitive/` are fine; `memory/work/projects/active/basic-memory/notes/` is not.
- **Completed tasks**: Tasks with `status: done` older than 14 days can be removed. Their insights should already be in MEMORY.md via reflection.
- **Completed tasks**: Tasks with `status: done` older than 14 days should be archived (not deleted). Their insights should already be in MEMORY.md via reflection.
- **Ask before destructive changes.** If uncertain whether information is still relevant, keep it with a `(review needed)` tag rather than deleting.
- **Distill, don't just remove.** When pruning error traces or stale observations, ask if there's a one-line lesson worth keeping before deleting entirely.
3 changes: 2 additions & 1 deletion memory-metadata-search/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,11 @@ search_notes("OAuth", metadata_filters={"status": "in-progress"})

## Guidelines

- **Use metadata search for structured queries.** If you're looking for notes by a known field value (status, priority, type), metadata filters are more precise than text search.
- **Precision retrieval over broad loading.** If you're looking for notes by a known field value (status, priority, type), metadata filters are more precise than text search. This aligns with the [Select principle](https://github.com/tyler555g/best-practices/blob/main/packages/content/technology_and_information/data_science_and_ai/context-engineering.md) — retrieve only what's needed for the current step.
- **Use text search for content queries.** If you're looking for notes *about* something, text search is better. Combine both when you need precision.
- **Custom fields are free.** Any YAML key you put in frontmatter becomes queryable — no schema or configuration required.
- **Multiple filters are AND.** `{"status": "active", "priority": "high"}` requires both conditions.
- **Omit `query` for filter-only searches.** `search_notes(metadata_filters={"status": "active"})` works without a text query.
- **Dot notation for nesting.** Access nested YAML structures with dots: `{"schema.version": "2"}` queries the `version` key inside a `schema` object.
- **Tags shortcut is convenient but limited.** `tags` and `status` are sugar for common fields. For anything else, use `metadata_filters` directly.
- **Consistency enables filtering.** Metadata filters require consistent values across notes. If you use `status: active` sometimes and `status: in-progress` other times for the same concept, filters break. Use schemas to enforce consistency.

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The guideline says to “Use schemas to enforce consistency,” but schema_validate explicitly ignores frontmatter-only fields (it only checks observation categories). As written, this implies schemas will enforce metadata filter values even when they’re only in frontmatter, which conflicts with the behavior described in memory-schema/SKILL.md. Consider rephrasing to clarify that schemas enforce consistency only for fields present as observations (and that metadata-filtered fields should be kept in sync across frontmatter + observations if you want both filtering and validation).

Suggested change
- **Consistency enables filtering.** Metadata filters require consistent values across notes. If you use `status: active` sometimes and `status: in-progress` other times for the same concept, filters break. Use schemas to enforce consistency.
- **Consistency enables filtering.** Metadata filters require consistent values across notes. If you use `status: active` sometimes and `status: in-progress` other times for the same concept, filters break. Schemas help enforce consistency only for fields that are also recorded as observations and validated by `schema_validate`; frontmatter-only fields are still searchable, but if you want both filtering and validation, keep the frontmatter value and corresponding observation in sync.

Copilot uses AI. Check for mistakes.
9 changes: 8 additions & 1 deletion memory-schema/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,14 @@ schema_validate(noteType="Meeting")
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).
### Why Notes Need Fields in Both Frontmatter and Observations

Basic Memory has two querying modes that access notes differently:

- **`search_notes` with `metadata_filters`** — reads frontmatter. This is how you find notes by status, priority, etc.
- **`schema_validate`** — checks for fields as observation categories in the note body (e.g., `- [status] active`).

A field stored only in frontmatter is not checked by `schema_validate`. If that field is required by the schema, it must also appear as an observation category or validation will report it as missing. A field stored only in observations can't be metadata-filtered. For fields you need both to query and to validate (like `status`, `current_step`), keep them in both places and keep them in sync. For fields only needed for one purpose, one location is fine.

Validation reports:
- **Missing required fields** — the note lacks a field the schema requires (as an observation category)
Expand Down
84 changes: 62 additions & 22 deletions memory-tasks/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ description: "Task management via Basic Memory schemas: create, track, and resum

# Memory Tasks

Manage work-in-progress using Basic Memory's schema system. Tasks are just notes with `type: Task` — they live in the knowledge graph, validate against a schema, and survive context compaction.
Manage work-in-progress using Basic Memory's schema system. Tasks are just notes with `type: task` — they live in the knowledge graph, validate against a schema, and survive context compaction.

## When to Use

- **Starting multi-step work** (3+ steps, or anything that might outlast the context window)
- **After compaction/restart** — search for active tasks to resume
- **Pre-compaction flush** — update all active tasks with current state
- **Pause protocol** — update all active tasks with current state before compaction
- **On demand** — user asks to create, check, or manage tasks

## Task Schema
Expand Down Expand Up @@ -78,29 +78,48 @@ What future-you needs to pick up this work. Include:
)
```

**Why both frontmatter and observations?** Fields in `metadata` (stored as frontmatter) power `search_notes` with `metadata_filters`. Fields as observations (`- [status] active`) power `schema_validate`. Include queryable fields in both places for full coverage.
### Why Both Frontmatter and Observations?

Frontmatter and observations serve different access patterns:

- **Frontmatter** (`metadata`) → powers `search_notes` with `metadata_filters`. This is how agents find tasks by status, priority, etc.
- **Observations** (`- [status] active`) → powers `schema_validate`. This is how the schema system checks conformance.

Any schema-required fields must exist as observations, because `schema_validate` only recognizes required fields when they appear as observation categories. For Task notes, that includes `description` and any other non-optional schema fields.

Duplicate only the subset of fields you want to metadata-filter (like `status` and `current_step`) into frontmatter, and keep those duplicated values in sync with the observations. Don't let the two diverge — if frontmatter says `status: done` but observations say `[status] active`, you have a split-brain state.

### Key Principles

- **Steps are concrete and checkable** — "Implement X in file Y", not "figure out stuff"
- **Context is for post-amnesia resumption** — Write it as if explaining to a smart person who knows nothing about what you've been doing
- **Relations link to other entities** — `parent_task [[Other Task]]`, `related_to [[Some Note]]`
- **`note_types` is case-sensitive** — `write_note(note_type="Task")` stores the type as lowercase `task` in frontmatter. Use `note_types=["task"]` (lowercase) in search queries.
- **`note_type` is normalized to lowercase** — `write_note(note_type="Task")` stores the type as lowercase `task` in frontmatter. Use lowercase values such as `note_types=["task"]` in search queries.
Comment thread
tyler555g marked this conversation as resolved.

## Resuming After Compaction
## Resume Protocol

On session start or after compaction:
On session start or after compaction, follow this sequence:

1. **Search for active tasks:**
```python
search_notes(note_types=["task"], status="active")
```
```
1. SEARCH → search_notes(note_types=["task"], status="active")
2. READ → read_note(identifier="<task-permalink>")
3. VALIDATE → confirm current_step matches the step checkboxes
4. CONTINUE → execute the next unchecked step
```

Cross-check `current_step` against the checkbox list — the checkboxes are the ground truth. Context compaction can leave step counts stale.

2. **Read the task note** to get full context
```python
# Step 1: Find active work
search_notes(note_types=["task"], status="active")

3. **Resume from `current_step`** using the `context` field
# Step 2: Read the full task
read_note(identifier="tasks/my-active-task")

4. **Update as you progress** — increment `current_step`, update context, check off steps
# Step 3: Validate — current_step is the next step to execute, so the last checked box should be current_step - 1
# If current_step=3 but steps 1, 2, 3 are all checked → update current_step to 4
# If steps 1, 2 are checked but current_step=3 → correct, continue with step 3
```

## Updating Tasks

Expand Down Expand Up @@ -131,16 +150,36 @@ completed: YYYY-MM-DD

Add a brief summary of what was accomplished and any follow-up needed.

## Pre-Compaction Flush
## Pause Protocol

When a compaction event is imminent:
Before any `/compact` event, end of session, or context-threatening operation:
Comment thread
tyler555g marked this conversation as resolved.

```
1. FIND ALL → search_notes(note_types=["task"], status="active")
2. FOR EACH → update current_step, context, and step checkboxes
3. VERIFY → read_note to confirm the update landed correctly
```

What to write in `context` before pausing:
- What you just completed (1 sentence)
- What the next step requires (key inputs, file paths, decisions)
- Any blockers discovered
- Anything that would be frustrating to re-discover

```python
edit_note(
identifier="tasks/my-active-task",
operation="find_replace",
find_text="## Context\nWhat future-you needs to pick up this work. Include:\n- Key file paths and repos involved\n- Decisions already made and why\n- What was tried and what worked/didn't\n- Where to look for related context",
content="""## Context
Completed: Implemented the database migration script at db/migrate/001.py.
Next: Run migration against staging. Need DATABASE_URL env var (check .env.staging).
Blocker: None.
Note: The migration is idempotent — safe to re-run if interrupted."""
)
Comment thread
tyler555g marked this conversation as resolved.
```

1. Find all active tasks: `search_notes(note_types=["task"], status="active")`
2. For each, update:
- `current_step` to reflect actual progress
- `context` with everything needed to resume
- Step checkboxes to show what's done
3. This is **critical** — context not written down is context lost
Context not written before `/compact` is context permanently lost.

## Querying Tasks

Expand All @@ -159,8 +198,9 @@ With BM's schema system, tasks are fully queryable:
## Guidelines

- **One task per unit of work** — Don't cram multiple projects into one task
- **Externalize early** — If you think "I should remember this", write it down NOW
- **Externalize early** — If you think "I should remember this", write it down NOW — not after the next tool call
- **Context > steps** — Steps tell you what to do; context tells you why and how
- **Close finished tasks** — Don't leave completed work as `active`
- **Link related tasks** — Use `parent_task [[X]]` or relations to connect related work
- **Schema validation is your friend** — Run `schema_validate(noteType="Task")` periodically to catch incomplete tasks
- **Keep task notes dense** — Task notes compete for context window space. Every token should earn its place: concrete steps, essential context, no filler. Stale context in a task note is [context distraction](https://github.com/tyler555g/best-practices/blob/main/packages/content/technology_and_information/data_science_and_ai/context-engineering.md) — it dilutes signal when the task is retrieved
Loading