Skip to content

One Store

Fabrizio Salmi edited this page Sep 6, 2026 · 1 revision

One store, three front ends

The shell, the VS Code extension and an MCP client all drive the same lgit binary, which reads the working tree and the git index and persists findings to one SQLite file.

That is the architectural choice worth understanding, because it is what makes the tool behave sensibly rather than being three tools that agree by coincidence.

What it buys

A finding you ignore in the editor stays ignored when CI runs. The state lives in the store, not in each front end. There is no second copy to drift.

An agent and a human see the same list. When your coding agent calls findings_list over MCP, it gets exactly what your sidebar shows, including everything you have already triaged. It is not re-deriving an opinion.

Triage is not repeated work. Deciding once about a finding is the expensive part; the store is what makes it happen once.

The concurrency detail

Two clients writing to one SQLite file is the obvious way to get SQLITE_BUSY. The design handles it explicitly: the store opens with journal_mode=WAL and busy_timeout=15000, and the extension serialises every lgit invocation.

So the extension and an agent-managed MCP server can hit the same database without tripping over each other. Worth knowing when you are running all three at once, because that is the configuration the design anticipates rather than one you are getting away with.

The MCP surface

Eight tools: gates_check, gates_list, findings_list, findings_stats, findings_ignore, findings_delete, findings_clear, findings_remediate.

Two properties matter for anyone wiring an agent to it:

The server never executes anything. It reports and it persists triage decisions. Whatever needs running, a human or the agent's own tools run.

findings_remediate returns a confidence of deterministic or guided. That is the field to branch on. deterministic means there is an exact recipe and applying it is mechanical. guided means the tool is offering a direction, and an agent should think rather than execute.

An agent that ignores that field and applies every remediation is using the tool wrong in a way the tool tried to prevent.

Practical consequences

Know where the store lives before you wire up CI. A fresh checkout has no store, so CI runs check from scratch every time, which is correct: CI should judge the tree, not inherit local triage. Local triage is for the developer loop.

findings_clear and findings_delete are destructive in the sense that matters here: they discard triage decisions somebody made. Reach for findings_ignore when the intent is "not this one", and for a config entry when the intent is "not this, ever".

Prefer config over ignore for permanent decisions. A finding ignored in the store is a decision that lives in one machine's database. A .l0git.json entry is a decision that lives in the repository, gets reviewed in a pull request, and applies to everyone. The store is for triage; the config is for policy.

Why it is one binary

No CGO, no Python, no rule engine, no YAML DSL. Binaries for linux, darwin and windows on amd64 and arm64, and the extension bundles them.

The consequence for you: what runs in your editor is the same code as what runs in CI, at the same version, with no per-environment interpretation. The reproducibility claim of the gates would be much weaker if each front end had its own implementation.

Clone this wiki locally