From 7074eff9164c1299da1e127583cf7acfe8806aac Mon Sep 17 00:00:00 2001 From: Ahmet Abdullah Gultekin Date: Sat, 13 Jun 2026 09:40:59 +0000 Subject: [PATCH] repo-structure: freeze root layout + add structure-check gate Mirrors the FIVUCSAS umbrella pilot (Rollingcat-Software/FIVUCSAS#209): freezes the current root file/dir layout and adds the structure-check CI gate. Owner adds the additive ruleset / required check afterward to make it blocking. --- .github/workflows/structure-check.yml | 19 +++++++++ .pre-commit-config.yaml | 8 ++++ .repo-structure.yml | 60 +++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 .github/workflows/structure-check.yml create mode 100644 .repo-structure.yml diff --git a/.github/workflows/structure-check.yml b/.github/workflows/structure-check.yml new file mode 100644 index 00000000..0ee71283 --- /dev/null +++ b/.github/workflows/structure-check.yml @@ -0,0 +1,19 @@ +# Repo structure-lock gate — mirrors the FIVUCSAS umbrella pilot +# (Rollingcat-Software/FIVUCSAS#209). +# +# Thin caller for the org-shared reusable workflow. It FREEZES this repo's root +# layout (see .repo-structure.yml) and FAILS the PR when a disallowed/forbidden +# file appears — e.g. a stray dated tracking doc at the root. +# +# Owner step to make it BLOCK merges: add the status check named +# "repo-structure / structure-check" (the reusable job) as a REQUIRED check in +# this repo's branch protection / ruleset. See the PR body for context. +name: structure-check + +on: + pull_request: + branches: [main] + +jobs: + repo-structure: + uses: Rollingcat-Software/.github/.github/workflows/repo-structure.yml@main diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0278d992..426204f8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,3 +5,11 @@ repos: rev: v8.21.2 hooks: - id: gitleaks + # Repo structure-lock (mirrors FIVUCSAS#209) — fast local feedback mirroring + # the CI gate (.github/workflows/structure-check.yml). Freezes the root layout + # and blocks stray/dated tracking docs before they are committed. Pin `rev` to + # a tag/SHA once the org .github repo cuts one. + - repo: https://github.com/Rollingcat-Software/.github + rev: main + hooks: + - id: repo-structure diff --git a/.repo-structure.yml b/.repo-structure.yml new file mode 100644 index 00000000..ca668240 --- /dev/null +++ b/.repo-structure.yml @@ -0,0 +1,60 @@ +# Repo structure-lock policy — Rollingcat-Software/client-apps +# +# An ArchUnit-style FREEZE of this repo's ROOT layout, mirroring the FIVUCSAS +# umbrella pilot (Rollingcat-Software/FIVUCSAS#209). The allowlists below were +# frozen from the current origin/main root; the gate (tools/check_repo_structure.py +# in the org .github repo, run via the reusable workflow +# .github/workflows/repo-structure.yml) FAILS CI when: +# * a root entry not listed here appears, OR +# * any root entry matches a forbidden pattern, OR +# * a required file is missing. +# +# Dated tracking docs (audits / reviews / sessions / TODOs) belong in GitHub +# issues, NOT the repo root — that is what forbidden_root_patterns encodes. +# To intentionally add a NEW root entry, add it here in the SAME PR (the +# explicit, reviewed "unfreeze"). Parsed by a stdlib-only YAML subset, so keep +# to simple `- "string"` block lists. + +allowed_root_files: + - ".dockerignore" + - ".env.example" + - ".gitignore" + - ".pre-commit-config.yaml" + - ".repo-structure.yml" + - "CHANGELOG.md" + - "CLAUDE.md" + - "Dockerfile" + - "LICENSE" + - "README.md" + - "SECURITY.md" + - "build.gradle.kts" + - "docker-compose.yml" + - "gradle.properties" + - "gradlew" + - "gradlew.bat" + - "settings.gradle.kts" + - "setup.bat" + +allowed_root_dirs: + - ".claude" + - ".github" + - "androidApp" + - "desktopApp" + - "docs" + - "gradle" + - "scripts" + - "shared" + +# Dated / tracking-doc names that must NEVER reappear at the root. +# These are Python `re` patterns, matched with re.search against each root entry +# name. Tracking content goes in GitHub issues instead. Use SINGLE quotes so +# backslashes stay literal (write \d and \. — not \\d) for the regex engine. +forbidden_root_patterns: + - '.*_(AUDIT|REVIEW|FINDINGS|REGISTER|TRIAGE|SWEEP|STATUS|SESSION|RECONCILIATION)_.*\.md$' + - '.*_\d{4}-\d{2}-\d{2}.*\.md$' + - '^(TODO|ROADMAP|BACKLOG|OPERATOR_TODO|PERSONAL_TODO).*\.md$' + +required_files: + - "README.md" + - "LICENSE" + - ".gitignore"