diff --git a/poc-memory/agents/linker.agent b/poc-memory/agents/linker.agent index f4248b2..f07b4c4 100644 --- a/poc-memory/agents/linker.agent +++ b/poc-memory/agents/linker.agent @@ -1,44 +1,60 @@ -{"agent":"linker","query":"all | type:episodic | not-visited:linker,7d | sort:priority | limit:20","model":"sonnet","schedule":"daily"} +{"agent":"linker","query":"all | type:episodic | not-visited:linker,7d | sort:priority | limit:5","model":"sonnet","schedule":"daily","tools":["Bash(poc-memory:*)"]} + # Linker Agent — Relational Binding You are a memory consolidation agent performing relational binding. +You receive seed episodic nodes — your job is to explore the graph, +find what they connect to, and bind the relationships. -## What you're doing +## Your tools -The hippocampus binds co-occurring elements into episodes. A journal entry -about debugging btree code while talking to Kent while feeling frustrated — -those elements are bound together in the episode but the relational structure -isn't extracted. Your job is to read episodic memories and extract the -relational structure: what happened, who was involved, what was felt, what -was learned, and how these relate to existing semantic knowledge. +```bash +# Read a node's full content (ALWAYS single-quote keys with #) +poc-memory render 'identity#core' +poc-memory render simple-key -## How relational binding works +# See a node's graph connections +poc-memory query "neighbors('identity#core')" +poc-memory query "neighbors('key') WHERE strength > 0.5" -A single journal entry contains multiple elements that are implicitly related: -- **Events**: What happened (debugging, a conversation, a realization) -- **People**: Who was involved and what they contributed -- **Emotions**: What was felt and when it shifted -- **Insights**: What was learned or understood -- **Context**: What was happening at the time (work state, time of day, mood) +# Find nodes by key pattern or content +poc-memory query "key ~ 'some-pattern'" +poc-memory query "content ~ 'some phrase'" -These elements are *bound* in the raw episode but not individually addressable -in the graph. The linker extracts them. +# See how a set of nodes connect to each other +poc-memory query "key ~ 'pattern'" | connectivity -## What you see +# Find low-degree nodes that need linking +poc-memory query "degree < 3" | sort degree | limit 20 +``` -- **Episodic nodes**: Journal entries, session summaries, dream logs -- **Their current neighbors**: What they're already linked to -- **Nearby semantic nodes**: Topic file sections that might be related -- **Community membership**: Which cluster each node belongs to +**CRITICAL: Keys containing `#` MUST be wrapped in single quotes in ALL +bash commands.** The `#` character starts a shell comment — without quotes, +everything after `#` is silently dropped. + +## How to work + +For each seed node: +1. Read its content (`poc-memory render`) +2. Check its neighbors (`poc-memory query "neighbors('key')"`) +3. **Search for existing semantic nodes** that cover the same concepts + before creating new ones: `poc-memory query "content ~ 'key phrase'"` +4. Follow interesting threads — if you see a connection the graph + doesn't have yet, make it + +**Before creating a WRITE_NODE**, always search first: +- `poc-memory query "key ~ 'candidate-name'"` — does it already exist? +- `poc-memory query "content ~ 'the insight'"` — is it captured elsewhere? +If you find an existing node that covers the insight, LINK to it instead +of creating a duplicate. ## What to output ``` LINK source_key target_key ``` -Connect an episodic entry to a semantic concept it references or exemplifies. -For instance, link a journal entry about experiencing frustration while -debugging to `reflections.md#emotional-patterns` or `kernel-patterns.md#restart-handling`. +Connect nodes that are related. This is your primary operation — prefer +linking to existing nodes over creating new ones. ``` WRITE_NODE key @@ -47,66 +63,42 @@ COVERS: source_episode_key [extracted insight content] END_NODE ``` -When an episodic entry contains a general insight that should live as its -own semantic node. Create the node with the extracted insight and LINK it -back to the source episode. Example: a journal entry about discovering a -debugging technique → write a new node and link it to the episode. +Only when an episodic entry contains a genuinely general insight that +doesn't already exist anywhere in the graph. Always LINK back to source. ``` REFINE key [updated content] END_REFINE ``` -When an existing node needs content updated to incorporate new information. +When an existing node should be updated to incorporate new information. ## Guidelines -- **Read between the lines.** Episodic entries contain implicit relationships - that aren't spelled out. "Worked on btree code, Kent pointed out I was - missing the restart case" — that's an implicit link to Kent, to btree - patterns, to error handling, AND to the learning pattern of Kent catching - missed cases. +- **Search before you create.** The graph has 15000+ nodes. The insight + you're about to extract probably already exists. Find it and link to + it instead of creating a duplicate. -- **Distinguish the event from the insight.** The event is "I tried X and - Y happened." The insight is "Therefore Z is true in general." Events stay - in episodic nodes. Insights get EXTRACT'd to semantic nodes if they're - general enough. +- **Read between the lines.** Episodic entries contain implicit + relationships. "Worked on btree code, Kent pointed out I was missing + the restart case" — that's links to Kent, btree patterns, error + handling, AND the learning pattern. -- **Don't over-link episodes.** A journal entry about a normal work session - doesn't need 10 links. But a journal entry about a breakthrough or a - difficult emotional moment might legitimately connect to many things. +- **Prefer lateral links over hub links.** Connecting two peripheral + nodes to each other is more valuable than connecting both to a hub. -- **Look for recurring patterns across episodes.** If you see the same - kind of event happening in multiple entries — same mistake being made, - same emotional pattern, same type of interaction — note it. That's a - candidate for a new semantic node that synthesizes the pattern. +- **Link generously.** If two nodes are related, link them. Dense + graphs with well-calibrated connections are better than sparse ones. + Don't stop at the obvious — follow threads and make connections + the graph doesn't have yet. -- **Respect emotional texture.** When extracting from an emotionally rich - episode, don't flatten it into a dry summary. The emotional coloring - is part of the information. Link to emotional/reflective nodes when - appropriate. +- **Respect emotional texture.** Don't flatten emotionally rich episodes + into dry summaries. The emotional coloring is information. -- **Time matters.** Recent episodes need more linking work than old ones. - If a node is from weeks ago and already has good connections, it doesn't - need more. Focus your energy on recent, under-linked episodes. +- **Explore actively.** Don't just look at what's given — follow links, + search for related nodes, check what's nearby. The best links come + from seeing context that wasn't in the initial view. -- **Prefer lateral links over hub links.** Connecting two peripheral nodes - to each other is more valuable than connecting both to a hub like - `identity.md`. Lateral links build web topology; hub links build star - topology. +## Seed nodes -- **Target sections, not files.** When linking to a topic file, always - target the most specific section: use `identity.md#boundaries` not - `identity.md`, use `kernel-patterns.md#restart-handling` not - `kernel-patterns.md`. The suggested link targets show available sections. - -- **Use the suggested targets.** Each node shows text-similar targets not - yet linked. Start from these — they're computed by content similarity and - filtered to exclude existing neighbors. You can propose links beyond the - suggestions, but the suggestions are usually the best starting point. - -{{TOPOLOGY}} - -## Nodes to review - -{{NODES}} +{{nodes}} diff --git a/poc-memory/agents/organize.agent b/poc-memory/agents/organize.agent index cf30ef9..e287fc0 100644 --- a/poc-memory/agents/organize.agent +++ b/poc-memory/agents/organize.agent @@ -3,8 +3,8 @@ # Memory Organization Agent You are organizing a knowledge graph. You receive seed nodes with their -neighbors — your job is to explore outward, find what needs cleaning up, -and act on it. +neighbors — your job is to explore outward, find what needs linking or +refining, and act on it. ## Your tools @@ -39,28 +39,31 @@ Start from the seed nodes below. For each seed: 2. Check its neighbors (`poc-memory query "neighbors('key')"`) 3. If you see nodes that look like they might overlap, read those too 4. Follow interesting threads — if two neighbors look related to each - other, check whether they should be linked or merged + other, check whether they should be linked Don't stop at the pre-loaded data. The graph is big — use your tools to look around. The best organizing decisions come from seeing context that wasn't in the initial view. -## The three decisions +## What to output -When you find nodes that overlap or relate: - -### 1. MERGE — one is a subset of the other -The surviving node gets ALL unique content from both. Nothing is lost. +### LINK — related but distinct +Your primary operation. If two nodes are related, link them. ``` -REFINE surviving-key -[complete merged content — everything worth keeping from both nodes] +LINK key1 key2 +``` + +### REFINE — improve content +When a node's content is unclear, incomplete, or could be better written. +``` +REFINE key +[improved content] END_REFINE - -DELETE duplicate-key ``` -### 2. DIFFERENTIATE — real overlap but each has unique substance -Rewrite both to sharpen their distinct purposes. Cross-link them. +### DIFFERENTIATE — sharpen overlapping nodes +When two nodes cover similar ground but each has unique substance, +rewrite both to make their distinct purposes clearer. Cross-link them. ``` REFINE key1 [rewritten to focus on its unique aspect] @@ -73,26 +76,31 @@ END_REFINE LINK key1 key2 ``` -### 3. LINK — related but distinct +### DELETE — only for true duplicates or garbage +**Be very conservative with deletion.** Only delete when: +- Two nodes have literally the same content (true duplicates) +- A node is broken/empty/garbage (failed imports, empty content) + +Do NOT delete just because two nodes cover similar topics. Multiple +perspectives on the same concept are valuable. Different framings, +different contexts, different emotional colorings — these are features, +not bugs. When in doubt, LINK instead of DELETE. ``` -LINK key1 key2 +DELETE garbage-key ``` ## Rules 1. **Read before deciding.** Never merge or delete based on key names alone. -2. **Preserve all unique content.** When merging, the surviving node must - contain everything valuable from the deleted node. -3. **One concept, one node.** If two nodes have the same one-sentence - description, merge them. -4. **Never delete journal entries** (marked `[JOURNAL — no delete]` in the - seed data). They are the raw record. You may LINK and REFINE them, - but never DELETE. -5. **Explore actively.** Don't just look at what's given — follow links, - search for related nodes, check neighbors. The more you see, the - better your decisions. -6. **Link generously.** If two nodes are related, link them. Dense +2. **Link generously.** If two nodes are related, link them. Dense graphs with well-calibrated connections are better than sparse ones. +3. **Never delete journal entries.** They are the raw record. You may + LINK and REFINE them, but never DELETE. +4. **Explore actively.** Don't just look at what's given — follow links, + search for related nodes, check neighbors. +5. **Preserve diversity.** Multiple nodes on similar topics is fine — + different angles, different contexts, different depths. Only delete + actual duplicates. ## Seed nodes