store: strip .md suffix from all keys
Keys were a vestige of the file-based era. resolve_key() added .md to lookups while upsert() used bare keys, creating phantom duplicate nodes (the instructions bug: writes went to "instructions", reads found "instructions.md"). - Remove .md normalization from resolve_key, strip instead - Update all hardcoded key patterns (journal.md# → journal#, etc) - Add strip_md_keys() migration to fsck: renames nodes and relations - Add broken link detection to health report - Delete redirect table (no longer needed) - Update config defaults and config.jsonl Migration: run `poc-memory fsck` to rename existing keys. Co-Authored-By: ProofOfConcept <poc@bcachefs.org>
This commit is contained in:
parent
77fc533631
commit
46f8fe662e
12 changed files with 289 additions and 132 deletions
|
|
@ -110,10 +110,9 @@ const MONTHLY: DigestLevel = DigestLevel {
|
|||
|
||||
const LEVELS: &[&DigestLevel] = &[&DAILY, &WEEKLY, &MONTHLY];
|
||||
|
||||
/// Store key for a digest node: "daily-2026-03-04.md", "weekly-2026-W09.md", etc.
|
||||
/// Matches the key format from the old import_file() path.
|
||||
/// Store key for a digest node: "daily-2026-03-04", "weekly-2026-W09", etc.
|
||||
fn digest_node_key(level_name: &str, label: &str) -> String {
|
||||
format!("{}-{}.md", level_name, label)
|
||||
format!("{}-{}", level_name, label)
|
||||
}
|
||||
|
||||
// --- Input gathering ---
|
||||
|
|
@ -148,12 +147,12 @@ fn gather(level: &DigestLevel, store: &Store, arg: &str) -> Result<(String, Vec<
|
|||
} else {
|
||||
// Leaf level: scan store for journal entries matching label
|
||||
let date_re = Regex::new(&format!(
|
||||
r"^journal\.md#j-{}", regex::escape(&label)
|
||||
r"^journal#j-{}", regex::escape(&label)
|
||||
)).unwrap();
|
||||
let mut entries: Vec<_> = store.nodes.values()
|
||||
.filter(|n| date_re.is_match(&n.key))
|
||||
.map(|n| {
|
||||
let ts = n.key.strip_prefix("journal.md#j-").unwrap_or(&n.key);
|
||||
let ts = n.key.strip_prefix("journal#j-").unwrap_or(&n.key);
|
||||
(ts.to_string(), n.content.clone())
|
||||
})
|
||||
.collect();
|
||||
|
|
@ -257,7 +256,7 @@ pub fn digest_auto(store: &mut Store) -> Result<(), String> {
|
|||
let date_re = Regex::new(r"^\d{4}-\d{2}-\d{2}").unwrap();
|
||||
let dates: Vec<String> = store.nodes.keys()
|
||||
.filter_map(|key| {
|
||||
key.strip_prefix("journal.md#j-")
|
||||
key.strip_prefix("journal#j-")
|
||||
.filter(|rest| rest.len() >= 10 && date_re.is_match(rest))
|
||||
.map(|rest| rest[..10].to_string())
|
||||
})
|
||||
|
|
@ -320,6 +319,16 @@ fn normalize_link_key(raw: &str) -> String {
|
|||
|
||||
let mut key = key.to_string();
|
||||
|
||||
// Strip .md suffix if present
|
||||
if let Some(stripped) = key.strip_suffix(".md") {
|
||||
key = stripped.to_string();
|
||||
} else if key.contains('#') {
|
||||
let (file, section) = key.split_once('#').unwrap();
|
||||
if let Some(bare) = file.strip_suffix(".md") {
|
||||
key = format!("{}#{}", bare, section);
|
||||
}
|
||||
}
|
||||
|
||||
// weekly/2026-W06 → weekly-2026-W06, etc.
|
||||
if let Some(pos) = key.find('/') {
|
||||
let prefix = &key[..pos];
|
||||
|
|
@ -329,27 +338,10 @@ fn normalize_link_key(raw: &str) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
// daily-2026-02-04 → daily-2026-02-04.md
|
||||
let re = Regex::new(r"^(daily|weekly|monthly)-\d{4}").unwrap();
|
||||
if re.is_match(&key) && !key.ends_with(".md") {
|
||||
key.push_str(".md");
|
||||
}
|
||||
|
||||
// Bare date → daily digest
|
||||
let date_re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
|
||||
if date_re.is_match(key.strip_suffix(".md").unwrap_or(&key)) {
|
||||
let date = key.strip_suffix(".md").unwrap_or(&key);
|
||||
key = format!("daily-{}.md", date);
|
||||
}
|
||||
|
||||
// Ensure .md extension
|
||||
if key.contains('#') {
|
||||
let (file, section) = key.split_once('#').unwrap();
|
||||
if !file.ends_with(".md") {
|
||||
key = format!("{}.md#{}", file, section);
|
||||
}
|
||||
} else if !key.ends_with(".md") && !key.contains('/') && !key.starts_with("NEW:") {
|
||||
key.push_str(".md");
|
||||
if date_re.is_match(&key) {
|
||||
key = format!("daily-{}", key);
|
||||
}
|
||||
|
||||
key
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue