Skip to content

Commit 373fc4e

Browse files
Ubuntuclaude
andcommitted
feat: add persistent auto-memory system
Implement a file-based persistent memory system that allows the AI to retain knowledge about users, feedback, projects, and references across sessions. Memory files use YAML frontmatter with markdown body, stored at ~/.claw/projects/<workspace-hash>/memory/. Key components: - MemoryStore data layer with FNV-1a workspace fingerprinting - MemoryRead/MemoryWrite tools with security hardening (path traversal, symlink, absolute path, and size limit protections) - System prompt injection of MEMORY.md index with prompt injection mitigation (fenced code block + trust-lowering notice) - autoMemoryEnabled config option (defaults to true) - Doctor health check for auto-memory state - /memory command enhancement showing persistent memory info Tested end-to-end with Zhipu GLM-4-Flash via OpenAI-compatible routing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d229a9b commit 373fc4e

9 files changed

Lines changed: 881 additions & 11 deletions

File tree

rust/crates/commands/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ const SLASH_COMMAND_SPECS: &[SlashCommandSpec] = &[
138138
SlashCommandSpec {
139139
name: "memory",
140140
aliases: &[],
141-
summary: "Inspect loaded Claude instruction memory files",
141+
summary: "Show instruction files and persistent auto memory",
142142
argument_hint: None,
143143
resume_supported: true,
144144
},

rust/crates/runtime/src/config.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ pub struct RuntimeFeatureConfig {
163163
api_timeout: ApiTimeoutConfig,
164164
rules_import: RulesImportConfig,
165165
provider: RuntimeProviderConfig,
166+
auto_memory_enabled: bool,
166167
}
167168

168169
/// Controls which external AI coding framework rules are imported into the system prompt.
@@ -801,6 +802,7 @@ fn build_runtime_config(
801802
api_timeout: parse_optional_api_timeout_config(&merged_value)?,
802803
rules_import: parse_optional_rules_import(&merged_value)?,
803804
provider: parse_optional_provider_config(&merged_value)?,
805+
auto_memory_enabled: parse_auto_memory_enabled(&merged_value),
804806
};
805807

806808
Ok(RuntimeConfig {
@@ -826,7 +828,10 @@ impl RuntimeConfig {
826828
Self {
827829
merged: BTreeMap::new(),
828830
loaded_entries: Vec::new(),
829-
feature_config: RuntimeFeatureConfig::default(),
831+
feature_config: RuntimeFeatureConfig {
832+
auto_memory_enabled: true,
833+
..RuntimeFeatureConfig::default()
834+
},
830835
}
831836
}
832837

@@ -1012,6 +1017,11 @@ impl RuntimeFeatureConfig {
10121017
&self.rules_import
10131018
}
10141019

1020+
#[must_use]
1021+
pub fn auto_memory_enabled(&self) -> bool {
1022+
self.auto_memory_enabled
1023+
}
1024+
10151025
/// Merge this config's default trusted roots with per-call roots.
10161026
#[must_use]
10171027
pub fn trusted_roots_with_overrides(&self, per_call_roots: &[String]) -> Vec<String> {
@@ -2172,6 +2182,13 @@ fn parse_optional_provider_config(root: &JsonValue) -> Result<RuntimeProviderCon
21722182
})
21732183
}
21742184

2185+
fn parse_auto_memory_enabled(root: &JsonValue) -> bool {
2186+
root.as_object()
2187+
.and_then(|object| object.get("autoMemoryEnabled"))
2188+
.and_then(JsonValue::as_bool)
2189+
.unwrap_or(true)
2190+
}
2191+
21752192
fn parse_filesystem_mode_label(value: &str) -> Result<FilesystemIsolationMode, ConfigError> {
21762193
match value {
21772194
"off" => Ok(FilesystemIsolationMode::Off),

rust/crates/runtime/src/config_validate.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ const TOP_LEVEL_FIELDS: &[FieldSpec] = &[
220220
name: "subagentModel",
221221
expected: FieldType::String,
222222
},
223+
FieldSpec {
224+
name: "autoMemoryEnabled",
225+
expected: FieldType::Bool,
226+
},
223227
];
224228

225229
const HOOKS_FIELDS: &[FieldSpec] = &[

rust/crates/runtime/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub mod mcp_lifecycle_hardened;
2727
pub mod mcp_server;
2828
mod mcp_stdio;
2929
pub mod mcp_tool_bridge;
30+
pub mod memory_store;
3031
mod oauth;
3132
pub mod permission_enforcer;
3233
mod permissions;
@@ -123,6 +124,7 @@ pub use mcp_stdio::{
123124
McpTool, McpToolCallContent, McpToolCallParams, McpToolCallResult, McpToolDiscoveryReport,
124125
UnsupportedMcpServer,
125126
};
127+
pub use memory_store::{MemoryEntry, MemoryStore, MemoryType};
126128
pub use oauth::{
127129
clear_oauth_credentials, code_challenge_s256, credentials_path, generate_pkce_pair,
128130
generate_state, load_oauth_credentials, loopback_redirect_uri, parse_oauth_callback_query,

0 commit comments

Comments
 (0)