Skip to content

Use frontmatter to enforce validation and set conditional (read-only / team-scoped) permissions #993

@groksrc

Description

@groksrc

Motivation

Basic Memory already treats frontmatter as a first-class control surface: type drives schema resolution, and any custom key is captured as entity_metadata and indexed. The schema system (Picoschema validation, inference, drift) reads from there too. Two capabilities are a natural extension of that surface and are worth landing — or at least designing the frontmatter contract for — in the v1.0 window, since both touch the write path:

  1. Tighter validation — make schema validation enforce-able from frontmatter, not just advisory.
  2. Conditional permissions — let frontmatter mark a note (or type) as read-only / locked so agents can't silently edit or delete it.

Both are "the file is the source of truth" features: the rule travels with the note, survives moves, and works in git without a side database.

Part 1 — Frontmatter-driven validation

Today validation is advisory (schema_validate reports warnings/errors but writes still go through). Proposal:

  • A note's schema (inline schema: dict, a schema: reference, or the implicit type schema) can declare required fields and enforcement level.
  • On write_note / edit_note, the write path consults that schema. At minimum surface violations back to the agent in the tool result; optionally reject writes that violate a schema marked enforce: true.
  • Keep the default non-breaking (warn, don't block) so existing notes/imports don't start failing; enforcement is opt-in per type/note.

This turns the existing ValidationReport machinery into something that can guard the write path instead of only being run on demand.

Part 2 — Conditional permissions (write/edit protection)

Let frontmatter declare that a note is protected, e.g.:

---
title: Release Process
type: runbook
locked: true          # or: permissions: read-only
---

When a note is locked / read-only, edit_note and delete_note (and overwriting write_note) refuse the operation and return a clear, actionable message ("this note is marked read-only in frontmatter; remove locked: true to edit"). This is the single most useful case: stable runbooks, canonical references, and decision records that an agent should not casually rewrite.

Open questions to settle in design:

  • Note-level vs type-level (schema) declaration — likely support both, note-level wins.
  • Whether the lock can be lifted by an agent editing the frontmatter itself (escape hatch vs. genuine guard) — probably a config/flag decision.
  • Interaction with imports and move_note (move should still be allowed; content edit should not).

Part 3 — Teams extension (forward-looking, may be a separate issue)

For Basic Memory Teams, the same frontmatter permission surface generalizes from a binary lock to scoped read / write / edit grants applied to agents, users, or groups:

---
permissions:
  read: [team:research, alice]
  write: [alice]
  edit: [alice]
---

This is out of scope for the single-user v1.0 core but the frontmatter contract designed in Parts 1–2 should not paint us into a corner — the permissions: key should be shaped so the team-scoped form is a superset of the local read-only form, not a redesign.

Non-goals (for the v1.0 core)

  • Full ACL enforcement / identity model — that's the Teams extension.
  • Encryption or hiding note content on disk — this is operation-gating at the MCP/CLI layer, the file stays plain markdown.
  • Changing the default behavior for existing notes (validation stays advisory unless opted in; notes without a lock key behave exactly as today).

Why v1.0

Both parts establish a frontmatter contract (enforce, locked/permissions) that's hard to change later once notes in the wild use it. Settling the key names and the precedence rules during the breaking-change window — even if Teams enforcement ships afterward — is the cheap moment to do it.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestv1.0Targeted for the v1.0 release
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions