Skip to content

Commit 4d3df41

Browse files
authored
Merge pull request #180 from PyAutoLabs/feature/hygiene-refs-dotdir
fix(hygiene): refs mangles dot-directory references
2 parents 3fd6574 + ee0487a commit 4d3df41

2 files changed

Lines changed: 40 additions & 3 deletions

File tree

agents/conductors/hygiene/_hygiene_refs.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,9 +361,18 @@ def resolves(self, reference: str, repo: str, directory: str) -> bool | None:
361361
target = self.index(repo)
362362
if target is None:
363363
return None
364-
path = reference.lstrip("./")
365-
while path.startswith("../"):
366-
path = path[3:]
364+
# Strip leading `./` and `../` as *prefixes*. `lstrip("./")` would strip
365+
# the character set, silently mangling every reference to a dot-directory
366+
# (`.claude/skills` -> `claude/skills`, `.github/workflows` ->
367+
# `github/workflows`) and then reporting it as dead.
368+
path = reference
369+
while True:
370+
if path.startswith("../"):
371+
path = path[3:]
372+
elif path.startswith("./"):
373+
path = path[2:]
374+
else:
375+
break
367376
head = path.split("/", 1)[0]
368377
if head in RUNTIME_DIRECTORIES:
369378
return None

tests/test_hygiene_conductor.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,34 @@ def test_refs_suppresses_prose_slashes_and_absolute_paths(tmp_path):
633633
assert "imaging/modeling" not in found
634634

635635

636+
def test_refs_resolves_dot_directory_references(tmp_path):
637+
workspace = tmp_path / "demo_workspace"
638+
(workspace / "scripts").mkdir(parents=True)
639+
(workspace / ".claude" / "skills").mkdir(parents=True)
640+
# `.github/` exists but holds no `workflows/`, so the reference below is
641+
# anchored (the guard will judge it) yet genuinely dead.
642+
(workspace / ".github").mkdir()
643+
(workspace / "README.md").write_text(
644+
"\n".join(
645+
[
646+
"- `scripts`: example scripts.",
647+
"See `.claude/skills` for agent skills and `.github/workflows` for CI.",
648+
"",
649+
]
650+
)
651+
)
652+
653+
found = {f["reference"] for f in _refs_row(tmp_path)["findings"]}
654+
655+
# A leading dot must survive prefix-stripping. Before the fix, `lstrip("./")`
656+
# ate it: `.claude/skills` became `claude/skills` and was reported dead even
657+
# though it exists, and `.github/workflows` was reported under a mangled name.
658+
assert ".claude/skills" not in found
659+
assert ".github/workflows" in found
660+
assert "github/workflows" not in found
661+
assert "claude/skills" not in found
662+
663+
636664
def test_refs_findings_reach_the_default_worklist(tmp_path):
637665
_write_refs_fixture(tmp_path)
638666

0 commit comments

Comments
 (0)