# vibe_erp — architectural guardrail CI. # # Defends two rules from CLAUDE.md guardrails #9 and #10: # - PBCs may NEVER import other PBCs # - api-v1 and reference-customer code may only see api.v1.* — never # org.vibeerp.platform.* or org.vibeerp.pbc.* # # Primary defense: the root build.gradle.kts afterEvaluate hooks reject # illegal Gradle dependencies. This workflow simply runs the build so # violations fail CI. # # Secondary defense: a source-tree grep for forbidden imports inside the # api-v1 and reference-customer trees. This catches anyone reaching past # the build system (e.g. via reflection-friendly imports). name: check-architecture on: pull_request: jobs: build-guard: name: gradle dependency rule runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: temurin java-version: "21" - name: Cache Gradle uses: actions/cache@v4 with: path: | ~/.gradle/caches ~/.gradle/wrapper key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'gradle/libs.versions.toml') }} - name: Build (enforces dependency rule via afterEvaluate hooks) run: ./gradlew build --no-daemon import-guard: name: forbidden-import grep runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Reject internal imports from api-v1 and reference-customer shell: bash run: | set -euo pipefail violations=0 for path in api/api-v1/src reference-customer; do if [ -d "$path" ]; then if grep -RInE 'import[[:space:]]+org\.vibeerp\.(platform|pbc)' "$path"; then echo "::error::Forbidden internal import found under $path" violations=$((violations + 1)) fi fi done if [ "$violations" -gt 0 ]; then echo "Architectural violation: api-v1 and reference-customer may only depend on org.vibeerp.api.v1.*" exit 1 fi echo "OK — no forbidden imports."