diff --git a/.github/workflows/ai_review.yml b/.github/workflows/ai_review.yml new file mode 100644 index 0000000000..a58523c4a7 --- /dev/null +++ b/.github/workflows/ai_review.yml @@ -0,0 +1,95 @@ +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See LICENSE.md for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. + + +# Adversarial AI review: once every CI run for the PR head has finished and the +# Malicious Code Scan has passed (see malicious_code_scan.yml), Claude and Codex +# take turns reviewing the PR, fixing CI failures and other issues, and +# committing fixes until one of them approves without changes. The workflow, +# scripts and prompt live in OpenC3/.github (ai-review-reusable.yml). +# +# workflow_run fires once per completed CI workflow, and the scan starts this +# workflow with workflow_dispatch when it passes. workflow_run only uses the copy +# of this file on the default branch, so edits here take effect after they merge. +# +# Secrets: ANTHROPIC_API_KEY, OPENAI_API_KEY, AI_REVIEW_PUSH_TOKEN (to push fixes: a GitHub App +# token or fine-grained PAT with contents:write and no workflows permission, so GitHub refuses a +# fix that changes a workflow) +# Variables (optional): AI_REVIEW_MAX_TURNS, AI_REVIEW_MAX_CI_ROUNDS, AI_REVIEW_CLAUDE_MODEL, +# AI_REVIEW_CODEX_MODEL, AI_REVIEW_CLAUDE_MAX_BUDGET_USD, AI_REVIEW_CODEX_SANDBOX +# Add the `skip-ai-review` label to a PR to opt out. + +name: AI Review + +on: + # workflow_run: + # # Every workflow that runs on pull_request, plus GitHub's CodeQL default setup. Each run warns + # # about a missing one; the gate waits only on pull_request runs, not built-in ones like CodeQL. + # workflows: + # - API Tests + # - Build UBI + # - CLI Tests + # - CodeQL + # - Dependency Review + # - eslint + # - Frontend Generator Tests + # - Playwright Tests + # - Python Lint + # - Python Type Check + # - Python Unit Tests + # - Ruby Unit Tests + # - Shell Lint + # - Check Spelling + # - Tool Version Check + # - Trivy Scan + # - TSDB Integration Tests + # types: + # - completed + # # Pushes to main run CI too; skip them here instead of starting a run that does nothing + # branches-ignore: + # - main + workflow_dispatch: + inputs: + pr_number: + description: PR number to review + required: true + force: + description: Review even if this commit was already reviewed + type: boolean + default: false + +permissions: + contents: read + +jobs: + review: + uses: OpenC3/.github/.github/workflows/ai-review-reusable.yml@main + permissions: + actions: read + contents: read + pull-requests: write + statuses: read + with: + pr_number: ${{ inputs.pr_number }} + force: ${{ inputs.force || false }} + review_instructions: | + - Ruby/Python parity: COSMOS keeps equivalent Ruby (openc3/lib) and Python (openc3/python) + implementations, so a change to one usually needs the same change to the other. + max_turns: ${{ vars.AI_REVIEW_MAX_TURNS }} + max_ci_rounds: ${{ vars.AI_REVIEW_MAX_CI_ROUNDS }} + claude_model: ${{ vars.AI_REVIEW_CLAUDE_MODEL }} + codex_model: ${{ vars.AI_REVIEW_CODEX_MODEL }} + claude_max_budget_usd: ${{ vars.AI_REVIEW_CLAUDE_MAX_BUDGET_USD }} + codex_sandbox: ${{ vars.AI_REVIEW_CODEX_SANDBOX }} + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + AI_REVIEW_PUSH_TOKEN: ${{ secrets.AI_REVIEW_PUSH_TOKEN }} diff --git a/.github/workflows/malicious_code_scan.yml b/.github/workflows/malicious_code_scan.yml new file mode 100644 index 0000000000..69d8280791 --- /dev/null +++ b/.github/workflows/malicious_code_scan.yml @@ -0,0 +1,64 @@ +# Copyright 2026 OpenC3, Inc. +# All Rights Reserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See LICENSE.md for more details. + +# This file may also be used under the terms of a commercial license +# if purchased from OpenC3, Inc. + + +# Scans every PR for obfuscated code, prompt injection, and other malicious +# changes, and gates the AI Review workflow on the result. The workflow and +# scanner live in OpenC3/.github (malicious-code-scan-reusable.yml). +# +# This runs on pull_request_target so the workflow and scanner never come from +# the PR: a PR cannot edit its way past the scan, and fork PRs get the Claude +# review too. The PR is only ever read as data. +# +# The result is posted as the commit status `security/malicious-code-scan` on +# the PR head; make that a required check in branch protection. A maintainer +# (write access or above) accepts blocking findings with the +# `malicious-scan-override` label. +# +# Secrets: ANTHROPIC_API_KEY (the Claude review is skipped with a warning without it) +# Variables (optional): MALICIOUS_SCAN_CLAUDE_MODEL + +name: Malicious Code Scan + +on: + pull_request_target: + types: + - opened + - reopened + - synchronize + - edited + - ready_for_review + - labeled + +permissions: + contents: read + +jobs: + scan: + uses: OpenC3/.github/.github/workflows/malicious-code-scan-reusable.yml@main + permissions: + contents: read + statuses: write + pull-requests: write + actions: write + with: + review_workflow: ai_review.yml + project_description: >- + OpenC3 COSMOS, an open-source command and control system for spacecraft and embedded systems + (Ruby, Python, Vue/JS, shell, Docker) + claude_model: ${{ vars.MALICIOUS_SCAN_CLAUDE_MODEL }} + # The built docs site (Docusaurus output published to GitHub Pages; the source is docs.openc3.com/) + generated_paths: | + docs/**/*.html + docs/assets/** + docs/search-*.json + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}