|
2 | 2 |
|
3 | 3 | All notable changes to jcodemunch-mcp are documented here. |
4 | 4 |
|
| 5 | +## [1.108.193] - 2026-07-27 - the size cap can be raised, and a withheld file cannot prove absence |
| 6 | + |
| 7 | +Both reported by @dkiaulakis, measured on 1.108.188. The ask was small. The |
| 8 | +finding underneath it was not. |
| 9 | + |
| 10 | +### Added |
| 11 | + |
| 12 | +- **`JCODEMUNCH_MAX_FILE_SIZE` / `max_file_size`.** The per-file size cap was |
| 13 | + the one limit of three with no way to move it. Its neighbours |
| 14 | + `DEFAULT_MAX_INDEX_FILES` and `DEFAULT_MAX_FOLDER_FILES` each had a resolver |
| 15 | + reading config; the size cap had none, appeared in none of the 79 |
| 16 | + `JCODEMUNCH_*` variables, was not among `index_folder()`'s 11 parameters, and |
| 17 | + was passed from `index_folder.py:1490` as a hardcoded constant. All five |
| 18 | + points verified before the fix. |
| 19 | + |
| 20 | + New `security.get_max_file_size()`, same shape as its siblings. |
| 21 | + ⚠ **The default is unchanged at 500KB.** The ask was an escape hatch, not a |
| 22 | + higher default, and 500KB still protects the common case from a parse worth |
| 23 | + less than it costs. |
| 24 | + |
| 25 | +### Fixed |
| 26 | + |
| 27 | +- ⚠ **A file refused for size no longer lets the corpus call itself complete.** |
| 28 | + His sentence, which is the actual finding: *"Size is the one exclusion reason |
| 29 | + where the file is real, current, and wanted."* |
| 30 | + |
| 31 | + Worse than reported. `too_large` is refused during **discovery**, so the file |
| 32 | + never reaches `files_accepted`, and the 1.108.176 completeness reconciliation |
| 33 | + balances perfectly because it compares what the walk accepted against what got |
| 34 | + indexed — the refused file is outside **both** numbers. Coverage reported |
| 35 | + `complete: true` over a corpus missing a real, current, wanted source file. |
| 36 | + The contract was answering a question about the walk while presenting the |
| 37 | + answer as being about the tree. |
| 38 | + |
| 39 | + Exclusions now split in two: |
| 40 | + |
| 41 | + - **excluded** — the corpus being defined. A `.png` is `binary`, a vendored |
| 42 | + tree is `gitignore`, a lockfile is `wrong_extension`. Never candidates. A |
| 43 | + search over this can still prove absence, and **must**, or no real |
| 44 | + repository could prove anything. |
| 45 | + - **withheld** — real source, current, wanted, refused by one of *our* limits: |
| 46 | + `too_large`, `file_limit`, `unreadable`. Any of these makes `complete` false, |
| 47 | + and a zero-result over such a corpus cannot prove absence. |
| 48 | + |
| 49 | + The refusal names the cause and the remedy, separately from the generic |
| 50 | + `partial` message, because they send a reader to different places: "the index |
| 51 | + did not cover the whole tree" sends them to inspect their repo, while naming |
| 52 | + `too_large` sends them to a setting. |
| 53 | + |
| 54 | + ⚠ **Existing indexes will start reporting `complete: false` after a re-index |
| 55 | + if they withheld anything, and affected absence claims degrade.** That is the |
| 56 | + contract reporting something true it was previously hiding, not a regression. |
| 57 | + |
| 58 | +### Tests |
| 59 | + |
| 60 | +- New `tests/test_v1_108_193.py` (15), including the boundary that keeps the |
| 61 | + signal useful: structural exclusions alone must still permit absence. |
| 62 | +- ⚠ `tests/test_watcher_memory_cache.py` corrected. It set a low cap by patching |
| 63 | + `DEFAULT_MAX_FILE_SIZE`, which the resolver no longer consults, so the patch |
| 64 | + silently did nothing and the watcher fast path indexed an oversize file. It |
| 65 | + now sets the config value, which exercises the override a user actually has — |
| 66 | + a stronger test than before, and the failure is what proved the fast path |
| 67 | + honours the new route end to end. |
| 68 | + |
| 69 | +No tool-count, INDEX_VERSION or schema change. |
| 70 | + |
5 | 71 | ## [1.108.192] - 2026-07-27 - #377 P3: one immutable snapshot, start to finish |
6 | 72 |
|
7 | 73 | The two edges @mightydanp pinned adversarially on #377 after reviewing |
|
0 commit comments