---
title: "Knowledge Format"
description: "Basic Memory stores knowledge as plain markdown files with simple patterns that create a searchable, connected knowledge graph."
canonical_url: "https://docs.basicmemory.com/concepts/knowledge-format"
---
# Knowledge Format

> Basic Memory stores knowledge as plain markdown files with simple patterns that create a searchable, connected knowledge graph.

Basic Memory is a knowledge base that you and your AI share. Everything is stored as plain markdown files on your machine — files you can open in any text editor, track with git, browse in Obsidian, or back up however you like. You own your data completely.

This page explains how those files are structured and how that structure turns a folder of notes into a connected knowledge graph.

<tip>

Using Basic Memory Cloud? The knowledge format is the same — create notes through AI conversations or edit them directly in the [web app](https://docs.basicmemory.com/cloud/note-editor).

</tip>

---

## What a Note Looks Like

Here's a note that an AI might create during a conversation about a project:

```markdown
---
title: Authentication Design
type: note
tags: [auth, security, backend]
permalink: authentication-design
created: 2026-08-01T14:30:00Z
modified: 2026-08-10T09:15:00Z
---

# Authentication Design

## Observations
- [decision] Using JWT tokens for stateless authentication #security
- [approach] Refresh tokens stored in HTTP-only cookies to prevent XSS
- [constraint] Tokens expire after 15 minutes to limit exposure window
- [status] Implementation complete and deployed to staging

## Relations
- implements [[API Security Requirements]]
- depends_on [[User Database Schema]]
- relates_to [[Session Management]]
```

That's it. Markdown with a few simple patterns. The AI handles writing notes like this for you — you just tell it what you want to remember and it produces well-structured notes. But it helps to understand what you're looking at, so let's walk through the pieces.

---

## Frontmatter

The YAML block at the top of each file holds metadata:

```yaml
---
title: Authentication Design
type: note
tags: [auth, security, backend]
permalink: authentication-design
created: 2026-08-01T14:30:00Z
modified: 2026-08-10T09:15:00Z
---
```

- **title** — The name of the note. Used for linking and display.
- **type** — What kind of note this is (e.g. `note`, `meeting`, `decision`). You can use any type you want.
- **tags** — For organization and filtering.
- **permalink** — A stable identifier for this note. Generated automatically from the file's path (and prefixed with the project name by default) if you don't set one. Stays the same even if you later move the file. Every Markdown note has one — as of v0.24 there is no setting to turn permalinks off.
- **created** and **modified** — Optional authoritative timestamps for the note. When present, Basic Memory uses them for recency ordering instead of filesystem timestamps. Without `created`, a new note takes its file's creation time, and later edits, moves, and reindexes keep it.

Historical `created` or `modified` values can move a note earlier in `bm_project(command="recent")` and date-sorted search results after the note is reindexed. Use valid date or datetime values and change them only when you intend to change the note's recorded chronology.

### Keys Basic Memory manages

A few frontmatter keys have special meaning:

<table>
<thead>
  <tr>
    <th>
      Key
    </th>
    
    <th>
      What it does
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        locked: true
      </code>
    </td>
    
    <td>
      Makes the note read-only to Basic Memory's note API. Edits, overwrites, and deletes from AI tools, the CLI, and the API are refused (HTTP <code>
        423
      </code>
      
      ). See <a href="#locked-notes">
        Locked notes
      </a>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        created_by
      </code>
      
       / <code>
        updated_by
      </code>
    </td>
    
    <td>
      Who wrote the note. Stamped by the server when the runtime knows the author — in Basic Memory Cloud, for example, <code>
        <member> via <key name>
      </code>
      
       for API-key writes. Whatever a writer submits for these keys is overwritten; <code>
        created_by
      </code>
      
       is set once and carried forward. Local installs supply no author, so these keys are left untouched.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bm_parse_semantics: false
      </code>
    </td>
    
    <td>
      Keeps a note graph-silent: its body is searchable, but its observations and links don't create graph entries.
    </td>
  </tr>
</tbody>
</table>

<tip>

Frontmatter is just standard YAML. You can add any fields you want — `status`, `priority`, `author`, `due_date`, whatever is useful for your workflow. The AI can set these automatically when creating notes, and you can search by them later with metadata search. If you want to formalize which fields a note type should have, that's what [schemas](https://docs.basicmemory.com/concepts/schema-system) are for.

</tip>

---

## Observations

Observations are individual facts, decisions, or details captured as list items with a category in brackets:

```markdown
## Observations
- [decision] Using JWT tokens for stateless authentication #security
- [approach] Refresh tokens stored in HTTP-only cookies
- [constraint] Tokens expire after 15 minutes (based on security audit)
```

The pattern is: `- [category] content #optional-tags (optional context)`

Categories can be anything that makes sense for what you're capturing — `[decision]`, `[fact]`, `[preference]`, `[question]`, `[todo]`, `[risk]`, `[idea]`, whatever fits. There's no fixed list. Use what feels natural and the AI will follow your lead.

The power of observations is that each one is indexed individually. When you search your knowledge base, Basic Memory can surface the specific fact you need rather than just pointing you at a whole document. See [Semantic Search](https://docs.basicmemory.com/concepts/semantic-search) for how this works.

### When a fact holds

An observation can also say when it's true, with a date qualifier right after the category:

```markdown
- [decision] @effective:2026-06-10 The cache layer will use Redis.
- [policy] @effective[2026-01-01,2026-07-01) Weekly releases on Tuesdays
- [deadline] @due:2026-09-30 Ship the migration tooling.
```

Basic Memory indexes these dates as **valid time**, separate from when the note was written, so your AI can ask what was true on a given day: "which caching decision was in effect on July 1st?" See [When a fact holds (valid time)](https://docs.basicmemory.com/concepts/observations-and-relations#when-a-fact-holds-valid-time) for the kinds, ranges, and date formats.

<note>

Basic Memory recognizes `[category]` syntax as observations but does not treat Markdown checkbox markers such as `[ ]`, `[x]`, `[X]`, `[-]`, `[/]`, `[>]`, and `[?]`, or timestamp-shaped transcript prefixes, as categories.

</note>

For category conventions, tags, and worked examples, see the deep dive: [Observations and Relations](https://docs.basicmemory.com/concepts/observations-and-relations).

---

## Relations

Relations link notes together using `[[wiki-link]]` syntax:

```markdown
## Relations
- implements [[API Security Requirements]]
- depends_on [[User Database Schema]]
- relates_to [[Session Management]]
```

The word before the link becomes the relationship type. Like categories, you can use any relation type — `implements`, `inspired_by`, `blocks`, `part_of`, `contrasts_with`, whatever describes the connection. Quoting rules and edge cases (multi-word types, bare wikilinks) are covered in [Observations and Relations](https://docs.basicmemory.com/concepts/observations-and-relations).

You can also reference other notes inline anywhere in the document:

```markdown
This builds on the patterns established in [[Core Architecture]] and
addresses the concerns raised in [[Security Review Q4]].
```

Relations can link to notes that don't exist yet. When those notes are created later, the connections are already in place. The reverse also holds: deleting a note leaves the links that pointed at it in place as unresolved references (since v0.24), so a broken-link check still finds them, and recreating the note reconnects them.

Wikilinks inside inline code (``[[Not A Link]]``) or code blocks are treated as code and don't create relations.

### Ordinary Markdown links

Standard Markdown links to files in the same project also become graph connections (new in v0.24):

```markdown
See [the setup guide](../guides/Getting%20Started.md#installation) and
the [runbook][rb].

[rb]: /ops/Release%20Runbook.md
```

Each one creates a `links_to` relation, just like an inline wikilink. Paths resolve relative to the note that contains the link; a leading `/` means the project root. Percent-encoding is decoded, and `#fragments` and query strings don't change the target. These are exact file paths — Basic Memory doesn't guess a title or add `.md` for you — and a link to a file that doesn't exist yet stays unresolved until it does.

External URLs, `mailto:` and `file:` links, fragment-only links (`#section`), images, links inside code, and paths that climb out of the project are ignored. Your Markdown is never rewritten. To give a link a type other than `links_to`, use relation syntax with a wikilink (`- implements [[API Spec]]`). Existing notes pick up Markdown-link relations on their next edit or reindex.

### How wikilinks resolve

Basic Memory tries exact identities first: permalink, title, and file path. At the project root, a filename-stem link such as `[[alpha_note]]` can resolve `alpha_note.md` even when the note's frontmatter title is different.

A wikilink spelled as an explicit relative path — `[[../guides/Setup.md]]` or `[[./same.md]]` — follows the Markdown-link rule instead: it resolves relative to the note, and only to that exact file.

If no exact identity matches, Basic Memory can try a Unicode case-insensitive file-path alias that treats underscores and hyphens as equivalent. The fallback must identify exactly one note; `[[alpha-note]]` remains unresolved when multiple files collapse to the same alias. This forgiving lookup applies only to link resolution—writes and updates keep their exact note identity rules and never use the alias to choose a file to overwrite or move.

Directory casing is handled separately. Since v0.23.2, each destination-folder segment on a note write or move resolves to an existing folder when there is exactly one case-insensitive match, so `schemas/drafts` can land in `Schemas/Drafts`. Unknown folders are created with the requested spelling, existing case-variant siblings remain ambiguous, and the note's basename is never case-corrected by this folder rule.

For relation-type conventions and how inline references index, see [Observations and Relations](https://docs.basicmemory.com/concepts/observations-and-relations).

---

## The Knowledge Graph

Every note you write becomes a node. Every relation becomes an edge. Together, they form a knowledge graph that grows with your conversations.

This graph is what makes Basic Memory more than a folder of files. When the AI uses `bm_context`, it can follow connections across notes to pull together relevant information from across your entire knowledge base — not just the one note you asked about, but the notes it links to, and the notes that link back to it.

---

## Permalinks

Every note has a permalink — a stable identifier derived from its file path (project-prefixed by default). Permalinks are how Basic Memory addresses notes internally and how `memory://` URLs work — and by default they stay unchanged when a file is renamed or moved:

```text
memory://authentication-design
```

Permalinks stay the same even if you rename or move the file. Basic Memory writes a `permalink` into any Markdown note that arrives without one the next time it's indexed. For more on how memory URLs work, including pattern matching and graph traversal, see [Memory URLs](https://docs.basicmemory.com/concepts/memory-urls).

---

## File Organization

Organize your files however you want — the knowledge graph is built from the content of your notes, not from where they sit on disk. See [Projects and Folders](https://docs.basicmemory.com/concepts/projects-and-folders) for organizing with projects and folder structure.

<note>

`bm_write` rejects filename-convention twins instead of creating a duplicate. For example, if a folder already contains the conventional equivalent of `Project Plan.md`, writing `project-plan.md` returns an error. Read or edit the existing note, or choose a genuinely different name.

</note>

---

## Locked notes

Set the YAML boolean `locked: true` in a note's frontmatter to protect it from changes made through Basic Memory:

```yaml
---
title: Release Runbook
locked: true
---
```

Once a note is locked, writes, edits, overwrites, and deletes through the note API — which is what AI tools and `bm tool` commands use — are refused with HTTP `423` and an explanation. Deleting a directory that contains a locked note is refused before anything is deleted. Reads, search, indexing, and moves still work, and a move keeps the lock.

The lock is one-way through the API: no tool call can remove it, and replacement content or find-and-replace edits can't weaken it. To unlock a note, open the file and remove `locked: true` (or set it to `false`) — direct filesystem edits always win, and imports, which write files directly, aren't bound by the lock either. That makes it a guard against accidental AI edits, not access control. Only the boolean enables it; the string `"true"` is ordinary metadata.

---

## Documents and other files

Projects can hold more than Markdown — PDFs, images, Word and PowerPoint files, spreadsheets. Basic Memory indexes them as files you can list, read, and link to. With the optional document extras, `bm import document` extracts a PDF, Word, PowerPoint, or CSV file into a searchable Markdown note that sits next to it. See [Documents and PDFs](https://docs.basicmemory.com/concepts/documents-and-pdfs).

---

## Components in notes

In Basic Memory Cloud, notes can include `::bm-*` components — charts, tables, kanban boards, and live query views written as Markdown directives:

```markdown
::bm-bars{title="Throughput" caption="Before and after the queue rewrite"}
- Before: 42/s
- **After: 96/s**
::
```

The data lives in the body as plain Markdown, so the same note still reads as an ordinary list or table in a local editor, on GitHub, or in a raw `bm_read`. See [Live Notes](https://docs.basicmemory.com/cloud/live-notes) for every component, examples, and live query views. Components never block a write; problems are reported back so they can be fixed. The `comark(7)` manual page (`bm man comark`, or `memory://man/comark(7)` over MCP) is the quick reference, and the `memory-comark` [agent skill](https://docs.basicmemory.com/integrations/skills) teaches your AI the full component set.

---

## Open Knowledge Format (OKF)

The [Open Knowledge Format](https://github.com/GoogleCloudPlatform/open-knowledge-format) is an open spec from Google Cloud for knowledge that any agent can navigate: a folder of Markdown files with typed frontmatter, an `index.md` for each folder, and a `log.md` of changes. Basic Memory's format already fits it, and Basic Memory speaks it in two ways:

- **Index and log pages.** The [Wiki](https://docs.basicmemory.com/cloud/wiki) keeps an `index.md` in the project root and in each folder, plus a `log.md` of recent changes, current in Basic Memory Cloud as your notes change. For a local project, `bm wiki rebuild` generates the same files. The root `index.md` carries `okf_version: "0.2"`.
- **Export.** `bm okf export` writes a local project as an OKF bundle (spec version 0.2), and `bm okf check` checks any bundle against the spec.

```bash
bm okf export ~/exports/research-okf --project research
bm okf check ~/exports/research-okf
```

An export keeps each note's frontmatter, with `type` defaulting to `note`. Wikilinks become standard Markdown links, and each note's typed relations are kept in a `bm.okf_export` metadata block, so tools that only follow links still see the graph, and nothing about relation types is lost. Observations stay in the body as you wrote them. The bundle is checked before it's written, and an unchanged project produces identical files. To export a cloud project, sync it to your computer first.

See the [CLI Reference](https://docs.basicmemory.com/reference/cli-reference) for every option.

---

## Schemas

If you want consistency across certain types of notes — say, all meeting notes should include attendees and action items — you can define schemas that describe what a note type should contain. The AI will follow them automatically.

See [Schema System](https://docs.basicmemory.com/concepts/schema-system) for details.

## Agent Skills

You can teach your AI best practices for writing notes using agent skills. The `memory-notes` skill gives the AI guidance on structuring knowledge effectively. See [Agent Skills](https://docs.basicmemory.com/integrations/skills) for how to set this up.

---

## Next Steps

<card-group>
<card icon="i-lucide-link" title="Observations and Relations" to="https://docs.basicmemory.com/concepts/observations-and-relations">

Detailed patterns and examples for semantic markup.

</card>

<card icon="i-lucide-at-sign" title="Memory URLs" to="https://docs.basicmemory.com/concepts/memory-urls">

URL patterns for navigating and querying the knowledge graph.

</card>

<card icon="i-lucide-shield-check" title="Schema System" to="https://docs.basicmemory.com/concepts/schema-system">

Define structure and validation for note types.

</card>

<card icon="i-lucide-search" title="Semantic Search" to="https://docs.basicmemory.com/concepts/semantic-search">

How observations power precise, fact-level search.

</card>
</card-group>


## Sitemap

See the full [sitemap](https://docs.basicmemory.com/sitemap.md) for all pages.
