repo-manager/tests/test_standards.py
tegwick 04145a59d9 feat: model repo standards and detect prefix collisions
Implement RMGR-WP-0004 T01 (flavor, required files, anti-patterns from
canon) and T08 (prefix ownership registry plus uniqueness scan).
rmgr conform and rmgr prefix-uniqueness are detection only.
2026-08-18 13:28:40 +02:00

112 lines
4 KiB
Python

from pathlib import Path
from repo_manager.cli import main
from repo_manager.prefix_registry import scan_prefixes
from repo_manager.standards import check_repository, resolve_flavor
def _write(path: Path, text: str) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text)
def _durable_files(root: Path) -> None:
_write(root / "INTENT.md", "# Intent\n\nWhy this exists.\n")
_write(root / "SCOPE.md", "# Scope\n")
_write(root / "README.md", "# Demo\n")
_write(root / "AGENTS.md", "# Agents\n")
_write(
root / ".repo-classification.yaml",
"repo_classification:\n category: tooling\n domain: infotech\n",
)
_write(
root / "workplans" / "DEMO-WP-0001.md",
"---\nid: DEMO-WP-0001\nstatus: proposed\n---\n# Demo\n",
)
def test_prj_repo_flags_intent_and_goal(tmp_path: Path):
root = tmp_path / "prj-demo"
_durable_files(root)
_write(
root / "GOAL.md",
"---\nrepo_flavor: project\n---\n# Goal\n\n"
"## Outcome\nX\n## Invariants\nY\n## Success gates\nZ\n## Project retirement\nW\n",
)
_write(
root / ".repo-classification.yaml",
"repo_classification:\n category: project\n domain: infotech\n",
)
report = check_repository(root)
codes = {f.code for f in report.findings}
assert "intent-and-goal" in codes
assert report.ok is False
assert report.flavor.prj_layout is True
def test_prj_repo_flags_flavor_derived_prefix(tmp_path: Path):
root = tmp_path / "prj-cutover"
_write(root / "GOAL.md", "## Outcome\n## Invariants\n## Success gates\n## Project retirement\n")
_write(root / "SCOPE.md", "# S\n")
_write(root / "README.md", "# R\n")
_write(root / "AGENTS.md", "# A\n")
_write(
root / ".repo-classification.yaml",
"repo_classification:\n category: project\n domain: infotech\n",
)
_write(
root / "workplans" / "PRJ-WP-0001.md",
"---\nid: PRJ-WP-0001\nstatus: proposed\n---\n# Bad\n",
)
report = check_repository(root)
assert any(f.code == "flavor-derived-prefix" for f in report.findings)
def test_durable_repo_missing_intent(tmp_path: Path):
root = tmp_path / "some-tool"
_write(root / "SCOPE.md", "# S\n")
_write(root / "README.md", "# R\n")
_write(root / "AGENTS.md", "# A\n")
_write(
root / ".repo-classification.yaml",
"repo_classification:\n category: tooling\n domain: infotech\n",
)
(root / "workplans").mkdir()
report = check_repository(root)
assert any(f.code == "required-file-missing" and f.path == "INTENT.md" for f in report.findings)
def test_flavor_disagreement_is_warning(tmp_path: Path):
root = tmp_path / "mixed"
_durable_files(root)
_write(root / "GOAL.md", "---\nrepo_flavor: project\n---\n# G\n")
flavor = resolve_flavor(root)
assert flavor.disagreements
report = check_repository(root)
assert any(f.code == "flavor-signal-disagreement" and f.severity == "warning" for f in report.findings)
def test_prefix_uniqueness_detects_share_and_reuse(tmp_path: Path):
a = tmp_path / "alpha"
b = tmp_path / "beta"
for repo, ident in ((a, "SHARED-WP-0001"), (b, "SHARED-WP-0001")):
_write(
repo / "workplans" / f"{ident}.md",
f"---\nid: {ident}\nstatus: finished\n---\n# X\n",
)
report = scan_prefixes(tmp_path)
assert report["ok"] is False
assert "SHARED-WP" in report["shared_prefixes"]
assert "SHARED-WP-0001" in report["reused_identifiers"]
def test_cli_conform_and_prefix(tmp_path: Path, capsys):
root = tmp_path / "ok-tool"
_durable_files(root)
assert main(["conform", "--path", str(root)]) == 0
fleet = tmp_path / "fleet"
one = fleet / "one"
_write(one / "workplans" / "PRJ-WP-0001.md", "---\nid: PRJ-WP-0001\nstatus: proposed\n---\n")
assert main(["prefix-uniqueness", "--root", str(fleet)]) == 1
out = capsys.readouterr().out
assert "PRJ-WP" in out or "flavor_derived" in out