Skip to content

write-note: add explicit --type arg; lock in content-frontmatter note_type with an integration test #875

Description

@phernandez

Background

The Claude Code memory-bridge plugin (#865) writes typed notes — type: session checkpoints, type: schema/decision seeds — through basic-memory tool write-note, relying on Basic Memory deriving note_type from the leading content frontmatter (services/entity_service.py:322-323 on create, 607-608 on update).

A Codex review on #865 (review 4397262976) flagged this as broken (P1) — believing the type is stripped and note_type defaults to note. It's a false positive (verified by reproduction + the code path; the cited markdown/utils.py:108-116 runs after the derivation). But settling it required a manual repro, and it exposed two real gaps worth fixing:

  1. The behavior is implicit and fragile. The CLI write-note has no way to set note_type directly, so the plugin hooks depend on frontmatter derivation rather than stating intent.
  2. It's untested. Nothing asserts the round-trip, which is exactly why the reviewer and the implementation disagreed.

Part 1 — write-note should accept an explicit --type (note_type)

The MCP write_note tool has a note_type param (src/basic_memory/mcp/tools/write_note.py:42), but the CLI basic-memory tool write-note exposes only --title/--folder/--content/--tags/--project/--project-id. Add the missing flag.

  • Add --type (note_type) to the tool write-note CLI command, passed through to write_note(note_type=...).
  • Define precedence when both an explicit --type and a content-frontmatter type are present (suggest: explicit --type wins; content frontmatter remains the fallback when --type is omitted, preserving today's behavior).
  • Update the plugin's PreCompact hook to pass --type session explicitly instead of relying on embedded frontmatter (plugins/claude-code/hooks/pre-compact.sh).
  • Update the setup skill's schema-seed step and /basic-memory:share to pass note_type explicitly via the MCP write_note(note_type=...) (they currently rely on content frontmatter). plugins/claude-code/skills/{setup,share}/.

Part 2 — Integration test: note_type round-trips

Lock in the behavior the review questioned so a future entity_service change can't silently break the memory bridge (and so reviewers/bots have ground truth).

  • Write a note whose content frontmatter is type: session (no explicit note_type) → assert the persisted entity has note_type == "session" and search_notes(metadata_filters={"type": "session"}) returns it.
  • Same for type: schema → assert it's found by the note_type == "schema" path and resolves via schema_validate.
  • After Part 1: assert an explicit --type sets note_type, and cover the precedence rule above.
  • (Optional) plugin smoke: a PreCompact-style checkpoint is found by the SessionStart --type session query.

Why both

Part 1 turns an implicit dependency into a first-class, explicit option for callers. Part 2 turns the behavior into a guaranteed contract. Together they would have pre-empted the entire #865 review back-and-forth.

Refs: #865, codex review 4397262976.

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