ADR 0035 — Latest-changes analysis for git knowledge sources (K11)
- Status: accepted
- Date: 2026-10-04
- Slice: P35 (knowledge roadmap K11)
Context
The Eezy-parity feature set (the EE AI assistant with MCP support, git repository indexing, source-code symbol recognition, source analysis, repo statistics, MCP tools) is already landed in Mosaic across the K1–K10 knowledge series and P29 (Mosaic Aide). The one remaining capability the feature list names is analyzing the latest changes: the K2 git facts are static (branch, commit count, last short-sha + date, contributor count). Nothing exposes the recent commit history, the files each commit touched, or the diff magnitude — and the assistant (Aide) cannot answer "what changed recently in this repo?" because no change data is indexed.
The knowledge engine already has the pieces this needs: the git CLI seam (K2 — fail-soft, pure parse layer + thin command wrapper), the ingest pipeline (K1/ADR 0019 delta with per-source manifests), the per-source stats row (which already carries the live git facts), and the MCP tool conventions (K1–K6).
Decision
K11 = latest-changes analysis, as a strategy layer (default on) on every
git work-tree source — declared sources[].git, a plain path that happens
to be a work tree, or a runtime-added git source (K9):
-
Engine (
mosaic-knowledge):git.rsgainsChangedFile { path, status, added, deleted },RecentCommit { sha, date, author, subject, files }, a pureparse_recent_commits(name_status, numstat) -> Option<Vec<RecentCommit>>(twogit logoutputs joined by sha —--name-statusfor the A/M/D/R status,--numstatfor the +/- magnitude; binary files are 0/0), and the fail-softrecent_commits(dir, limit)over the git CLI seam (None when not a work tree, git missing, or the log is empty).source_worktree(base, path, git_url)resolves a source's work tree WITHOUT cloning (git source → the K8.gitcache/<label>when present; path source → the path when present) so surfaces can read history from disk live.ingest.rs:Strategy.changes(default on — "with and without is a flag", like symbols/graph/git/books). For a work-tree source, ingest appends synthetic knowledge entries — one per recent commit (kind: git-commit,Locator::Inline { doc: "git-commit/<sha>" }, subject + author + date + per-file status and +/-) and one aggregate summary (kind: git-changes: the window's per-commit one-liners + the most-changed files) — under a dedicated doc slug<label>/git-log(upserted as a whole, so re-ingest replaces the window cleanly). The slug is tracked inSourceManifest.git_logso ADR 0014 removal deletes it with the source, and inIngestReport.changesso every stats surface carries it (the entries themselves are excluded from the LOC language mix, likecode-summary).- The window is capped at
CHANGES_LIMIT = 20commits (deterministic; the cap lives in the engine so REST/MCP/stats agree).
-
Surfaces (generated app lens):
- The per-source stats row gains
changes(the last ≤20 commits with their files) — flowing throughGET /api/vectordb/{name}/stats, theknowledge_stats+repo_profileMCP tools, the/knowledgepage, andmosaic knowledge-reportwith zero per-surface code. GET /api/vectordb/{name}/changes?limit=N— LIVE (recomputed from the checkout on request, default 10, capped 50; not ingest-time data), reporting every git work-tree source of the collection (declared + runtime) with branch + commits. Fail-soft per source.- The
recent_changesMCP tool (kb+ optionallimit) over the same live path — the agent-facing "analyze the latest changes". - The
/knowledgepage renders a "recent changes" table per KB from the stats row (no new fetch — the page already consumes the stats JSON).
- The per-source stats row gains
-
DSL:
vector_dbs[].strategy.changes(default on) — the only new key. No new dependencies (the git CLI seam is unchanged), no new surfaces beyond the existing conventions.
Consequences
- Aide (P29) can answer "what changed recently / who touched file X
recently" by RAG over the indexed commit entries, and can call
recent_changesfor a live read — closing the Eezy code-intelligence feature list. - Shallow (
--depth 1) remote clones (K8) have a one-commit history, so their changes window is that single commit — inherent to the K8 reuse-if-present clone contract (delete the cache to refresh; a full local path or bundle carries the full history). - The commit entries live in the index (embedded like any chunk); a reindex
refreshes the window. The live
/changesendpoint is always current. - Stats payloads grow by ≤20 small commit rows per git source (deterministic order, newest first).