Skip to content

Commit dbd6d4c

Browse files
committed
Validate and auto-repair identity on startup
Add validation and repair for the stored identity. Introduces is_valid_uuid() in config.py and ensure_identity() in store.py to detect missing or malformed identity IDs, regenerate a new UUID (and a name only if absent), persist the fix, and return (was_repaired, identity). Update cli._require_root to call ensure_identity() and notify the user if the identity was regenerated. This ensures the store always has a valid identity before running commands.
1 parent 2cd9529 commit dbd6d4c

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

src/lore/cli.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ def _require_root() -> Path:
189189
"[red]No .lore directory found. Run `lore init` first.[/red]"
190190
)
191191
raise typer.Exit(code=1)
192+
from .store import ensure_identity
193+
repaired, identity = ensure_identity(root)
194+
if repaired:
195+
console.print(
196+
f"\n [bold {_A}]▲[/bold {_A}] Identity was missing or corrupt — regenerated: "
197+
f"[bold {_A}]{identity['name']}[/bold {_A}] [dim]({identity['id']})[/dim]\n"
198+
)
192199
return root
193200

194201

src/lore/config.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ def generate_identity() -> dict[str, str]:
4949
return {"name": name, "id": uid}
5050

5151

52+
def is_valid_uuid(value: str) -> bool:
53+
"""Return True if *value* is a well-formed UUID string."""
54+
try:
55+
uuid.UUID(value)
56+
return True
57+
except (ValueError, AttributeError):
58+
return False
59+
60+
5261
DEFAULT_CONFIG: dict[str, Any] = {
5362
"version": 1,
5463
"identity": {"name": "", "id": ""},

src/lore/store.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from pathlib import Path
88
from typing import Any
99

10-
from .config import memory_dir, load_config, save_config, DEFAULT_CONFIG, generate_identity
10+
from .config import memory_dir, load_config, save_config, DEFAULT_CONFIG, generate_identity, is_valid_uuid
1111

1212
# Per-file YAML parse cache: path -> (mtime, parsed_data)
1313
# Re-parses only when the file's mtime changes — transparent for both CLI and TUI.
@@ -51,6 +51,33 @@ def init_store(root: Path) -> None:
5151
save_config(root, existing_cfg)
5252

5353

54+
def ensure_identity(root: Path) -> tuple[bool, dict]:
55+
"""Verify the store has a valid identity; repair silently if not.
56+
57+
Returns ``(was_repaired, identity_dict)``.
58+
If the id is missing or not a valid UUID the id is regenerated.
59+
If the name is also absent a fresh name is generated too.
60+
The existing name is preserved when only the id is broken.
61+
"""
62+
cfg = load_config(root)
63+
identity = cfg.get("identity", {})
64+
ident_id = identity.get("id", "")
65+
ident_name = identity.get("name", "")
66+
67+
if ident_id and is_valid_uuid(ident_id):
68+
return False, identity
69+
70+
# Repair: keep name when still present, always issue a fresh id.
71+
if ident_name:
72+
new_identity: dict = {"name": ident_name, "id": str(uuid.uuid4())}
73+
else:
74+
new_identity = generate_identity()
75+
76+
cfg["identity"] = new_identity
77+
save_config(root, cfg)
78+
return True, new_identity
79+
80+
5481
def _short_id() -> str:
5582
return str(uuid.uuid4())[:8]
5683

0 commit comments

Comments
 (0)