Overview
These findings were identified during a code smell review on 2026-03-13. Actionable, self-contained fixes (dead imports, FURB101 read_bytes patterns, the isinstance dict guard) have already been applied. The items below are deferred structural work, mypy type-narrowing, and LOW-priority observations.
Deferred Findings
auto_sync_manifests.py
| Severity |
Location |
Finding |
| MEDIUM |
module level (lines 39–42) |
sys.stdout.reconfigure() runs at import time. Guard behind if __name__ == "__main__" or move to CLI entry-point function to avoid side effects when imported as a library. |
| LOW |
whole file |
File is 1300+ lines combining CLI parsing, git diff analysis, manifest CRUD, version bumping, and reconciliation. Consider decomposing into submodules: _version_bump.py, _reconcile.py, _git_helpers.py. |
plugin_validator.py
| Severity |
Location |
Finding |
| HIGH |
line 1981 |
data["hooks"] typed as YamlValue — mypy does not narrow through .get() guard on line 1979. Fix: assign hooks = data["hooks"] after the isinstance guard, or use an explicit cast. |
| HIGH |
line 3024 |
item.lstrip("./") where item is YamlValue (iterated from list[YamlValue]). Non-string items would raise AttributeError at runtime. Add if isinstance(item, str) guard. |
| HIGH |
line 4063 |
group.get("hooks", []) returns YamlValue which includes int | float | None — not always iterable. Add isinstance check before iterating. |
| MEDIUM |
line 2957 |
metadata["author"] = author assigns dict[str, str] to a slot typed as YamlValue. Technically compatible but mypy flags due to recursive type alias limitations. Consider narrowing metadata dict annotation. |
| MEDIUM |
module level (lines 28–31) |
sys.stdout.reconfigure() at import time — same concern as auto_sync_manifests.py. |
| MEDIUM |
line 85 |
_ADAPTERS dict built at module level via load_adapters() — triggers filesystem operations on import. |
| LOW |
whole file |
File is 4000+ lines. Consider extracting: HookValidator into its own module, CLI entry point (app, typer commands) into cli.py, auto-fix logic into _autofix.py, reporting/formatting into _reporting.py. |
| LOW |
multiple except blocks |
Where exceptions are re-raised, consider using e.add_note() (PEP 678) to attach context rather than wrapping in new exceptions. |
adapters/claude_code/adapter.py
| Severity |
Location |
Finding |
| MEDIUM |
line 66 |
self.get_schema("plugin") — verify that the schema contains a "plugin" entry in file_types, otherwise validate() always returns [] for JSON files. |
| LOW |
— |
ClaudeCodeAdapter implements PlatformAdapter protocol but does not declare compliance. Consider explicit inheritance or a module-level type assertion: _: PlatformAdapter = ClaudeCodeAdapter() |
| LOW |
— |
Add runtime protocol compliance assertion at module bottom to catch interface drift early. |
_schema_loader.py
| Severity |
Location |
Finding |
| LOW |
— |
Return type is dict — could be dict[str, Any] for precision. No FileNotFoundError handling; consider a friendlier error message when a bundled schema file is missing. |
tests/test_frontmatter_utils.py
| Severity |
Location |
Finding |
| LOW |
lines 21, 30, 39, 49, 75 |
Imports of loads_frontmatter, dump_frontmatter, etc. inside every test method. Move to module level to reduce noise. |
Acceptance Criteria
https://claude.ai/code/session_01BevYUBWJm64cnqQ1E7U9uj