Skip to content

fix(mcp): add opt-in snapshot evidence envelopes - #2914

Draft
bline wants to merge 1 commit into
DeusData:mainfrom
bline:fix/2585-observation-contract
Draft

bline wants to merge 1 commit into
DeusData:mainfrom
bline:fix/2585-observation-contract

Conversation

@bline

@bline bline commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Evidence consumers need to identify the publication behind a tool result and distinguish indexed source from a later filesystem read. This implements the remaining observation contract proposed in #2585: snapshot: true on query_graph, search_graph, trace_path, get_code_snippet, check_index_coverage and search_code pins the existing database read scope and returns {store_generation, snapshot_consistent: true, data}. data preserves the original JSON or tree result. Default requests stay unwrapped; failure to establish or retain the pin returns an explicit error. Cross-service traces are refused because they span project stores.

This draft proposes the opt-in response contract for maintainer design review. Maintainer direction on the unified observation contract in #2585 remains pending.

search_code now labels match coordinates as live filesystem observations. Full/context source is captured before rendering, verified against the indexed hash, and sliced from those same captured bytes across output-budget retries. Known drift withholds source; legacy unverifiable source stays explicitly unverified. Captures are shared by file path, with a 64 MiB retained-buffer budget and explicit source_unavailable: "capture_budget" output when exhausted. A bounded temporary builder can exceed the retained quota; the quota is not a process RSS limit.

The pin covers indexed structure. It does not make filesystem reads atomic, establish graph completeness, or provide the optional whole-input/build/configuration manifest discussed in the issue. metadata.generation retains its coverage-recording meaning. Existing per-tool output budgets apply to data; the envelope adds metadata and JSON quoting overhead.

Regression coverage exercises all six tools, default and opt-out output, drift despite matching file metadata, writes after capture in full/context modes, a real second SQLite writer publishing during the pinned request, shared-file capture ownership, quota exhaustion and files-mode capture avoidance.

Validation on Linux x86_64:

  • scripts/test.sh CC=clang CXX=clang++: exit 0; ASan+UBSan, 10,329 passed, 0 failed, 11 skipped across 192 suites, followed by all production-binary guards. MCP phase: 428 passed, 4 skipped.
  • scripts/lint.sh --ci CLANG_FORMAT=clang-format-20 CPPCHECK_JOBS=4 LINT_SRCS=src/mcp/mcp.c LINT_HDRS=src/mcp/mcp_internal.h: exit 0 using the project lint toolchain container.
  • scripts/security-audit.sh, source/test syntax checks and git diff --check: exit 0. The production tools/list serializer emits 21,336 bytes, below the existing 21,504-byte ceiling.

Full scripts/lint.sh remains non-green: clang-tidy reports existing large-handler complexity and NULL-server dispatch paths. The NULL-server paths follow unchanged baseline handlers; this PR preserves the valid-server behavior. No check suppression, threshold or allocation-baseline changes were made.

AI disclosure: implemented with Codex; retained read-only Claude and Astra xhigh reviews were used for correctness feedback. Model review is separate from the executed checks above.

Fixes #2585

Fixes DeusData#2585

Signed-off-by: Scott Beck <296871+bline@users.noreply.github.com>
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

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. 0.9.1-rc.1 is out, so the release freeze that held reviews is over — but it left a large queue of open pull requests behind it, and we are reading through them oldest-first. The background is in discussion #1144.

What that means for this PR, concretely:

  • It will not be closed for inactivity. No stale bot touches pull requests here.
  • It may still sit a while before a human reads it. That is on us, not on you.
  • Older PRs are read first, so a recent one is not being skipped — it is behind a queue.

Things that will genuinely speed it up whenever review does happen:

  • Keep it rebased on main — the tree is moving quickly right now, and a conflicting branch cannot be reviewed as the diff you intended.
  • Get CI green, or say which failures you believe are pre-existing.
  • Keep the change to one claim. Bundled features and refactors get split before they get merged, which costs you a round trip.
  • Every commit needs a sign-off (git commit -s) — CI enforces DCO.

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.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tool results cannot be tied to one coherent, content-verified index snapshot

1 participant