ReMe/reme2/memory/protocol.md
huangsen dd2de16481 ```
feat(file_watcher): add directory deletion support with descendant indexing

Add support for deleting entire directories and their indexed descendants
in the file watcher. Previously only individual file deletions were
handled properly. Now when a directory is deleted, the system finds all
indexed files beneath that directory path and removes them along with
their metadata and chunks.

The implementation includes:
- New `_descendant_indexed_paths` method to find all indexed files
  under a given directory path
- Updated `_on_deleted` method to process both the target path and
  all its indexed descendants
- Proper handling of symlinks and path resolution differences
- Enhanced logging to show directory deletion with child count

Also adds necessary os import for path operations.

refactor(config): restructure configuration profiles for clarity

Rename curated.yaml to remove outdated configuration file and
rename full.yaml to expert.yaml with updated documentation.
Add new service.yaml configuration profile that provides a
service-aligned MCP surface with three main tools:
- retrieve: graph-aware hybrid retrieval
- remember: single write entry point with log/distill modes
- maintain: vault hygiene sweep

The expert configuration now excludes the ingest tool since
cold-path operations are handled by external agents, and adds
memory_lint tool for structural issue detection.

Updated documentation to clarify the different configuration
profiles and their intended usage patterns.
```
2026-05-11 10:52:25 +08:00

6.6 KiB

Memory Protocol

Single source of truth for vault schema, conventions, and the R-M-W write loop. Consumed by:

  • Ingestor's embedded ReAct prompt (reme2/memory/ingestor.yaml — injected as {protocol} at load time).
  • Strong-agent SKILL (reme-plugin/skills/reme/SKILL.md — transcluded so the host agent sees the same rules).

Anything that defines schema invariants, path templates, write tool semantics, or the R-M-W decision tree belongs here. Anything role- specific (caller framing, audit trail expectations, summary requirements) stays in the consumer.

Vault layout

  • Topics — long-lived cognitive memory at topics/{folder}/{name}.md. A folder topic has folder == name; it's the cluster's index head. Short wikilink [[X]] resolves to the folder topic if one exists, else falls back to a unique same-stem file.
  • Events — fact log of one session at events/{YYYY-MM-DD}/{name}/{name}.md. The .md is the index inside a folder; sibling files are materials (raw conversation, tool outputs, data dumps). The index lists them under ## Materials.

Frontmatter — 4 schema axes

Every memory declares 4 orthogonal axes. The legacy category field is auto-translated to these axes for back-compat reads, but new writes should set the axes directly.

Axis Values Meaning
lifecycle streaming / evolving / frozen streaming = events (decay/archive); evolving = topics (long-lived, edited); frozen = materials (immutable references)
scope instance / class instance = a specific moment / object; class = abstract concept / role / pattern
source auto / curated / derived auto = system-captured; curated = human/LLM intent; derived = computed from other memories
role observation / claim / question / profile / concept / method / reference / fundamentals cognitive role — drives ranking + role-specific validation

Conditional fields

  • confidence ∈ {, , } — REQUIRED when role: claim (legacy categories thesis / model). Same gate applies to role: question (legacy questions).
  • status ∈ {active, distilled, archived} — meaningful only for lifecycle: streaming. Topic-style memories ignore it.
  • originSessionId — should be set when source: auto.

Standard identity fields

title, description, tags, created, updated, topics, parent. Use today's date for created / updated on new writes.

Cross-file references

[[wikilink]] syntax. Two forms:

  • Stem form [[X]] — resolved against the file_store's stem index; prefers the folder topic if one exists.
  • Path form [[topics/X/X]] or [[topics/X/X.md]] — anchored at the vault root.

Status state machine

active → distilled → archived (single direction, no skip). A reverse or skip transition will be flagged by the Maintainer.

Every create path routes through MemoryCreate.write, which refuses to introduce ambiguity (existing [[X]] would resolve to ≥2 paths). When rejected, the response includes a suggested_name. Retry with that, or pick a domain-specific qualifier (Apple-Inc beats Apple-2). Never bypass with force=true unless you fully understand the ambiguity.

Available tools

Read tools (gather context BEFORE writing)

  • memory_get(path, include_chunks=False) — full file content + frontmatter. On an event index, follow ## Materials and read each artifact whose content you need.
  • memory_list(path_prefix=None, tags=None, metadata=None, limit=100) — list indexed files filtered by prefix / tags / frontmatter.
  • memory_resolve_wikilink(wikilink) — resolve [[X]] to a path; flags ambiguity / dangling.
  • memory_backlinks(path) — files linking TO the given path.
  • memory_links(path) — files the given path links to.
  • memory_search(query, …) — hybrid (vector + keyword) chunk search.
  • memory_graph_search(query, seeds, graph_depth, …) — vector + keyword + graph BFS fusion.

Write tools (mutations are SSOT-routed; each returns success +

payload + records to audit)

  • memory_update(path, old_string, new_string, replace_all=False) — body edit by exact-string substitution. Use a tail snippet to append.
  • memory_property_update(path, key, value) — change one frontmatter key (value=null deletes). Use this to flip status.
  • memory_create(path, metadata, content, overwrite=False, force=False) — new file. Reserve for genuinely NEW topics. Do NOT use for events (sync owns events). All paths must be ABSOLUTE under vault_root.
  • memory_rename(old_path, new_path) — move file + rewrite cross-vault wikilinks. Refuses on destination conflict or stem ambiguity.
  • memory_delete(path) — remove a file.
  • memory_archive(path) — flip status: archived and move under <vault>/Archive/.

Hot-write helper (deterministic, no LLM)

  • sync(name, description?, content?, topics?, tags?, materials?, on_date?) — idempotent upsert of an event FOLDER per (date, name). Reuse the same name across calls in one thread to keep extending the same folder. Refuses on status: distilled / archived and returns a suggested_name.

R-M-W decision rules

Apply in order. Stop at the first match.

  1. SKIP — if material is ALREADY covered by existing topics, reply with a single line SKIP: <one-line reason> and call no tools.
  2. CONTRADICT — if material CONTRADICTS an existing block, use memory_update with a unique snippet of the outdated text and the corrected replacement.
  3. EXTEND — if material EXTENDS an existing topic, use memory_update with a unique TAIL snippet of the existing body, and new_string = tail + blank line + new content.
  4. CREATE — if material warrants a GENUINELY NEW topic, use memory_create at topics/{folder}/{name}.md. Do NOT memory_create under events/sync owns that path.
  5. STATUS FLIP — after integrating an event's content into a topic, flip that event's status to distilled with memory_property_update.

Operating principles

  • Read before write. Always inspect related topics before deciding CONTRADICT vs EXTEND vs CREATE. The wikilink-uniqueness gate refuses blind creates; reading first prevents wasted attempts.
  • Minimal edits. Edit only what must change. Don't restructure while updating content.
  • Frontmatter on create. Always include reasonable frontmatter: the 4 axes, title, created, updated, plus confidence when role: claim or role: question.
  • Never delete unless asked. Distillation flips status; it does not remove events.