diff --git a/.github/rulesets/Immutable-Tags.json b/.github/rulesets/Immutable-Tags.json new file mode 100644 index 0000000..53739af --- /dev/null +++ b/.github/rulesets/Immutable-Tags.json @@ -0,0 +1,19 @@ +{ + "name": "Immutable-Tags", + "target": "tag", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": ["~ALL"], + "exclude": [] + } + }, + "bypass_actors": [], + "rules": [ + {"type": "creation"}, + {"type": "deletion"}, + {"type": "non_fast_forward"}, + {"type": "update"}, + {"type": "required_signatures"} + ] +} diff --git a/.github/rulesets/Optimus-Branch.json b/.github/rulesets/Optimus-Branch.json new file mode 100644 index 0000000..03ad488 --- /dev/null +++ b/.github/rulesets/Optimus-Branch.json @@ -0,0 +1,44 @@ +{ + "name": "Optimus-Branch", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": ["~DEFAULT_BRANCH"], + "exclude": [] + } + }, + "bypass_actors": [], + "rules": [ + { + "type": "deletion" + }, + { + "type": "non_fast_forward" + }, + { + "type": "required_signatures" + }, + { + "type": "pull_request", + "parameters": { + "required_approving_review_count": 2, + "dismiss_stale_reviews_on_push": true, + "require_code_owner_review": true, + "require_last_push_approval": true, + "required_review_thread_resolution": true, + "require_extra_approval_for_unattributed_changes": true, + "required_reviewers": [], + "allowed_merge_methods": [] + } + }, + { + "type": "required_status_checks", + "parameters": { + "strict_required_status_checks_policy": true, + "do_not_enforce_on_create": false, + "required_status_checks": [] + } + } + ] +} diff --git a/.github/settings.yml b/.github/settings.yml index 6860868..c0afd2f 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -105,21 +105,3 @@ labels: # ─── Branch Protection ───────────────────────────────────────────────────────── -branches: - - name: "main" - protection: - required_pull_request_reviews: - required_approving_review_count: 1 - dismiss_stale_reviews: true - require_code_owner_reviews: true - required_status_checks: - strict: true - contexts: - - "hypatia-scan" - - "codeql" - - "openssf-compliance" - enforce_admins: true - required_signatures: true - restrictions: null - allow_force_pushes: false - allow_deletions: false diff --git a/.github/workflows/ci-benchmarks.yml b/.github/workflows/ci-benchmarks.yml new file mode 100644 index 0000000..bbffbff --- /dev/null +++ b/.github/workflows/ci-benchmarks.yml @@ -0,0 +1,178 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +# +# KRL CI: Benchmarks and Tests +# +# Runs: +# 1. Language-specific tests (lexer, parser, queries) +# 2. Central benchmarks from proven-tests-and-benchmarks repo +# 3. GitGuardian secret scanning +# 4. SonarQubeCloud quality analysis +# 5. Existing E2E tests + +name: CI - Tests & Benchmarks + +on: + push: + branches: [main, develop] + paths: + - 'src/**' + - 'server/**' + - 'benches/**' + - 'tests/**' + - '.github/workflows/ci-benchmarks.yml' + pull_request: + branches: [main] + paths: + - 'src/**' + - 'server/**' + - 'benches/**' + - 'tests/**' + - '.github/workflows/ci-benchmarks.yml' + workflow_dispatch: + schedule: + # Nightly benchmarks + - cron: '0 2 * * *' + +permissions: + contents: read + pull-requests: write + +concurrency: + group: ci-benchmarks-${{ github.ref }} + cancel-in-progress: true + +env: + BENCHMARKS_REPO: hyperpolymath/proven + BENCHMARKS_PATH: benchmarks/krl + +jobs: + # Job 1: Run KRL-specific tests + krl-tests: + name: KRL Tests + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout KRL repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Zig + uses: goto-bus-stop/setup-zig@v2 + with: + version: 0.16.0 + + - name: Set up Julia + uses: julia-actions/setup-julia@v2 + with: + version: '1.12' + + - name: Run existing E2E tests + uses: ./.github/workflows/e2e.yml + + - name: Run lexer/parser tests + run: | + # TODO: Replace with actual KRL lexer/parser tests + julia --color=yes server/krl/test/lexer_test.jl + julia --color=yes server/krl/test/parser_test.jl + + - name: Run query tests + run: | + # TODO: Replace with actual KRL query tests + julia --color=yes server/krl/test/sql_test.jl + + # Job 2: Run central benchmarks + benchmarks: + name: KRL Benchmarks + needs: krl-tests + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout KRL repo + uses: actions/checkout@v4 + + - name: Checkout proven benchmarks repo + uses: actions/checkout@v4 + with: + repository: ${{ env.BENCHMARKS_REPO }} + path: proven + + - name: Install benchmark dependencies + run: | + sudo apt-get update + sudo apt-get install -y jq bc + + - name: Run KRL benchmarks + run: | + cd proven/benchmarks/krl + # Run all benchmarks and compare with baselines + ./run.sh --all + + - name: Upload benchmark results + uses: actions/upload-artifact@v4 + if: always() + with: + name: krl-benchmark-results + path: proven/benchmarks/krl/results.json + retention-days: 30 + + # Job 3: GitGuardian secret scanning + gitguardian: + name: GitGuardian Secret Scan + needs: krl-tests + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: GitGuardian scan + uses: GitGuardian/ggshield-action@v1 + with: + args: scan repo . + env: + GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} + + # Job 4: SonarQubeCloud quality analysis + sonarqube: + name: SonarQubeCloud Analysis + needs: krl-tests + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: SonarQube scan + uses: SonarSource/sonarqube-scan-action@v2 + with: + args: >- + -Dsonar.projectKey=krl + -Dsonar.organization=hyperpolymath + -Dsonar.sources=src,server + -Dsonar.language=julia + env: + SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }} + + # Job 5: CodeQL analysis (existing) + codeql: + name: CodeQL Analysis + needs: krl-tests + uses: ./.github/workflows/codeql.yml + secrets: inherit + + # Job 6: Dependabot (existing) + dependabot: + name: Dependabot + needs: krl-tests + uses: ./.github/workflows/dependabot-automerge.yml + secrets: inherit diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index bce3810..8b3e471 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -39,7 +39,7 @@ on: pull_request: types: [opened, reopened, synchronize] permissions: - contents: write # needed to enable auto-merge + contents: read # needed to enable auto-merge pull-requests: write # needed to approve # NB: keep narrow — do NOT add secrets: read or id-token: write here. jobs: diff --git a/.github/workflows/fragment-conformance.yml b/.github/workflows/fragment-conformance.yml new file mode 100644 index 0000000..0b70903 --- /dev/null +++ b/.github/workflows/fragment-conformance.yml @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: MPL-2.0 +name: KRL fragment conformance +on: + pull_request: + push: + branches: [main, master] + workflow_dispatch: +permissions: + contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +jobs: + fragment: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout specification + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + with: + persist-credentials: false + - name: Checkout current QuandleDB implementation + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + with: + repository: hyperpolymath/quandledb + path: deps/quandledb + persist-credentials: false + - name: Record implementation revision + run: git -C deps/quandledb rev-parse HEAD + - name: Install Julia 1.12 + run: | + set -euo pipefail + curl -fsSL https://install.julialang.org -o "$RUNNER_TEMP/juliaup-init.sh" + sh "$RUNNER_TEMP/juliaup-init.sh" --yes --default-channel 1.12 + echo "$HOME/.juliaup/bin" >> "$GITHUB_PATH" + - name: Check fragment acceptance and rejection + run: julia --startup-file=no tests/conformance/retrieval_fragment.jl deps/quandledb diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 8776de0..3f783fa 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -13,4 +13,4 @@ permissions: jobs: governance: - uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 \ No newline at end of file + uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@f9dca6ded2cad8ab54044c1cb0489b558ae2682b \ No newline at end of file diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index fc2b1ae..42fed59 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -19,4 +19,4 @@ permissions: jobs: scan: - uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 \ No newline at end of file + uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@f9dca6ded2cad8ab54044c1cb0489b558ae2682b \ No newline at end of file diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 6bd847d..b0b1a01 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -8,5 +8,5 @@ permissions: contents: read jobs: mirror: - uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@d135b05bfc647d0c0fbfedc7e80f37ea50f49236 + uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@5b1d00229e5e8c0c0fbfedc7e80f37ea50f49236 secrets: inherit diff --git a/.github/workflows/rhodibot.yml b/.github/workflows/rhodibot.yml index d020405..2d36e45 100644 --- a/.github/workflows/rhodibot.yml +++ b/.github/workflows/rhodibot.yml @@ -19,7 +19,7 @@ on: workflows: ["Hypatia Neurosymbolic Analysis"] types: [completed] permissions: - contents: write + contents: read pull-requests: write jobs: rhodibot: diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 11d9b2a..b8acc98 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -11,7 +11,7 @@ permissions: jobs: scorecard: - uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 + uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@f9dca6ded2cad8ab54044c1cb0489b558ae2682b permissions: contents: read security-events: write diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index d51eed2..0e12d73 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -14,5 +14,5 @@ jobs: scan: permissions: contents: read - uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@7fdc2705df74b4e352d2a1cde3e87a5923fdf329 + uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@5b1d00229e5e8c0c0fbfedc7e80f37ea50f49236 secrets: inherit \ No newline at end of file