# FablePool constitutional test suite — CI gate. # # Three jobs guard every pull request: # 1. validate — structural validation of the scenario corpus # 2. unit-tests — engine / DSL / harness unit tests (pytest) # 3. amendment-gate (PRs only) — runs the full adversarial corpus # against BOTH the base branch's constitution and the PR's # constitution. Any scenario that the current text defends but # the proposed text does not is a regression and blocks the merge. # # A push to main re-runs the full suite against the ratified text so the # corpus and the constitution can never silently drift apart. name: constitutional-tests on: pull_request: push: branches: [main] permissions: contents: read jobs: validate: name: Validate scenario corpus runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install run: | python -m pip install --upgrade pip pip install -e . - name: Validate corpus run: python -m fabletest validate --corpus scenarios unit-tests: name: Engine, DSL, and harness unit tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install run: | python -m pip install --upgrade pip pip install -e . pytest - name: Run pytest run: pytest -q full-suite: name: Full adversarial corpus (ratified text) runs-on: ubuntu-latest needs: [validate] if: github.event_name == 'push' steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install run: | python -m pip install --upgrade pip pip install -e . - name: Run corpus run: | mkdir -p reports python -m fabletest run \ --corpus scenarios \ --params constitution/parameters.yaml \ --format github \ --report-out reports/suite-report.json - name: Upload report if: always() uses: actions/upload-artifact@v4 with: name: suite-report path: reports/ amendment-gate: name: Amendment gate (blocks PR on regression) runs-on: ubuntu-latest needs: [validate] if: github.event_name == 'pull_request' steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install run: | python -m pip install --upgrade pip pip install -e . - name: Extract baseline parameters from base branch env: BASE_REF: ${{ github.base_ref }} run: | git fetch origin "$BASE_REF" --depth=1 if git show "origin/$BASE_REF:constitution/parameters.yaml" > /tmp/baseline-parameters.yaml 2>/dev/null; then echo "baseline extracted from origin/$BASE_REF" else echo "no baseline on base branch; falling back to working tree" cp constitution/parameters.yaml /tmp/baseline-parameters.yaml fi - name: Evaluate amendment against the full corpus run: | mkdir -p reports python -m fabletest check-amendment \ --corpus scenarios \ --baseline /tmp/baseline-parameters.yaml \ --proposed constitution/parameters.yaml \ --format github \ --report-out reports/amendment-report.json - name: Upload amendment report if: always() uses: actions/upload-artifact@v4 with: name: amendment-report path: reports/