Memory Review
SkillWeb & browsingUse when the user says 'review memories', 'clean up the memory database', 'process unreviewed memories', 'memory cleanup', 'merge duplicate memories', or wants periodic LLM-powered post-ingestion review. Removes junk, merges duplicates, fixes miskeyed data, marks good entries as reviewed.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Memory Review skill
What this skill tells your AI
The instructions your AI receives, as published by m13v/ai-browser-profile in review/SKILL.md and read by ahel’s review.
LLM-powered post-ingestion review of the user memories database. Processes unreviewed memories in phases — bulk cleanup first, then per-entry review.
Setup
import sys, os
sys.path.insert(0, os.path.expanduser("~/ai-browser-profile"))
from ai_browser_profile import MemoryDB
mem = MemoryDB(os.path.expanduser("~/ai-browser-profile/memories.db"))
Workflow
Phase 0: Fast Pass (bulk cleanup)
Before reviewing individual entries, bulk-delete entire categories of known noise. This typically removes ~50% of entries instantly.
# 1. Delete ALL autofill:* entries — these are raw form field duplicates of real data
autofill_ids = [r[0] for r in mem.conn.execute(
"SELECT id FROM memories WHERE key LIKE 'autofill:%' AND reviewed_at IS NULL"
).fetchall()]
for mid in autofill_ids:
mem.delete(mid)
# 2. Delete ALL address_type_* entries — always noise (last names, numbers in address fields)
addr_type_ids = [r[0] for r in mem.conn.execute(
"SELECT id FROM memories WHERE key LIKE 'address_type_%' AND reviewed_at IS NULL"
).fetchall()]
for mid in addr_type_ids:
mem.delete(mid)
# 3. Delete ALL superseded entries
superseded_ids = [r[0] for r in mem.conn.execute(
"SELECT id FROM memories WHERE superseded_by IS NOT NULL AND reviewed_at IS NULL"
).fetchall()]
for mid in superseded_ids:
mem.delete(mid)
Check for leaked secrets before bulk-deleting autofill. Grep for client_secret, api_key, token, password in autofill values and flag them to the user before deleting.
Phase 1: Supersession Chain Repair
After the fast pass, single-value key chains (first_name, last_name, full_name, card_holder_name, email) are often corrupted. The extraction supersedes the real value with garbage because each new autofill entry blindly replaces the old one.
Common pattern: first_name chain goes Matthew → Marina → mediar → ... leaving "mediar" as the active value.
# For each single-value key, check the active (non-superseded) value
SINGLE_VALUE_KEYS = ["first_name", "last_name", "full_name", "card_holder_name", "email", "phone"]
for key in SINGLE_VALUE_KEYS:
rows = mem.conn.execute(
"SELECT id, value, confidence, superseded_by FROM memories WHERE key=? ORDER BY id",
(key,)
).fetchall()
print(f"\n{key}:")
for r in rows:
status = "ACTIVE" if r[3] is None else f"superseded by {r[3]}"
print(f" id={r[0]} val='{r[1]}' conf={r[2]} [{status}]")
Fix by:
- Deleting garbage entries (code identifiers, other people's names, company names in name fields)
- Unsuperseding the real value:
UPDATE memories SET superseded_by=NULL, superseded_at=NULL WHERE id=? - Boosting confidence on the real value if needed
Phase 2: Per-Entry Review
Now process remaining unreviewed entries in batches:
- Call
mem.get_unreviewed(limit=50)to get a batch - Print the batch as a numbered table
- Classify each as KEEP, DELETE, MERGE, or FIX
- Execute actions via
mem.delete(),mem.update_memory(), etc. - Call
mem.mark_reviewed([...ids...])on all processed IDs (including kept ones) - Print summary per batch
- Repeat until no unreviewed remain
Phase 3: Profile Verification
After all entries are reviewed, verify the profile output catches any residual issues:
print(mem.profile_text())
Check for:
- Wrong name showing (garbage superseded the real one)
- Mixed cities/states (e.g. "San Francisco, New York" in the same address)
- Garbage card holder names
- Missing fields that should be populated
Fix any issues, then mem.close().
Classification Criteria
DELETE — remove entirely
- Gibberish/test data:
"wegs sdg","asdf","test123","technical placeholder just to pay", single characters - Code identifiers in name fields: values containing underscores (
investor_role,handle_new_workflow_analysis,on_low_level_event_insert), or known non-names (os,type,use-case) - Leaked secrets: values containing
client_secret,GOCSPX-, full API keys, OAuth tokens, private keys — flag to user before deleting - Other people's data: names/emails/phones that belong to someone else — UNLESS stored as
contact:*orlinkedin:*keys - Company names in name fields:
first_name="mediar",last_name="inc",full_name="Mediar, inc."— these are autofill bugs - Truncated names:
last_name="Di",full_name="Matthew Di",full_name="Matt"(incomplete) - Noise locations: cities/states from insurance quoting, comparison shopping, or form testing
- Expired card data: card expiry dates in the past
- Meaningless amounts:
"100.00","199.00","1.00","$ 245.80"— these are form values, not useful data - Duplicate phone formats: keep only one format per phone number (prefer international format with
+1)
MERGE — combine duplicates
- Same phone, different formats:
"+1 650-796-1489","(650) 796-1489","6507961489"— keep the international format with highest confidence, delete all others - Same email, different casing: keep lowercase
- Duplicate DOB entries: identify the real one (consistent across sources) vs noise
- Same contact, multiple entries: merge into highest-confidence one
When merging: keep highest confidence. If tied, keep highest accessed_count. Delete the rest.
FIX — correct bad data
- Wrong key assignment:
company="Dmitrii Diakonov"→ delete (person name in company field) - Wrong confidence: real DOB at 0.4 while fake one at 0.6 → boost real one
- Missing tags:
phonekey withoutphonetag,emailwithoutemailtag - Broken supersession: use
UPDATE memories SET superseded_by=NULL, superseded_at=NULL WHERE id=? - Use
mem.update_memory(id, key=..., value=..., confidence=..., tags=[...])for fixes
KEEP — mark as reviewed
- Genuine user data
- Correctly keyed and tagged entries
- Legitimate contacts, accounts, tools
- Just call
mem.mark_reviewed([id])— no changes needed
Output Format
For each batch, print a table like:
Batch 1/N (50 memories)
───────────────────────────────────────
ID | Key | Value | Conf | Action
----|------------------|--------------------|------|--------
1 | first_name | Matthew | 0.8 | KEEP
2 | full_name | investor_role | 0.5 | DELETE (code identifier)
3 | phone | +14155551234 | 0.7 | KEEP
4 | phone | (415) 555-1234 | 0.5 | MERGE → #3
...
Summary: 30 kept, 12 deleted, 5 fixed, 3 merged
At the end, print the profile and final stats:
## Final Profile
[output of mem.profile_text()]
## Stats
Total: X memories (was Y before review)
Deleted: Z, Kept: W, Fixed: V, Merged: U
Secrets found and removed: N
Signals
- GitHub stars
- 53
- Forks
- 5
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
memory-review-m13v- Source
- github.com/m13v/ai-browser-profile