Memory Scopes
Session, project, and global scopes — how memories are organized and expire.
Scopes
Every memory has a scope that determines its visibility and default lifetime:
| Scope | What it's for | Default TTL |
|---|---|---|
session | Single coding session — what you just did, decisions made, blockers hit | 30 days |
project | Per-repo knowledge — API quirks, architecture decisions, team conventions | 90 days |
global | Cross-project patterns — personal preferences, tool configs, workflow habits | Forever |
Project keying
Projects are identified by git remote URL. This means the same project is recognized regardless of where the repo is checked out — different machines, different paths, same project.
When storing a memory with scope: "project", the project field should be the git remote (e.g. git@github.com:Saturate/HUSK.git). The Claude Code plugin handles this automatically.
TTL and expiry
Memories expire based on their scope's default TTL, unless overridden:
- Custom TTL: Pass
ttl(in seconds) when storing to override the default - Explicit forever: Pass
ttl: nullto store a memory that never expires regardless of scope - Admin max: The
HUSK_TTL_MAXconfig caps all TTLs (even "forever") to a ceiling value
Expired memories are filtered out at query time — they're still in the database but won't appear in search results.
Duplicate detection
Before storing a new memory, HUSK checks for semantically similar existing memories from the same user. If a match is found above the dedup threshold (default: 0.92 similarity), the existing memory is returned instead of creating a duplicate.
You can:
- Force store: Pass
force: trueto skip dedup and store anyway - Replace: Pass
replace: "memory-id"to overwrite an existing memory's content - Adjust threshold: Set
HUSK_DEDUP_THRESHOLD(0.5–1.0) to make dedup more or less aggressive