Skip to content

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions