"""Structured issue/branch ownership evidence (#440). Author branches must follow ``(fix|feat|docs|chore)/issue--``. Duplicate-work and recovery gates use this parser instead of broad substring checks like ``issue-420`` inside unrelated names (for example ``issue-4200``). """ from __future__ import annotations import re IMPLEMENTATION_BRANCH_RE = re.compile( r"^(?:fix|feat|docs|chore)/issue-(\d+)(?:-.+)?$" ) def parse_tracked_issue_number(branch_name: str) -> int | None: """Return the issue number encoded in a canonical author branch name.""" text = (branch_name or "").strip() if not text: return None match = IMPLEMENTATION_BRANCH_RE.match(text) if not match: return None return int(match.group(1)) def branch_tracks_issue(branch_name: str, issue_number: int) -> bool: """True when ``branch_name`` structurally belongs to ``issue_number``.""" parsed = parse_tracked_issue_number(branch_name) return parsed == issue_number if parsed is not None else False