mcp/snapshot: secret-filter drift guard + per-session edit locks (#528 audit)#530
Merged
Conversation
…audit) Two correctness/security items surfaced by the #528 capability audit. - isSensitivePath drift guard: snapshot.zig and watcher.zig keep duplicate copies of the secret/credential exclusion filter. They are equivalent today (verified by tracing every input class), but a future edit to one copy and not the other would silently leak a secret into either the snapshot or the live index. Make snapshot's copy `pub` and add a parity test over a ~40-path battery (incl. the .env-prefix edge cases and .ssh//.aws/ dirs) so any drift fails CI. No runtime behavior change. - Per-session edit-lock owner: codedb_edit hardcoded EditRequest.agent_id = 1 (the startup __filesystem__ agent). The advisory lock is re-entrant per agent id, so multiple MCP connections sharing one process would both "win" the same file's lock and fail to detect concurrent edits. Thread a distinct per-session agent id (Session.edit_agent_id, registered at session start) through handleCall -> dispatch -> handleEdit (and the bundle recursion). Today's stdio MCP is single-connection and the HTTP server already takes a per-client agent id, so this is forward-looking hardening + removes the TODO; behavior- preserving for the current single-connection path. Validated by zig build test. Registry lock semantics were already covered in test_core.zig; added a test tying distinct session ids to mutual exclusion. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Benchmark Regression ReportThresholds: 10.00% and 50,000 ns absolute delta
|
Positive runtime evidence for the per-session edit-lock fix: an edit through a session agent registered AFTER __filesystem__ (so id != 1, mirroring the real server's Session.edit_agent_id) successfully acquires the advisory lock and writes the file, and a second agent can edit once the lock is released. applyEdit returns error.FileLocked if the id were not a live registered agent, so this guards against a wiring regression that compilation can't catch. test-snapshot 29/29; full zig build test green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Benchmark Regression ReportThresholds: 10.00% and 50,000 ns absolute delta
|
justrach
added a commit
that referenced
this pull request
Jun 4, 2026
…, CLI hardening, ReScript - release_info.semver 0.2.5823 -> 0.2.5824 (the version codedb reports and update.zig compares against; build.zig.zon was already 0.2.5824). - CHANGELOG: document the warm CLI daemon (#525), faster fuzzy find (#526), CLI hardening (#529), ReScript .res/.resi (#532), and audit fixes (#530) alongside the existing code-graph / snapshot-load sections. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two correctness/security items surfaced by the #528 capability audit. Both were verified against the actual code — and notably, both turned out to be latent rather than live, which the fixes reflect honestly.
1.
isSensitivePathsecret-filter — drift guard (not a live bug)snapshot.zigandwatcher.zigkeep duplicate copies of the secret/credential exclusion filter (snapshot persistence vs live indexing). The audit flagged "divergent logic causing coverage gaps" — but tracing every input class shows they're functionally equivalent today (watcher's first-char fast-path gate{'.','c','s','i'}covers every sensitive name; both have the.envboundary check from issue-409).So there's no live coverage gap — but it is a real future-leak hazard in security code (edit one copy, not the other → a secret silently slips into one path). Fix: make
snapshot.isSensitivePathpuband add a parity test over a ~40-path battery (.env,id_rsa,.ssh/known_hosts,keystore.jks, … and the non-secret.envoy.json/.environmentedge cases) that fails CI on any drift. No runtime behavior change.2.
codedb_editagent_id = 1— per-session edit-lock owner (forward-looking)handleEdithardcodedEditRequest.agent_id = 1(the startup__filesystem__agent). The advisory lock is re-entrant per agent id, so multiple MCP connections sharing one process would both "win" the same file's lock and miss a concurrent edit.On inspection this is latent, not live: stdio MCP is one connection per process, and
server.zig(HTTP serve) already takes a per-clientagentid from the request. So it'd only bite if a multi-connection MCP transport is added. The fix threads a distinct per-session id (Session.edit_agent_id, registered at session start) throughhandleCall → dispatch → handleEdit(+ the bundle recursion), removing the documentedTODO. Behavior-preserving for today's single-connection path (the single client just owns a distinct registered id instead of the shared1).Tests / validation
test_snapshot.zig:isSensitivePathparity battery (snapshot ≡ watcher) + explicit secret/non-secret anchors.test_core.zig: distinct session ids register non-1and mutually exclude on a path (the registry's contention semantics were already covered).zig buildandzig build testare green.This came out of a multi-agent capability audit of codedb; the larger roadmap (callpath+PageRank from the already-computed edges, token-budget context packing,
format=json, prefix/kind symbol search, git-churn ranking) is tracked separately.🤖 Generated with Claude Code