---
title: "One grep command kept the nightly sweep from committing 190 files"
canonical: https://dxdev.com/blog/a-read-only-search-claimed-190-files/
datePublished: 2026-09-27
---
The nightly sweep's [dry run](/blog/dry-run-that-lied-different-code-path-from-apply/) held a 190-file notes repo whole, and the only reason was 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, with no edit. 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 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. If the parser can't read a command, the safe direction is to let it count as a claim rather than exempt it.

## Checking it

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

An ownership check has two ways to be wrong. It can hold a repo over a command that only read a file, which is what happened here. It can also release a repo because it misread a command it could not parse. The fix settles the first by recognizing inspection verbs, and it settles the second by treating anything unparseable as a claim.
