validators.py
python
sha256:0e9549ec7b463911bc08b7d586dc320b1ac9b1f5c943ee7e3865dcc6cb0f6f83
chore(governance): sync handover+roadmap to 84db8c8 (drift:…
Human
14 hours ago
| 1 | """Owner/repo/path validators and allowlist helpers (§HGD.4.2, §HGD.5.3).""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | import re |
| 6 | |
| 7 | OWNER_REPO_SEGMENT_RE = re.compile(r"^[A-Za-z0-9._-]+$") |
| 8 | ALLOWLIST_ENTRY_RE = re.compile(r"^[A-Za-z0-9._-]+(?:/[A-Za-z0-9._-]+)?$") |
| 9 | |
| 10 | DEFAULT_ORG_ENUMERATION_CAP = 100 |
| 11 | DEFAULT_ROADMAP_PATH = "docs/ROADMAP.md" |
| 12 | DEFAULT_HANDOVER_PATH = "docs/OVERSEER-HANDOVER.md" |
| 13 | MARKER_PATH = ".overseer/config.yaml" |
| 14 | |
| 15 | |
| 16 | def valid_owner_repo_segment(value: str) -> bool: |
| 17 | """Return whether ``value`` matches the frozen owner/repo segment pattern.""" |
| 18 | return bool(value) and bool(OWNER_REPO_SEGMENT_RE.match(value)) |
| 19 | |
| 20 | |
| 21 | def parse_allowlist_entry(entry: str) -> tuple[str, str | None]: |
| 22 | """Parse an allowlist entry into ``(owner, repo_or_None)``. |
| 23 | |
| 24 | Raises ``ValueError`` when the entry does not match the frozen shape. |
| 25 | """ |
| 26 | if not isinstance(entry, str) or not entry.strip(): |
| 27 | raise ValueError("empty allowlist entry") |
| 28 | text = entry.strip() |
| 29 | if not ALLOWLIST_ENTRY_RE.match(text): |
| 30 | raise ValueError(f"invalid allowlist entry: {entry!r}") |
| 31 | if "/" in text: |
| 32 | owner, repo = text.split("/", 1) |
| 33 | return owner, repo |
| 34 | return text, None |
| 35 | |
| 36 | |
| 37 | def validate_allowlist(entries: list[str]) -> list[tuple[str, str | None]]: |
| 38 | """Validate and return normalized allowlist pairs.""" |
| 39 | return [parse_allowlist_entry(e) for e in entries] |
| 40 | |
| 41 | |
| 42 | def unknown_query_keys(query: dict[str, list[str]], *, allowed: frozenset[str] = frozenset()) -> list[str]: |
| 43 | """Return query keys not in ``allowed`` (empty allowed → any key is unknown).""" |
| 44 | return sorted(k for k in query if k not in allowed) |
File History
1 commit
sha256:6abcf1fa82a7a621ccbc945f19acdba5bc0db54569599404a1452fb4a096a199
fix(ISR): default require_independent_second_reviewer to require
Human
minor
⚠
13 hours ago