Repository navigation
Conversation
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
|
Thank you for identifying a correctness problem that can make stale coordinates look authoritative, and for covering both snippet and search paths. I checked current There is one mechanical scope blocker before code review. This PR adds 196 lines across seven new |
|
The fix is good and I want it. Two things before it can land — one of them is a merge-order hazard you may not have noticed, and it is the more important of the two. Blocker: this must not merge before #1787Your D1 makes
And your own #1787 exists because that oracle returns So if this lands first, on Windows:
Both read tools would go dark on that platform. Today the broken oracle is merely uninformative because only #1787 goes first. I have approved it; once it lands I will re-run this one. Worth adding a "depends on #1787" line to the description so nobody merges them the other way round. Please drop the
|
The snippet and full-mode search tools slice the live file on disk using line coordinates recorded at index time. After the file is edited without re-indexing, those ranges are stale: the tools returned shifted source text, or a grep hit attributed to an adjacent function, with no signal that the answer was drifting (everything after a small edit looked like current source). Both tools now consult the same freshness oracle check_index_coverage already exposes. When the file no longer matches the recorded metadata (metadata_changed/missing) they skip the stale live slice and report source_drift/freshness instead; the healthy path (metadata_match) is byte-identical to before. No index-format change: the recorded metadata is unchanged, only the read tools consult it. Fixes DeusData#1750 Signed-off-by: Ulises Millan Guerrero <[email protected]>
0297861 to
3cb8e15
Compare
Signed-off-by: Ulises Millan Guerrero <[email protected]>
3cb8e15 to
cb2eb32
Compare
|
Thank you for the October 22 update and for removing the openspec files while preserving the design explanation. The description now records the merged #1787 dependency and the refreshed tests; the next review is on us. Sorry for the delay—I’ll follow up soon. |
|
Thank you, Ulises, for this fix, for the careful design write-up, and for the October 22 update. Removing the openspec files while keeping the D1 to D4 reasoning in the description was exactly what we hoped for, and we are sorry you then waited on us again. We are closing this PR because #2600, now merged in 2658a18, fixes the get_code_snippet side of the same defect with a stronger check. Instead of comparing mtime and size, it compares the file against the SHA-256 recorded at index time, which also catches a same-size edit that kept its timestamp, and it slices the snippet from the very bytes it verified. Landing both would have given the snippet path two drift checks that can disagree (for example when only the timestamp changed), so we kept one. Your work shaped how we judged this. Keeping file_path and the line range on a withheld snippet is how #2600 behaves too, and your #1787 is what made file freshness trustworthy on Windows in the first place. The search_code half is not covered by #2600: it still attaches source by indexed coordinates. #1750 stays open for it, and your D3 and D4 approach (freshness resolved once per result, raw grep hits keep their content, one drifted file never suppresses healthy results) is a good starting point for that work. If you would like to take that on as a focused PR built on the content check from #2600, it would be very welcome. Thank you again for the persistence and the care. |
What does this PR do?
Fixes #1750.
get_code_snippetandsearch_codesliced the live file on disk using line coordinates recorded at index time. After the file was edited without re-indexing those ranges are stale, and the tools returned shifted source text — a grep hit misattributed to an adjacent function, or a snippet of the wrong symbol — presented as though it were current source.Both tools now consult the same freshness oracle
check_index_coveragealready exposes. When the recorded metadata no longer matches the file on disk (metadata_changed/missing), they skip the stale live slice and reportsource_drift: trueplus the freshness state instead. The healthy path (metadata_match) is unchanged; re-indexing remains the remedy.Depends on #1787 (merged). This change makes
coverage_path_freshnessload-bearing for the read tools, so it must not land on a tree where the oracle still reportsmetadata_changedfor every file on Windows. Rebased onto currentmain, which includes #1787.Design decisions
coverage_path_freshness:metadata_changed/missing⇒ drifted (skip the live read, emitsource_drift+freshness);metadata_match⇒ today's behavior.unavailable/not_tracked/outside_projectkeep today's behavior: a file with no hash record cannot be judged, and containment is already enforced separately.resolve_snippet_sourcegainsbool read_allowed; only theread_file_linescall is gated. On drift the response keepsfile_path/start_line/end_line(they describe the node asked about) and states that no source is available because the file changed after indexing. Outline and PDF paths are untouched.handle_search_codeand carried onsearch_result_t, soattach_result_sourceneeds no extra store/project plumbing through the paged/budgeted renderers. A drifted item gets neithersourcenorcontext. Raw (unattributed) grep hits keep their content, since those lines come from live grep output rather than index coordinates.stat+ one indexed hash-row read per result file.Changes since the first revision: dropped the
openspec/tree as requested, rebased ontomain(post-#1787 / budgeted search renderers), moved the search freshness lookup tohandle_search_codeper D3 above, and the tests now record the fixture hash withcbm_path_info_utf8(same mtime source as the indexer, per #1714) instead ofstruct stat.Tests
Two reproduce-first regression tests in
tests/test_mcp.c:tool_get_code_snippet_reports_drift_after_file_change— fresh metadata serves source with no drift marker; after appending to the file, the response carriessource_drift: true,freshness: metadata_changed, and no stale text.tool_search_code_marks_drifted_file_without_source— same forsearch_codein full mode.Checklist
git commit -s) — required, CI rejects unsigned commits (DCO, see CONTRIBUTING.md)scripts/test.sh --suites mcp: 382 passed, 4 skipped). Note:search_code_scan_live_child_deadline_is_bounded_and_fails_closed(100 ms deadline) alternated pass/fail on the same binary under ASan on a 2-core box; it fails before the code this PR touches.scripts/lint.sh). cppcheck reports nothing on the changed lines; I could not run the project's pinned clang-format/clang-tidy build locally.