1313 └── test_main.py
1414```
1515
16+ ---
17+
1618## Cache Keys
1719
1820Each repository is identified by ` {owner}-{name} ` :
19- - GitHub repos: owner and repo name from the URL (e.g., ` pydantic-monty ` )
20- - Local folders: ` local-{folder_name} ` (e.g., ` local-myproject ` )
21+
22+ * ** GitHub repositories** : owner and repository name from the URL
23+ Example: ` pydantic-monty `
24+ * ** Local folders** : ` local-{folder_name} `
25+ Example: ` local-myproject `
26+
27+ ---
2128
2229## Index Schema
2330
@@ -39,63 +46,87 @@ Each repository is identified by `{owner}-{name}`:
3946}
4047```
4148
49+ ---
50+
4251## Index Versioning
4352
44- - ` index_version ` is stored in every index JSON.
45- - Current version: ** 2** (defined in ` INDEX_VERSION ` constant).
46- - On load, if ` stored_version > INDEX_VERSION ` , the index is rejected (returns None).
47- - Older versions (v1) are loaded with missing fields defaulting to empty values.
48- - Bump ` INDEX_VERSION ` when making breaking schema changes.
53+ * ` index_version ` is stored in every index JSON.
54+ * The current version is defined by the ` INDEX_VERSION ` constant.
55+ * If a stored index has a ** newer** version than the running software, the index is rejected.
56+ * Older versions are loaded with missing optional fields populated using defaults.
57+ * Increment ` INDEX_VERSION ` only for ** breaking schema changes** .
58+
59+ ---
4960
5061## File Hash Change Detection
5162
52- Each indexed file's SHA-256 hash is stored in ` file_hashes ` .
63+ Each indexed file stores a SHA-256 content hash in ` file_hashes ` .
64+
65+ During incremental indexing:
66+
67+ 1 . Compute hashes for current files.
68+ 2 . Compare with stored hashes.
69+ 3 . Classify files as:
70+
71+ * ** Changed** — hash differs
72+ * ** New** — not present in prior index
73+ * ** Deleted** — present previously but missing now
5374
54- On re-index with ` incremental=True ` :
55- 1 . Read current file contents and compute hashes.
56- 2 . Compare against stored ` file_hashes ` .
57- 3 . Classify files as: ** changed** (hash differs), ** new** (not in old index), ** deleted** (in old index but not on disk).
75+ ---
5876
5977## Incremental Indexing
6078
61- When ` incremental=True ` and an existing index is found :
79+ When ` incremental=True ` and a prior index exists :
6280
63- 1 . ** Detect changes** via ` IndexStore.detect_changes() ` .
64- 2 . ** Re-parse only** changed and new files.
65- 3 . ** Remove symbols** for deleted and changed files from existing index .
66- 4 . ** Merge** new symbols into the remaining symbol list .
67- 5 . ** Update** file hashes, source files list , and languages .
68- 6 . ** Save atomically ** via temp file + rename .
81+ 1 . Detect file changes via ` IndexStore.detect_changes() ` .
82+ 2 . Re-parse only changed and new files.
83+ 3 . Remove symbols belonging to changed or deleted files .
84+ 4 . Merge newly extracted symbols into the index .
85+ 5 . Update file hashes, source file lists , and language counts .
86+ 6 . Save the updated index atomically .
6987
70- If no existing index exists, falls back to full index.
88+ If no prior index exists, a full index is created automatically.
89+
90+ ---
7191
7292## Git Branch Switching
7393
74- For git repositories (local folders):
75- - ` git_head ` stores the HEAD commit hash at index time.
76- - On re-index, if HEAD changed, a full reindex is triggered (or diff-based if incremental).
77- - ` _get_git_head() ` runs ` git rev-parse HEAD ` with a 5-second timeout.
94+ For Git-based repositories:
95+
96+ * ` git_head ` records the repository HEAD commit at index time.
97+ * On re-index, a changed HEAD indicates potential file changes.
98+ * A full or incremental re-index is triggered depending on configuration.
99+ * Commit detection uses ` git rev-parse HEAD ` with a bounded execution timeout.
100+
101+ ---
78102
79103## Invalidation
80104
81105### Manual Invalidation
82- - ** ` invalidate_cache(repo) ` ** MCP tool: deletes index JSON and raw content directory.
83- - ** ` delete_index(owner, name) ` ** on IndexStore: same effect programmatically.
106+
107+ * ` invalidate_cache(repo) ` MCP tool deletes the index JSON and cached file directory.
108+ * ` IndexStore.delete_index(owner, name) ` performs the same operation programmatically.
84109
85110### Automatic Invalidation
86- - Re-indexing the same repo overwrites the existing index.
87- - Index version mismatch causes the old index to be ignored.
111+
112+ * Re-indexing overwrites existing indexes.
113+ * Index-version mismatches cause the stored index to be ignored automatically.
114+
115+ ---
88116
89117## Atomic Writes
90118
91- Index JSON is written via a two-step process:
119+ Indexes are written using a safe two-step process:
120+
921211 . Write to ` {owner}-{name}.json.tmp `
93- 2 . Rename (replace) to ` {owner}-{name}.json `
122+ 2 . Rename to ` {owner}-{name}.json `
123+
124+ This prevents corrupted indexes caused by partial writes or process interruptions.
94125
95- This prevents corrupted index files from partial writes or crashes.
126+ ---
96127
97128## Hash Strategy
98129
99- - ** File hashes: ** SHA-256 of UTF-8 encoded file content string.
100- - ** Symbol content hashes: ** SHA-256 of raw symbol source bytes (stored per-symbol for drift detection).
101- - All hashes are hex-encoded strings.
130+ * ** File hashes** : SHA-256 of UTF-8 encoded file content
131+ * ** Symbol hashes** : SHA-256 of raw symbol source bytes (used for drift detection)
132+ * All hashes are stored as hexadecimal strings
0 commit comments