#!/usr/bin/env python3 # file: scripts/audit_khadhroony_workspace_rules.py # version: 2 """Audit mechanically verifiable rules specific to khadhroony-bot3.""" from __future__ import annotations import argparse import dataclasses import pathlib import re import sys import tomllib @dataclasses.dataclass(frozen=True) class Violation: """One project-specific workspace rule violation.""" code: str path: str line: int message: str def package_name(crate_dir: pathlib.Path) -> str | None: """Return a crate package name.""" cargo = crate_dir / "Cargo.toml" if not cargo.exists(): return None value = tomllib.loads(cargo.read_text(encoding="utf-8")).get("package", {}).get("name") return value if isinstance(value, str) else None def relevant_tracing_crate(crate_dir: pathlib.Path) -> bool: """Return whether the crate owns a tracing target contract.""" cargo = crate_dir / "Cargo.toml" data = tomllib.loads(cargo.read_text(encoding="utf-8")) if "tracing" in data.get("dependencies", {}): return True return any("TRACING_TARGET" in path.read_text(encoding="utf-8") for path in crate_dir.glob("src/**/*.rs")) def audit_tracing(root: pathlib.Path) -> list[Violation]: """Audit the project tracing target contract.""" violations: list[Violation] = [] for cargo in sorted(root.glob("*/Cargo.toml")): crate = cargo.parent if crate.name == "kb-lib": continue if not relevant_tracing_crate(crate): continue name = package_name(crate) if name is None: continue constants = crate / "src/constants.rs" expected = f'pub(crate) const TRACING_TARGET: &str = "{name}";' relative_constants = constants.relative_to(root).as_posix() if not constants.exists() or expected not in constants.read_text(encoding="utf-8"): violations.append(Violation("KH_TRACE001", relative_constants, 1, f"expected `{expected}`")) crate_root = crate / "src/lib.rs" if not crate_root.exists(): crate_root = crate / "src/main.rs" relative_root = crate_root.relative_to(root).as_posix() if not crate_root.exists() or "pub(crate) use crate::constants::TRACING_TARGET;" not in crate_root.read_text(encoding="utf-8"): violations.append(Violation("KH_TRACE002", relative_root, 1, "missing crate-root TRACING_TARGET re-export")) for path in crate.glob("src/**/*.rs"): relative = path.relative_to(root).as_posix() for index, line in enumerate(path.read_text(encoding="utf-8").splitlines(), 1): if "khbot." in line: violations.append(Violation("KH_TRACE003", relative, index, "legacy khbot tracing target is forbidden")) if "crate::constants::TRACING_TARGET" in line and path.name not in {"lib.rs", "main.rs"}: violations.append(Violation("KH_TRACE004", relative, index, "use crate::TRACING_TARGET outside crate root")) if re.search(r"(?:crate::[A-Za-z0-9_]+::|(? list[Violation]: """Audit hierarchical tracing targets owned by operational kb-lib components.""" violations: list[Violation] = [] crate = root / "kb-lib" crate_root = crate / "src/lib.rs" if not crate_root.exists(): return violations root_text = crate_root.read_text(encoding="utf-8") aliases = set( re.findall( r"^pub\(crate\) use crate::[A-Za-z0-9_:]+::([A-Z][A-Z0-9_]+_TRACING_TARGET);$", root_text, re.MULTILINE, ) ) target_pattern = re.compile( r'^pub\(crate\) const TRACING_TARGET: &str = "([^"]+)";$', re.MULTILINE, ) for constants in sorted((crate / "src").rglob("constants.rs")): text = constants.read_text(encoding="utf-8") match = target_pattern.search(text) if match is None: continue component = constants.parent.relative_to(crate / "src") expected = "kb-lib." + ".".join(component.parts) relative = constants.relative_to(root).as_posix() if match.group(1) != expected: violations.append( Violation( "KH_TRACE101", relative, text[: match.start()].count("\n") + 1, f"expected hierarchical target `{expected}`", ) ) macro_pattern = re.compile( r"tracing::(?:debug|error|info|trace|warn)!\(\s*target:\s*crate::([A-Z][A-Z0-9_]+_TRACING_TARGET)" ) for path in sorted((crate / "src").rglob("*.rs")): relative = path.relative_to(root).as_posix() text = path.read_text(encoding="utf-8") for index, line in enumerate(text.splitlines(), 1): if "let _target" in line: violations.append( Violation( "KH_TRACE102", relative, index, "fake tracing target consumption is forbidden", ) ) for match in macro_pattern.finditer(text): if match.group(1) not in aliases: violations.append( Violation( "KH_TRACE103", relative, text[: match.start()].count("\n") + 1, f"missing crate-root re-export for `{match.group(1)}`", ) ) return violations def audit_solana_types(root: pathlib.Path) -> list[Violation]: """Reject non-canonical Solana address types in workspace Rust code.""" violations: list[Violation] = [] for path in sorted(root.rglob("*.rs")): if "target" in path.parts or ".git" in path.parts: continue relative = path.relative_to(root).as_posix() for index, line in enumerate(path.read_text(encoding="utf-8").splitlines(), 1): if "solana_address::Address" in line: violations.append(Violation("KH_SOL001", relative, index, "use solana_pubkey::Pubkey instead of solana_address::Address")) return violations def main() -> int: """Run the khadhroony-specific audit.""" parser = argparse.ArgumentParser() parser.add_argument("--root", default=".") parser.add_argument("--report-only", action="store_true") arguments = parser.parse_args() root = pathlib.Path(arguments.root).resolve() violations = audit_tracing(root) + audit_kb_lib_tracing(root) + audit_solana_types(root) violations.sort(key=lambda item: (item.code, item.path, item.line, item.message)) if not violations: sys.stdout.write("Khadhroony workspace rule audit: clean\n") return 0 sys.stdout.write(f"Khadhroony workspace rule audit: {len(violations)} violation(s)\n") for item in violations: sys.stdout.write(f"{item.code} {item.path}:{item.line}: {item.message}\n") return 0 if arguments.report_only else 1 if __name__ == "__main__": raise SystemExit(main())