⚙️ 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¶
- Checks out the PR branch
- Checks whether
GOOGLE_API_KEYis available - If the key is available: writes a temporary Gemini config and runs the full 5-stage pipeline, including Gate Zero
- If the Gemini secret is unavailable (fork PR or missing repo secret): skips LLM, uploads a report explaining the skip
- Uploads
council-report.jsonas a workflow artifact
Where to find the artifact¶
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_refpassesgit check-ref-format(prevents injection via malformed ref)upstream_repomatchesowner/repoformat 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¶
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¶
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:
💻 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.
⏩ Related Pages¶
- 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