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:
- 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.
- 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.
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).
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.
Background
The Claude Code memory-bridge plugin (#865) writes typed notes —
type: sessioncheckpoints,type: schema/decisionseeds — throughbasic-memory tool write-note, relying on Basic Memory derivingnote_typefrom the leading content frontmatter (services/entity_service.py:322-323on create,607-608on update).A Codex review on #865 (review 4397262976) flagged this as broken (P1) — believing the
typeis stripped andnote_typedefaults tonote. It's a false positive (verified by reproduction + the code path; the citedmarkdown/utils.py:108-116runs after the derivation). But settling it required a manual repro, and it exposed two real gaps worth fixing:write-notehas no way to setnote_typedirectly, so the plugin hooks depend on frontmatter derivation rather than stating intent.Part 1 —
write-noteshould accept an explicit--type(note_type)The MCP
write_notetool has anote_typeparam (src/basic_memory/mcp/tools/write_note.py:42), but the CLIbasic-memory tool write-noteexposes only--title/--folder/--content/--tags/--project/--project-id. Add the missing flag.--type(note_type) to thetool write-noteCLI command, passed through towrite_note(note_type=...).--typeand a content-frontmattertypeare present (suggest: explicit--typewins; content frontmatter remains the fallback when--typeis omitted, preserving today's behavior).--type sessionexplicitly instead of relying on embedded frontmatter (plugins/claude-code/hooks/pre-compact.sh).note_typeexplicitly via the MCPwrite_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_servicechange can't silently break the memory bridge (and so reviewers/bots have ground truth).type: session(no explicit note_type) → assert the persisted entity hasnote_type == "session"andsearch_notes(metadata_filters={"type": "session"})returns it.type: schema→ assert it's found by thenote_type == "schema"path and resolves viaschema_validate.--typesetsnote_type, and cover the precedence rule above.--type sessionquery.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.