"""Exemption tables and namespace rules for the markdown-naming convention. The data half: which basenames are reserved by external tooling, which directory trees are exempt, and the prefix of the banned TODO files. :mod:`md_naming.rules` holds the predicates that read these, and :mod:`md_naming.config` re-exports both as the public surface. Deliberately built on top of :mod:`file_length._tables` for the shared notions of "excluded dir", "third-party repo" and "vendored tree". Restating those here is exactly what lets two gates disagree about the same file. """ from __future__ import annotations import re #: The three namespaces. A markdown file in a kuhy-owned repo must match one. #: #: README -- what this directory is and how to run it. #: CLAUDE* -- instructions Claude must read. #: DOCS* -- reference, findings, design records. Permanent. #: #: TODO*.md is banned outright (tasks live in the todo app). ALLOWED_PATTERN = re.compile(r"^(README|CLAUDE.*|DOCS.*)\.(md|markdown)$") #: Legacy: the removal marker of the retired TODO convention. No gate reads it #: any more; only the one-shot migrate/apply.py (kept as a record) imports it. MARKER = "REMOVE ME AFTER FINISH" #: Prefix identifying a banned task file. TODO_PREFIX = "TODO" #: Basenames owned by external tooling. Renaming these breaks the tool, so #: they are exempt from the namespace rule rather than migrated. #: #: SKILL.md -- the skill loader requires the literal filename. #: CLAUDE/AGENTS -- auto-loaded by the harness. #: copilot-* -- read by GitHub Copilot. HARNESS_NAMES = frozenset( { "SKILL.md", "CLAUDE.md", "AGENTS.md", "copilot-instructions.md", } ) #: Community-health and license-compliance names. GitHub keys off these exact #: filenames to surface contributing/security UI; CREDITS and ATTRIBUTION also #: back the standing "always attribute assets" rule, so renaming them would #: quietly weaken an unrelated guarantee. COMMUNITY_NAMES = frozenset( { "CONTRIBUTING.md", "SECURITY.md", "CODE_OF_CONDUCT.md", "CHANGELOG.md", "NOTICE.md", "CREDITS.md", "ATTRIBUTION.md", "THIRD_PARTY_NOTICES.md", "LICENSE.md", "ISSUE_TEMPLATE.md", "PULL_REQUEST_TEMPLATE.md", "BRANCH_PROTECTION.md", } ) #: Directory fragments whose markdown is machine-managed or vendored, wherever #: they appear. `.github/` holds templates GitHub names itself; the rest are #: agent-memory and skill-bundle trees dropped in from elsewhere. EXEMPT_SUBPATHS = ( "/.github/", "/.projectmem/", "/.hippo/", "/.agents/", "/.claude/", "/ios/Runner/", "/android/app/src/", ) #: A dated backup is never a live repo, so its markdown is not ours to name. #: Matched by *shape* rather than by listing each one: the 2026-09-11 ~ #: reorganisation renamed every backup into ~/archive/YYYY-MM-DD-, which #: silently invalidated the hand-listed #: "screen-locker-backup-20260705-200741" and left this gate red on main. DATED_BACKUP = re.compile(r"^\d{4}-\d{2}-\d{2}-") #: Repos under ~ that are clones of other people's work, in addition to the #: shared THIRD_PARTY_REPOS list. EXTRA_THIRD_PARTY = frozenset( { # Dotfile clones of other people's projects. These live outside ~/*/ # so a survey that walks only project dirs misses them -- the 2026-08-24 # migration renamed 5 files in nvm and ohmyzsh before this was added. ".nvm", ".oh-my-zsh", ".cargo", ".rustup", ".pyenv", ".fzf", ".tmux", "flax-editor", "flax-mcp-test", "diet-guard-peer-backup", "claude_refactor_staging", } )