Skip to content

⚙️ Workflows

Council ships with two GitHub Actions workflows. Which one you use depends on who opened the PR and whether secrets are available.


🔀 Quick Decision Guide

Who opened the PR?
   ┌────┴──────┐
   │              │
 You / your team   External / fork contributor
   │              │
   ▼              ▼
council-review.yml    council-byok.yml
(auto, on PR open)    (manual, workflow_dispatch)

📊 Side-by-Side Comparison

council-review.yml council-byok.yml
Trigger pull_request (automatic) workflow_dispatch (manual)
Secrets access Repository GOOGLE_API_KEY secret Fork/repo GOOGLE_API_KEY secret that you supply
Fork PRs ⚠️ Skips LLM step (no secrets) ✅ Full review (you trigger it)
Inputs None — runs on the PR branch base_ref, upstream_repo, audience
Input validation N/A ✅ Branch ref + repo format validated
Artifacts council-report.json council-report.json + council-review.md
Use case Every PR from your own branches Fork PRs, external contributors, targeted re-runs

🔄 PR Workflow — council-review.yml

This is the always-on review gate. It fires automatically when a PR is opened or updated.

What it does

  1. Checks out the PR branch
  2. Checks whether GOOGLE_API_KEY is available
  3. If the key is available: writes a temporary Gemini config and runs the full 5-stage pipeline, including Gate Zero
  4. If the Gemini secret is unavailable (fork PR or missing repo secret): skips LLM, uploads a report explaining the skip
  5. Uploads council-report.json as a workflow artifact

Where to find the artifact

Actions tab → [workflow run] → Artifacts → council-report

Fork PRs

Fork PRs cannot access repository secrets — this is GitHub's security model, not a Council bug. The PR workflow detects missing GOOGLE_API_KEY, skips the LLM step, and uploads a council-report.json explaining the skip. Do not work around this. Use council-byok.yml with a fork-local GOOGLE_API_KEY to review fork contributor PRs.


🔑 BYOK Workflow — council-byok.yml

This is the manual, key-controlled review workflow. You trigger it explicitly from the Actions tab. It is also pinned to Gemini and fails fast if GOOGLE_API_KEY is not configured in the repository or fork where it runs.

Workflow dispatch inputs

Input Required Description
base_ref ✅ Yes The base branch to diff against (e.g. main)
upstream_repo ❌ Optional Full owner/repo if reviewing a fork (e.g. contributor/myrepo)
audience ❌ Optional Output audience: developer (default) or owner

Input validation

Before running, the BYOK workflow validates:

  • base_ref passes git check-ref-format (prevents injection via malformed ref)
  • upstream_repo matches owner/repo format if provided (prevents redirect attacks)
  • All file reads are contained within the repo root via is_relative_to() (prevents path traversal)

Use restricted keys

The BYOK workflow uses your repository secrets directly. Use inference-only API keys with no billing or admin access. See Security → API Key Hardening.

How to trigger

Actions tab → council-byok → Run workflow → fill inputs → Run

Both workflows use gemini/gemini-3-pro-preview in CI, set reviewer_timeout_seconds = 360, and run reviewers sequentially with reviewer_concurrency = 1 to reduce preview-model timeout/rate-limit noise.


📦 Artifacts Reference

Artifact File Workflow Contents
council-report council-report.json Both Full ChairVerdict: per-reviewer findings, confidence, degraded reasons, final verdict
council-report council-review.md BYOK only Human-readable markdown review (developer or owner format)

Finding your artifacts

GitHub → Actions tab → Select workflow run → Artifacts section (bottom of summary page)

Getting council-review.md from a PR workflow run

The PR workflow currently only uploads council-report.json. To get the markdown review:

Option A — Run the BYOK workflow against the same branch

Option B — Run locally:

council review --branch main --output-md council-review.md

💻 Local Workflow

Local runs are always advisory by default — they never block a push.

Mode Command Blocks on FAIL?
Advisory council review --branch main No
Advisory + JSON council review --branch main --output-json report.json No
Advisory + Markdown council review --branch main --output-md review.md No
CI mode council review --ci --branch main Yes

CI mode (--ci) exits non-zero on FAIL. PASS WITH WARNINGS always exits zero.


  • Getting Started — install, init, first review, adding secrets
  • Security — BYOK threat model, input validation details, fork PR policy
  • Design — the 5-stage pipeline these workflows invoke