board_names.py
python
sha256:0e9549ec7b463911bc08b7d586dc320b1ac9b1f5c943ee7e3865dcc6cb0f6f83
chore(governance): sync handover+roadmap to 84db8c8 (drift:…
Human
1 day ago
| 1 | """Board filename identity helpers (§MR.6.5).""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | import re |
| 6 | |
| 7 | _NON_ALNUM = re.compile(r"[^A-Za-z0-9]+") |
| 8 | |
| 9 | |
| 10 | def repo_slug(repo_name: str) -> str: |
| 11 | """Uppercase ``repo.name`` with non-alnum → ``-`` collapsed (§MR.6.5).""" |
| 12 | text = (repo_name or "").strip() |
| 13 | if not text: |
| 14 | return "" |
| 15 | collapsed = _NON_ALNUM.sub("-", text).strip("-") |
| 16 | return collapsed.upper() |
| 17 | |
| 18 | |
| 19 | def expected_handover_basename(repo_name: str, *, lane: str | None = None) -> str: |
| 20 | """Default-lane or lane-prefixed handover basename.""" |
| 21 | slug = repo_slug(repo_name) |
| 22 | if lane and lane.strip() and lane.strip().lower() not in {"product", "default"}: |
| 23 | return f"{slug}-{lane.strip().upper()}-OVERSEER-HANDOVER.md" |
| 24 | return f"{slug}-OVERSEER-HANDOVER.md" |
| 25 | |
| 26 | |
| 27 | def expected_roadmap_basename(repo_name: str, *, lane: str | None = None) -> str: |
| 28 | """Default-lane or lane-prefixed roadmap basename.""" |
| 29 | slug = repo_slug(repo_name) |
| 30 | if lane and lane.strip() and lane.strip().lower() not in {"product", "default"}: |
| 31 | return f"{slug}-{lane.strip().upper()}-ROADMAP.md" |
| 32 | return f"{slug}-ROADMAP.md" |
| 33 | |
| 34 | |
| 35 | def expected_handover_title(repo_name: str, *, lane: str | None = None) -> str: |
| 36 | """Human title including repo (or lane) label.""" |
| 37 | label = (repo_name or "").strip() or "Repo" |
| 38 | if lane and lane.strip() and lane.strip().lower() not in {"product", "default"}: |
| 39 | return f"{label} {lane.strip()} Overseer Handover" |
| 40 | # Title-case-ish: keep slug readable — use repo_name as given. |
| 41 | pretty = label.replace("-", " ").replace("_", " ") |
| 42 | if pretty.islower() or pretty.isupper(): |
| 43 | pretty = pretty.title() |
| 44 | return f"{pretty} Overseer Handover" |
| 45 | |
| 46 | |
| 47 | def expected_roadmap_title(repo_name: str, *, lane: str | None = None) -> str: |
| 48 | label = (repo_name or "").strip() or "Repo" |
| 49 | if lane and lane.strip() and lane.strip().lower() not in {"product", "default"}: |
| 50 | return f"{label} {lane.strip()} Roadmap" |
| 51 | pretty = label.replace("-", " ").replace("_", " ") |
| 52 | if pretty.islower() or pretty.isupper(): |
| 53 | pretty = pretty.title() |
| 54 | return f"{pretty} Roadmap" |
| 55 | |
| 56 | |
| 57 | _BARE_HANDOVER = frozenset({"overseer-handover.md"}) |
| 58 | _BARE_ROADMAP = frozenset({"roadmap.md"}) |
| 59 | |
| 60 | |
| 61 | def is_bare_legacy_basename(name: str, *, kind: str) -> bool: |
| 62 | """True when basename is the bare legacy pair (case-insensitive).""" |
| 63 | base = Path_basename(name).lower() |
| 64 | if kind == "handover": |
| 65 | return base in _BARE_HANDOVER |
| 66 | if kind == "roadmap": |
| 67 | return base in _BARE_ROADMAP |
| 68 | return False |
| 69 | |
| 70 | |
| 71 | def Path_basename(path_or_name: str) -> str: |
| 72 | """Basename helper without importing pathlib at module top for tests.""" |
| 73 | from pathlib import Path |
| 74 | |
| 75 | return Path(path_or_name).name |
| 76 | |
| 77 | |
| 78 | def matches_prefixed_pattern(basename: str, repo_name: str, *, kind: str) -> bool: |
| 79 | """True when basename starts with ``{REPO_SLUG}-`` and matches kind suffix.""" |
| 80 | slug = repo_slug(repo_name) |
| 81 | if not slug: |
| 82 | return False |
| 83 | name = Path_basename(basename) |
| 84 | if not name.upper().startswith(f"{slug}-"): |
| 85 | return False |
| 86 | upper = name.upper() |
| 87 | if kind == "handover": |
| 88 | return upper.endswith("-OVERSEER-HANDOVER.MD") or upper.endswith("OVERSEER-HANDOVER.MD") |
| 89 | if kind == "roadmap": |
| 90 | return upper.endswith("-ROADMAP.MD") or upper.endswith("ROADMAP.MD") |
| 91 | return False |
| 92 | |
| 93 | |
| 94 | def board_name_violation( |
| 95 | *, |
| 96 | repo_name: str, |
| 97 | handover_basename: str | None, |
| 98 | roadmap_basename: str | None, |
| 99 | strict: bool, |
| 100 | ) -> bool: |
| 101 | """True when ``strict_board_names`` and board names are bare/unprefixed.""" |
| 102 | if not strict: |
| 103 | return False |
| 104 | if handover_basename is None or roadmap_basename is None: |
| 105 | return True |
| 106 | if is_bare_legacy_basename(handover_basename, kind="handover"): |
| 107 | return True |
| 108 | if is_bare_legacy_basename(roadmap_basename, kind="roadmap"): |
| 109 | return True |
| 110 | if not matches_prefixed_pattern(handover_basename, repo_name, kind="handover"): |
| 111 | return True |
| 112 | if not matches_prefixed_pattern(roadmap_basename, repo_name, kind="roadmap"): |
| 113 | return True |
| 114 | return False |
File History
1 commit
sha256:6abcf1fa82a7a621ccbc945f19acdba5bc0db54569599404a1452fb4a096a199
fix(ISR): default require_independent_second_reviewer to require
Human
minor
⚠
1 day ago