Skip to content

feat: typed records and relations (knowledge base, sub-project 1) - #10

Merged
qdequele merged 14 commits into
mainfrom
qdequele/knowledge-graph
Oct 9, 2026
Merged

qdequele merged 14 commits into
mainfrom
qdequele/knowledge-graph

Conversation

@qdequele

@qdequele qdequele commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Why

memd stored only flat text. This adds structured knowledge: the companies, teams, people, projects, products, services, customers and concepts in the user's world, plus typed relations between them, so any agent can ask "what is Lumen, what depends on it, who owns it?" and get one structured answer. memd stays model-free: agents supply names and relations; the crawler adds one project entity per git repository.

Stacked on #9 (base qdequele/memory-quality); retarget to main once #9 merges.

Spec: docs/superpowers/specs/2026-10-08-typed-records-and-relations-design.md · Plan: docs/superpowers/plans/2026-10-09-typed-records-and-relations.md

What changed

  • Entities are memories with type = entity and flattened, filterable knowledge fields (name, aliases, kind_of, owner, status, entities, …). Ids are entity_<slug>; saving under a name or an alias updates one record (passed fields overwrite, absent ones are kept, aliases/tags union).
  • Relations live in a new memory_relations index, one document per directed edge. Unknown names become stub entities so an edge always lands.
  • MCP (additive): save_entity, explore (entity + relations both ways + related entities + mentioning memories, depth ≤ 2), forget_relation; save_memory/update_memory accept entities and relations; get_memory/list_memories filter by entity, status, kind_of. Vocabularies come from one set of constants.
  • Crawler creates a project entity per git repository (README heading + first paragraph), links crawled files and scoped memories to it, never overwrites an agent's entity, adopts stubs and path-less agent projects, and lets a moved repo keep its id.
  • CLI: memd entity, memd entity add, memd relate, memd unrelate, search --entity --status --kind-of; memd context opens with one line about the current project; doctor --fix back-fills project links.

Departures from the spec (engine constraints)

  1. Ids use entity_, not entity: — Meilisearch ids allow only A-Za-z0-9-_.
  2. The embedder template is unchanged — the engine fails tasks for documents missing a template field; aliases reach the embedder through an "Also known as" line in content.
  3. Resolution is id-first and global; only alias ties use the scope chain — otherwise a stub could overwrite an entity defined in another project.
  4. An entity's description lives in the existing summary field.
  5. id is filterable so explore fetches neighbours in one request.

Verification

  • cargo fmt --check, cargo clippy --all-targets -D warnings, cargo test — 141 passed.
  • Live against a local engine: alias merge, relations, stubs, explore depth 2, entity-linked memory with automatic project link, project entity output, doctor --fix back-fill; test records removed afterwards. Re-crawl after the fix pass: 0 indexed, 0 deleted, 0 errors (ids stable).
  • A fresh whole-branch review found 1 Critical (crawler could overwrite an agent's entity whose id matched a repo name) and 7 Important issues; all fixed test-first.

Deferred minors: relation created_at lost on fetch error; id-shaped unknown names; raw content edits on entities; --reset can swap colliding project ids; stats/history descriptions; docs/cli.mdx/crawler.mdx coverage; two escaping helpers; watcher re-links only on reconcile.

🤖 Generated with Claude Code

@qdequele
qdequele added this pull request to stack #11 October 9, 2026 08:08
Base automatically changed from qdequele/memory-quality to main October 9, 2026 08:08
…ore writing

- Crawler consults every entity: an agent's non-project entity blocks its id
  for repositories; stubs and path-less agent projects are adopted (the
  latter get their path); a moved repository reclaims its id; a failed
  entity fetch aborts the scan instead of disabling the protection.
- save_entity validates kind and name before any write; relate rejects
  self-relations and empty predicates before stubbing either end.
- A deduplicated save_memory still adds the entity links it asked for.
- memd context no longer injects entities as memories.
- update_memory's description no longer promises an automatic project link.
@qdequele
qdequele force-pushed the qdequele/knowledge-graph branch from e63b087 to f815d76 Compare October 9, 2026 08:08
@qdequele
qdequele merged commit 773a498 into main Oct 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant