Skip to content

[FEATURE] opt-in Open Knowledge Format (OKF) conformance for the note format #1246

Description

@paulsen-it

Summary

Basic Memory's on-disk format is already very close to Google Cloud's Open Knowledge Format (OKF, published June 2026, now at v0.2). One syntactic difference prevents an OKF consumer from seeing the knowledge graph: relations are expressed as wikilinks, while OKF specifies cross-links as standard inline Markdown links.

This request proposes an opt-in setting that lets Basic Memory read and write relations as standard Markdown links, so a Basic Memory project is directly consumable as an OKF bundle without conversion — and an OKF bundle produced elsewhere is directly consumable by Basic Memory.

Default behaviour would not change.

Why this matters

OKF is a format, not a runtime: a directory of Markdown files with YAML frontmatter, exactly one required frontmatter field (type), standard inline Markdown links for cross-references, and two reserved filenames (index.md for directory listings / progressive disclosure, log.md for change history). Consumers must tolerate unknown types, missing optional fields, unknown frontmatter keys, and broken cross-links.

That is a near-exact description of what Basic Memory already produces. Supporting it would mean:

  • Portability without a migration project. A knowledge base written by Basic Memory could be handed to any OKF-aware consumer, and vice versa. This is the same "no lock-in, plain Markdown, your files" promise already in the README, extended to a published interoperability surface.
  • Producer/consumer independence. Basic Memory becomes an OKF producer (agent-maintained bundles) and an OKF consumer (import hand-authored or pipeline-generated bundles). Given that this repo already ships host-native packages for Claude Code, Codex, Hermes, and OpenClaw, speaking a vendor-neutral knowledge format seems aligned with the project's direction.
  • Ecosystem timing. OKF is young (v0.1 → v0.2 within weeks), and other memory tools have started adopting it natively. Early support is cheap now and gets more expensive once bundles exist in the wild.

Current state

What already conforms, as far as I can tell from the docs and tests:

OKF requirement Basic Memory today
Directory of Markdown files with YAML frontmatter Yes
Non-empty type field on every concept document Yes — note_type, default note, arbitrary values supported (the parser tests use type: component)
Recommended fields title, tags Yes
Consumers must preserve unknown frontmatter keys Yes — custom frontmatter is retained in entity_metadata
Cross-links as standard inline Markdown links No — relations require [[wikilinks]]; the parser explicitly excludes [text](url)
Reserved index.md / log.md not treated as concept documents No — but .bmignore / project .gitignore already provide a workaround

So the gap is narrow and specific.

Proposed change

1. Relation link style (the core of the request)

A config setting, e.g.:

{ "relation_link_style": "wikilink" }

with values wikilink (default, current behaviour), markdown, or both (parse either, write the configured preferred form).

In markdown mode, the relation form becomes:

## Relations
- implements [OAuth Implementation](../auth/oauth-implementation.md) (Core auth flows)
- uses [Redis Cache](../infra/redis-cache.md) (Token caching)

Why keep the relation type as a list-item prefix. OKF has no notion of typed relations, so the type has to live somewhere. Keeping it exactly where it is today — as a bare prefix before the link — means:

  • An OKF consumer sees a plain inline Markdown link inside a list item. Fully conformant, traversable, no spec extension needed.
  • Basic Memory reads the prefix as the relation type, as it does now.
  • Round-trips are lossless in both directions, and the parser change is confined to link syntax rather than the relation model.
    The same reasoning applies to the existing bare and prose link forms that index as links_to.

Implementation looks localised: the relation syntax handling appears to live in src/basic_memory/markdown/entity_parser.py, with a clear test pattern to extend in tests/markdown/test_entity_parser.py. Adding one recognised form next to the existing ones seems tractable; the writer side needs the same switch so notes are emitted in the configured style.

2. Reserved filenames (small, optional)

OKF reserves index.md and log.md; they must not be treated as concept documents, and frontmatter is only permitted in a bundle-root index.md (where okf_version may be declared). Today Basic Memory would index them as entities and add permalink frontmatter, which breaks conformance.

.bmignore already solves this, so this is a convenience rather than a blocker: when OKF mode is active, skip reserved filenames by default instead of requiring users to remember the ignore entry.

3. Generation and validation (nice to have, clearly out of core scope)

Lower priority and easy to do externally, listed only for completeness:

  • bm export okf / bm okf check — emit or validate a bundle against the v0.2 structural conformance rules (parseable YAML, non-empty type on concept documents, reserved-file structure).
  • Optional generation of index.md per folder from title / description frontmatter, and log.md from git history.
    I'd be happy to keep this part outside the project as a separate script if you'd rather not own it.

Backward compatibility

Default stays wikilink; existing vaults, Obsidian workflows, and the [[...]] aliasing syntax are unaffected. both gives existing users a non-destructive migration path: parse either form, keep writing whichever they prefer.

Alternatives considered

  • External converter. Works, but the graph then has to be maintained in two syntaxes, and the semantic index inside Basic Memory still can't traverse the OKF form. Fine as a stopgap, not a solution.
  • Maintaining a fork. Given AGPL-3.0 and network use, upstreaming is both the cleaner and the less burdensome route, which is why I'm opening this rather than patching quietly.
  • Extending OKF with a typed-relation field. Unnecessary — the list-item prefix already fits inside the spec as published.

Happy to contribute

If the direction sounds acceptable, I'm willing to open a PR for item 1 (and item 2 if wanted), with tests. I'd rather agree on the config shape and the exact relation syntax first than send an unsolicited patch.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions