---
title: "A Read-Only Search Claimed Ownership of 190 Files It Never Touched"
canonical: https://dxdev.com/blog/2026-09-26_a-read-only-search-claimed-190-files/
datePublished: 2026-09-26
---
The nightly sweep's dry run said it would commit nothing. It was holding a whole 190-file vault repo over one grep.

## What the sweep was looking at

A live session's subagent had grepped one of its own dirty files while researching. It was pure inspection, no edit. The dry run held the whole repo anyway.

The ownership check in `sweep_attribution._owns()` was a naive path-substring test. It asked whether a session's shell command contained the dirty file's path, and any mention counted as a claim. Reading a path is not a claim on it, but the check could not tell the difference.

## A pipe inside the pattern

The grep's regex argument contained a literal `|`. The naive path-substring check could not tell that from a real ownership claim. A naive split on `|` would also misparse it as a second pipeline stage and make the whole line look non-inspecting.

## The fix: drop the statements that only look

`_owns()` now runs each Bash or PowerShell command through `_mutating_text()`:

- It splits the command into statements on `&&`, `||`, `;` and newline.
- It tokenizes each statement with `shlex`, which is quote-aware, so a `|` inside a quoted pattern is not mistaken for a pipe.
- It splits on a bare `|` into pipeline stages.
- It drops any statement whose every stage is a pure-inspection verb: `grep`, `cat`, `ls`, `awk`, `sort`, `tr`, read-only `git` subcommands like `diff`, `show`, `log` and `status`, and a few more.

Only the text that survives gets searched for the dirty path. `sed -i`, `mv`, `rm`, `git mv` and running a script still count as ownership. A statement `shlex` cannot parse, such as one with an unbalanced quote, is kept as is. The safe direction is to let it count as a claim rather than exempt it.

## Checking it

I reproduced the failure against a session's real transcripts and the vault commit that cleaned up the false hold, and `commit_all` flipped back to `True`. I added two regression tests to the sweep attribution test file and confirmed both fail without the fix: a read-only grep no longer holds the repo, and `sed -i` still does.

Now a read-only grep no longer holds the repo, and `sed -i` still does.
