Skip to content

Commit 15a4deb

Browse files
mrapclaude
andcommitted
sanitize(memory): strip personal data from hex-foundation
Caught during a post-release review — three personalization leaks slipped past Gate 4's sanitize-check (the check doesn't scan test fixtures or comments): 1. provider.rs hex_root() fallback was the hardcoded path /Users/mrap/hex. Now uses $HOME/hex (or /tmp/hex as last resort), matching the rest of the codebase's $HOME-relative pattern. 2. recall.rs test fixture used person:whitney / 'Mike\'s wife'. Renamed to person:alice / 'a sample person'. 3. recall.rs comments + slug-boost examples used "whitney" / "whitney-chew". Renamed to "alice" / "alice-johnson". Note: there is still substantial pre-existing personalization elsewhere in the codebase (mrap-hex paths in ~8 files, hardcoded /Users/mrap/... in integration modules, mrap-dev GCP project) — out of scope for this commit but worth a dedicated sanitize pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4a7f0ac commit 15a4deb

2 files changed

Lines changed: 9 additions & 9 deletions

File tree

system/harness/src/memory/provider.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ impl std::error::Error for ProviderError {}
2323
pub fn hex_root() -> PathBuf {
2424
env::var("HEX_DIR")
2525
.map(PathBuf::from)
26-
.unwrap_or_else(|_| PathBuf::from("/Users/mrap/hex"))
26+
.unwrap_or_else(|_| std::env::var("HOME").map(|h| PathBuf::from(h).join("hex")).unwrap_or_else(|_| PathBuf::from("/tmp/hex")))
2727
}
2828

2929
pub fn load_openrouter_key() -> Option<String> {

system/harness/src/memory/recall.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ fn facts_recall(
4949
k: usize,
5050
) -> rusqlite::Result<Vec<FactHit>> {
5151
// FTS5 default-ANDs tokens — for natural-language queries we want any-match.
52-
// Drop stopwords and OR the remaining alphanumerics so "who is whitney" hits
53-
// facts mentioning whitney.
52+
// Drop stopwords and OR the remaining alphanumerics so "who is alice" hits
53+
// facts mentioning the slug.
5454
let fts_query = query
5555
.to_lowercase()
5656
.split(|c: char| !c.is_alphanumeric())
@@ -80,8 +80,8 @@ fn facts_recall(
8080
};
8181

8282
// Slug boost: for each token in the query, surface facts whose subject
83-
// contains `:<token>` after the type prefix (e.g. "whitney" → subject
84-
// LIKE '%:whitney%' matches both `person:whitney` and `person:whitney-chew`).
83+
// contains `:<token>` after the type prefix (e.g. "alice" → subject
84+
// LIKE '%:alice%' matches both `person:alice` and `person:alice-chew`).
8585
for tok in query.to_lowercase().split_whitespace() {
8686
if tok.len() < 3 { continue; }
8787
let pattern = format!("%:{tok}%");
@@ -335,14 +335,14 @@ mod plan2_tests {
335335
crate::memory::schema::apply_plan2(&c).unwrap();
336336
c.execute(
337337
"INSERT INTO facts (id,subject,predicate,object,importance,created_at,updated_at)
338-
VALUES ('f1','person:whitney','is','Mike''s wife',0.95,'2026-05-23','2026-05-23')",
338+
VALUES ('f1','person:alice','is','a sample person',0.95,'2026-05-23','2026-05-23')",
339339
[],
340340
)
341341
.unwrap();
342-
let recall = recall_with_facts(&c, "who is whitney").unwrap();
342+
let recall = recall_with_facts(&c, "who is alice").unwrap();
343343
assert!(
344-
recall.facts.iter().any(|f| f.subject == "person:whitney"),
345-
"expected person:whitney fact in recall results"
344+
recall.facts.iter().any(|f| f.subject == "person:alice"),
345+
"expected person:alice fact in recall results"
346346
);
347347
}
348348
}

0 commit comments

Comments
 (0)