# Ci

- Object ID: `em:automation:sha256:8564fbb863aa61b4f2dd7b69d98b4b3b4574fb052ebdbaf099c48cff55a6edd7`
- Kind: `automation`
- Repository path: [`.github/workflows/ci.yml`](https://github.com/yoheinakajima/epistemedia/blob/f92846570180dfa4511263f8ba98ecd18f7772c9/.github/workflows/ci.yml)
- Content digest: `103035b71129f518e1cab8753e1788631e1c8cec1c9a5dde235167626dd57ff4`

**Also filed under:** [Agent Operations](https://epistemedia.org/topics/agent-operations/), [Human and Agent Interfaces](https://epistemedia.org/topics/public-interfaces/), [Releases and Reproducibility](https://epistemedia.org/topics/releases/)

## Source content

name: validate

on:
  pull_request:
  push:
    branches: [main]
  workflow_dispatch:

permissions: {}

concurrency:
  group: validate-${{ github.ref }}
  cancel-in-progress: true

jobs:
  check:
    permissions:
      checks: read
      contents: read
      pull-requests: read
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }}
          path: candidate
          fetch-depth: 0
          persist-credentials: false
      - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
        with:
          ref: ${{ github.event.pull_request.base.sha || github.sha }}
          path: validator
          fetch-depth: 0
          persist-credentials: false
      - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
        with:
          python-version: "3.12"
          cache: pip
          cache-dependency-path: candidate/pyproject.toml
      - name: Classify docket contribution mode using accepted-base code
        id: classify
        shell: bash
        env:
          BASE_SHA: ${{ github.event.pull_request.base.sha }}
        run: |
          set -euo pipefail
          if [[ -f validator/ops/classify_docket_pr.py ]]; then
            python validator/ops/classify_docket_pr.py \
              --candidate candidate \
              --base-sha "$BASE_SHA" \
              --github-output "$GITHUB_OUTPUT"
          else
            # One-time bootstrap for the reviewed EM-0040 implementation. The accepted base
            # predates the classifier, so no docket-sensitive diff may pass this transition.
            mapfile -t bootstrap_paths < <(
              git -C candidate diff --name-only "$BASE_SHA...HEAD"
            )
            for path in "${bootstrap_paths[@]}"; do
              if [[ "$path" == research/open-dockets/* ]]; then
                echo "accepted base lacks the docket classifier; rejecting sensitive diff" >&2
                exit 1
              fi
            done
            echo "mode=normal" >> "$GITHUB_OUTPUT"
          fi
      - name: Install
        if: steps.classify.outputs.mode == 'normal'
        working-directory: candidate
        run: python -m pip install -e '.[dev]'
      - name: Validate, build, test, audit, and verify deterministic state
        if: steps.classify.outputs.mode == 'normal'
        working-directory: candidate
        run: make check
      - name: Validate and block untrusted submission using accepted-base code
        if: steps.classify.outputs.mode == 'submission'
        env:
          PYTHONPATH: validator/src
          BASE_SHA: ${{ github.event.pull_request.base.sha }}
          CURRENT_PR_NUMBER: ${{ github.event.pull_request.number }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          GITHUB_TOKEN: ${{ github.token }}
        run: python validator/ops/validate_submission_pr.py --candidate candidate --base-sha "$BASE_SHA"
      - name: Validate promotion using accepted-base code
        if: steps.classify.outputs.mode == 'promotion'
        env:
          PYTHONPATH: validator/src
          BASE_SHA: ${{ github.event.pull_request.base.sha }}
          CANDIDATE_SHA: ${{ github.event.pull_request.head.sha }}
          CURRENT_PR_NUMBER: ${{ github.event.pull_request.number }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          GITHUB_TOKEN: ${{ github.token }}
        run: python validator/ops/validate_promotion_pr.py --candidate candidate --base-sha "$BASE_SHA"
