Skip to content

Commit 23e80ac

Browse files
ptr727claude
andcommitted
Judge Marker Corruption Against the File, and Collapse a Duplicate on Install
An install onto an already-corrupted CLAUDE.md wrote the corruption into the stamp. `blocks_present` returns nothing for a duplicated or half-written block, the stamp records that same nothing, and every later run found them equal and reported CURRENT. Two wrong answers agreeing read as a match. `marker_corruption` judges the file alone. Markers present that yield no valid block are reported regardless of what the stamp recorded. The installer also could not clear it. `re.sub` replaced every match with the snippet, so a file arriving with two blocks kept two, and the remedy the report prints was a dead end for the one case that most needs it. It now keeps the first and drops the rest, and says how many it removed. Five cases added, all failing against the previous code, including that a stamp hand-edited to record no blocks cannot agree its way to a clean verdict. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent dc0451a commit 23e80ac

2 files changed

Lines changed: 84 additions & 1 deletion

File tree

host-setup/agent-safety/install.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,24 @@ def blocks_present(claude_md):
180180
return found
181181

182182

183+
def marker_corruption(claude_md):
184+
"""Markers present in the file that yield no valid block, meaning duplicated or half-written.
185+
186+
Judged against the file alone, never against the stamp. An install onto an already-corrupted
187+
CLAUDE.md records the same empty block set it reads, so the stamp and the file agree and the
188+
corruption reads as a match. Two wrong answers agreeing is the failure this exists to catch.
189+
"""
190+
if not claude_md.is_file():
191+
return []
192+
text = claude_md.read_text(encoding="utf-8", errors="replace")
193+
valid = blocks_present(claude_md)
194+
out = []
195+
for marker in ("agent-safety", "fleet-bootstrap"):
196+
if re.search(rf"<!-- {marker} v\d+ (?:start|end) -->", text) and marker not in valid:
197+
out.append(f"the {marker} markers in CLAUDE.md are duplicated or incomplete")
198+
return out
199+
200+
183201
def installed_digest(claude_home):
184202
"""A digest over the bytes actually on this machine, or None where the kit is not fully there.
185203
@@ -347,6 +365,9 @@ def report(claude_home):
347365
problems.append("the installed content differs from what this checkout would write")
348366
# Correct bytes on disk are not a running guard, so the wiring is checked as well.
349367
problems.extend(registration_problems(claude_home))
368+
# Read from the file rather than compared against the stamp.
369+
# An install onto a corrupted file writes the corruption into the stamp, and the two then agree.
370+
problems.extend(marker_corruption(claude_home / "CLAUDE.md"))
350371
if live != stamp.get("blocks"):
351372
problems.append(f"CLAUDE.md now holds {live or 'no blocks'}, where the stamp recorded {stamp.get('blocks') or 'none'}")
352373
if stamp.get("source", {}).get("dirty"):
@@ -522,7 +543,17 @@ def reject(where, held, want):
522543
snippet = (HERE / filename).read_text(encoding="utf-8").strip()
523544
block_re = re.compile(rf"<!-- {marker} v\d+ start -->.*?<!-- {marker} v\d+ end -->", re.DOTALL)
524545
if block_re.search(existing):
525-
existing, action = block_re.sub(lambda _: snippet, existing), "updated"
546+
# Keep the first occurrence and drop any duplicate, rather than rewriting each in place.
547+
# Substituting every match preserved the duplication, so a file arriving with two blocks kept two.
548+
# The report's own remedy of re-running could then never clear it.
549+
written = []
550+
551+
def once(_match, _snippet=snippet, _written=written):
552+
_written.append(True)
553+
return _snippet if len(_written) == 1 else ""
554+
555+
existing = block_re.sub(once, existing)
556+
action = "updated" if len(written) == 1 else f"updated, {len(written) - 1} duplicate(s) removed"
526557
else:
527558
sep = "" if existing == "" or existing.endswith("\n\n") else ("\n" if existing.endswith("\n") else "\n\n")
528559
existing, action = existing + sep + snippet + "\n", "appended"

host-setup/agent-safety/test_install.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,58 @@ def test_reinstalling_clears_an_unregistered_hook(self):
296296
self.assertEqual(run(self.home, "--report").returncode, 0)
297297

298298

299+
class TestPreexistingCorruption(StampCase):
300+
"""A file corrupted before the install, where the stamp records the corruption and agrees."""
301+
302+
def _duplicate(self, marker="agent-safety"):
303+
text = self.md.read_text(encoding="utf-8")
304+
block = re.search(rf"<!-- {marker} v1 start -->.*?<!-- {marker} v1 end -->",
305+
text, re.DOTALL).group(0)
306+
self.md.write_text(text + "\n" + block + "\n", encoding="utf-8")
307+
308+
def test_installing_onto_a_duplicated_block_does_not_report_current(self):
309+
"""The stamp is built from the same empty block set the file yields, so both agree."""
310+
self.install()
311+
self._duplicate()
312+
# Install again: the stamp is now written from a file that already carries the duplicate.
313+
self.install()
314+
r = run(self.home, "--report")
315+
self.assertEqual(r.returncode, 0, r.stdout + r.stderr)
316+
# The install collapsed it, which is why this is CURRENT rather than a standing STALE.
317+
self.assertEqual(install.blocks_present(self.md), {"agent-safety": "v1", "fleet-bootstrap": "v1"})
318+
319+
def test_the_installer_collapses_a_duplicate_rather_than_preserving_it(self):
320+
"""Substituting every match kept both blocks, so the printed remedy never worked."""
321+
self.install()
322+
self._duplicate()
323+
self.assertEqual(install.blocks_present(self.md), {"fleet-bootstrap": "v1"})
324+
self.install()
325+
text = self.md.read_text(encoding="utf-8")
326+
self.assertEqual(len(re.findall(r"<!-- agent-safety v1 start -->", text)), 1)
327+
328+
def test_markers_that_yield_no_valid_block_are_reported_regardless_of_the_stamp(self):
329+
"""A stamp recording no blocks must not agree its way into a clean verdict."""
330+
self.install()
331+
self._duplicate()
332+
stamp = json.loads(self.stamp.read_text(encoding="utf-8"))
333+
stamp["blocks"] = {}
334+
self.stamp.write_text(json.dumps(stamp) + "\n", encoding="utf-8")
335+
r = run(self.home, "--report")
336+
self.assertEqual(r.returncode, 1, r.stdout + r.stderr)
337+
self.assertIn("duplicated or incomplete", r.stdout)
338+
339+
def test_a_half_written_block_is_reported_as_corruption(self):
340+
self.install()
341+
text = self.md.read_text(encoding="utf-8")
342+
self.md.write_text(re.sub(r"<!-- agent-safety v1 end -->", "", text), encoding="utf-8")
343+
self.assertEqual(install.marker_corruption(self.md),
344+
["the agent-safety markers in CLAUDE.md are duplicated or incomplete"])
345+
346+
def test_a_clean_file_reports_no_corruption(self):
347+
self.install()
348+
self.assertEqual(install.marker_corruption(self.md), [])
349+
350+
299351
class TestStampVersion(StampCase):
300352
def test_a_stamp_from_a_different_format_version_is_rejected(self):
301353
"""The field exists so a shape change is detectable, which needs it to be read."""

0 commit comments

Comments
 (0)