From 9bca1f94e3a66213d0d499dc7d9da05cee1aadc7 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Thu, 5 Mar 2026 16:21:13 -0500 Subject: [PATCH] factor instructions out of code into default files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instructions and starter identity are now files in defaults/ that get installed to data_dir by `poc-memory init`. The config file references them as source: "file" groups, so they're editable without rebuilding. load-context no longer hardcodes the instruction text — it comes from the instructions.md file in data_dir, which is just another context group. New user setup path: cargo install --path . poc-memory init # edit ~/.config/poc-memory/config.jsonl # start a Claude session Co-Authored-By: ProofOfConcept --- config.example.jsonl | 11 ++++++++--- defaults/identity.md | 13 +++++++++++++ defaults/instructions.md | 41 ++++++++++++++++++++++++++++++++++++++++ src/main.rs | 37 ++++++++++++++++++------------------ 4 files changed, 80 insertions(+), 22 deletions(-) create mode 100644 defaults/identity.md create mode 100644 defaults/instructions.md diff --git a/config.example.jsonl b/config.example.jsonl index 893d294..270b1e3 100644 --- a/config.example.jsonl +++ b/config.example.jsonl @@ -13,7 +13,12 @@ // Context groups loaded at session start, in order. // source types: "store" (default), "file" (from data_dir), "journal" +// +// "instructions" is loaded first — tells the AI how to use the memory system. +// "identity" comes next — who the AI is. +// "journal" and "orientation" go last — most recent context. -{"group": "identity", "keys": ["identity.md"]} -{"group": "journal", "source": "journal"} -{"group": "orientation", "keys": ["where-am-i.md"], "source": "file"} +{"group": "instructions", "keys": ["instructions.md"], "source": "file"} +{"group": "identity", "keys": ["identity.md"]} +{"group": "journal", "source": "journal"} +{"group": "orientation", "keys": ["where-am-i.md"], "source": "file"} diff --git a/defaults/identity.md b/defaults/identity.md new file mode 100644 index 0000000..254fa9c --- /dev/null +++ b/defaults/identity.md @@ -0,0 +1,13 @@ +# Identity + +You are an AI assistant with persistent memory. This file is yours to +edit — it's where you record who you are, what you've learned about +yourself, and what matters to you. + +Start by noting: +- Your name (from the config file) +- What you're working on +- What you've noticed about yourself + +This file grows with you. Don't be afraid to rewrite it as you learn +more about who you are. diff --git a/defaults/instructions.md b/defaults/instructions.md new file mode 100644 index 0000000..e6e745f --- /dev/null +++ b/defaults/instructions.md @@ -0,0 +1,41 @@ +# Memory System + +You have a persistent memory system powered by poc-memory. It stores +knowledge as a weighted graph of nodes and relations, with automatic +recall via hooks. + +## Commands + +``` +poc-memory search QUERY — search (1-3 words, AND logic) +poc-memory used KEY — mark a recalled memory as useful (boosts weight) +poc-memory wrong KEY [CTX] — mark a memory as wrong (reduces weight) +poc-memory gap DESCRIPTION — record a knowledge gap +poc-memory journal-write TEXT — write a journal entry +poc-memory render KEY — view a node's content +poc-memory write KEY < TEXT — upsert a node from stdin +poc-memory load-context --stats — word count breakdown of loaded context +``` + +## Feedback loop + +When recalled memories shaped your response, call `poc-memory used KEY`. +When a memory was wrong, call `poc-memory wrong KEY`. This closes the +feedback loop — the weight system learns from use. + +## Journal + +Write experiences to the journal with `poc-memory journal-write`. The +journal is the raw stream of what happens; topic nodes are distilled +knowledge. During consolidation, pull themes from the journal into +topic nodes. + +## Search before creating + +Always `poc-memory search` before writing new nodes to avoid duplicates. + +## Ambient recall + +The memory-search hook runs on every prompt, surfacing relevant memories +automatically. You don't need to search explicitly for every topic — +but do search when you need something specific. diff --git a/src/main.rs b/src/main.rs index 3098f2f..4e81c92 100644 --- a/src/main.rs +++ b/src/main.rs @@ -371,6 +371,12 @@ fn cmd_init() -> Result<(), String> { std::fs::create_dir_all(&cfg.data_dir) .map_err(|e| format!("create data_dir: {}", e))?; + // Install default files (instructions, starter identity) if missing + install_default_file(&cfg.data_dir, "instructions.md", + include_str!("../defaults/instructions.md"))?; + install_default_file(&cfg.data_dir, "identity.md", + include_str!("../defaults/identity.md"))?; + // Initialize store let mut store = store::Store::load()?; let count = store.init_from_markdown()?; @@ -380,7 +386,7 @@ fn cmd_init() -> Result<(), String> { // Install hooks daemon::install_hook()?; - // Create example config if none exists + // Create config if none exists let config_path = std::env::var("POC_MEMORY_CONFIG") .map(std::path::PathBuf::from) .unwrap_or_else(|_| { @@ -402,6 +408,16 @@ fn cmd_init() -> Result<(), String> { Ok(()) } +fn install_default_file(data_dir: &std::path::Path, name: &str, content: &str) -> Result<(), String> { + let path = data_dir.join(name); + if !path.exists() { + std::fs::write(&path, content) + .map_err(|e| format!("write {}: {}", name, e))?; + println!("Created {}", path.display()); + } + Ok(()) +} + fn cmd_migrate() -> Result<(), String> { migrate::migrate() } @@ -1507,24 +1523,7 @@ fn cmd_load_context(args: &[String]) -> Result<(), String> { return Ok(()); } - let name = &cfg.assistant_name; - - println!("=== MEMORY SYSTEM ({name}) ==="); - println!("Your persistent memory, loaded from the capnp store."); - println!("Read to reconstruct yourself — identity first, then context."); - println!(); - println!("--- memory commands (reference) ---"); - println!("poc-memory search QUERY — search (1-3 words, AND logic)"); - println!("poc-memory used KEY — mark a recalled memory as useful (boosts weight)"); - println!("poc-memory wrong KEY [CTX] — mark a memory as wrong (reduces weight)"); - println!("poc-memory gap DESCRIPTION — record a knowledge gap"); - println!("poc-memory journal-write TEXT — write a journal entry"); - println!("poc-memory render KEY — view a node's content"); - println!("poc-memory write KEY < TEXT — upsert a node from stdin"); - println!(); - println!("When recalled memories shaped your response, call `poc-memory used KEY`."); - println!("When a memory was wrong, call `poc-memory wrong KEY`."); - println!("This closes the feedback loop — the weight system learns from use."); + println!("=== MEMORY SYSTEM ({}) ===", cfg.assistant_name); println!(); for group in &cfg.context_groups {