Edit Logging

Edit logging

Every file edit Claude Code makes, across every project on this machine, lands in a single SQLite database I can query.

The synodic-kit pre-tool-use hook intercepts every Edit and Write tool call. Before the edit executes, the hook logs the full context to a database I keep outside any repo. After several months of running this on a heavily-used Mac Mini, the database holds tens of thousands of edits with full before-and-after content. It is the single most useful artifact the plugin produces.

This page is about why I built the central log, what is in it, and how the vector search layer on top changed how I navigate my own change history.


What Gets Logged

Each row in edits.db captures everything I would want to know about an edit weeks later:

Field Content
timestamp When the edit happened
repo Which project (full path)
branch Which branch
file_path What was edited (relative to repo)
change_type bugfix, feature, refactor, style, test, docs
user_prompt What I asked for in the conversation
old_content File content before the edit
new_content File content after the edit

The hook filters out binary files, lock files, files larger than a megabyte, and build outputs, so the log stays focused on meaningful code changes. A separate threads.db tracks every inline-dialogue thread operation (created, responded, dismissed) with full thread state and git context, populated by the inline-dialogue MCP server rather than the hook.

Why Centralized

I considered keeping the log per-repo, alongside each project. Three things pushed me to a single shared database instead.

No merge conflicts. A SQLite file inside a git repo creates binary merge conflicts on every branch you switch to. Putting the database outside any repo eliminates that class of pain.

No PR noise. Edit logs do not pollute project diffs or show up in code reviews. The log is for me, not for collaborators.

Cross-project queries. “Show me every refactor across every project this month” is one SQL query. “What did I change about authentication anywhere in the last week” is one ChromaDB lookup. Per-repo logs cannot answer those questions without writing a custom aggregator.

Vector Search on Top

ChromaDB indexes the edit history for semantic queries, with the all-MiniLM-L6-v2 embedding model running locally so there are no API calls. Each indexed document combines the user prompt with extracted directives from the edit, which means I can search by intent rather than by exact string match.

The query I make most often is the natural-language one. “What did I change about Telegram message routing last month” returns the relevant edits across patchbay-relay, synodic-kit, and Fanta in one pass, even though those projects use different terminology for the same concept. Grep across git history would not have caught any of that.

What This Pairs With

The synodic-kit pre-tool-use hook is the producer. Code is on GitHub at synodic-studio/synodic-kit, specifically hooks/session/sqlite_logger.py. The database itself is local-only and contains content I do not publish.

The bigger lesson is in the pattern, not the implementation. Anywhere you have an LLM doing meaningful work over a long horizon, you want a structured log of what it did. The log does not need to be elaborate. A SQLite file plus a hook is enough. The leverage is in having a complete record you can query weeks later when “what did I change?” is the only question that matters.