From 79da1bfde3da20047de945c41d3106fe8280db91 Mon Sep 17 00:00:00 2001 From: Steve Dudenhoeffer Date: Sat, 27 Jun 2026 22:05:31 -0400 Subject: [PATCH 1/4] feat(reusable): ship the curated swarm as the default config consumers inherit Make the reusable workflow's input defaults BE the standard Gadfly swarm so a consumer subscribes by just calling it (no `with:` block) and inherits: - models: 3 strong cloud (minimax-m3, glm-5.2, deepseek-v4-pro) + Claude Code (sonnet, opus, opus:max) - specialists: the 5-lens default suite (security, correctness, maintainability, performance, error-handling) - provider_concurrency: ollama-cloud=3,claude-code=3 (all three claudes at once) - timeout_minutes default 45 -> 90 (5 lenses x 2 passes over a slow lane) The default is opinionated (needs OLLAMA_CLOUD_API_KEY + CLAUDE_CODE_OAUTH_TOKEN); consumers override `models:` for cloud-only / other providers. gadfly's own caller is slimmed to inherit (only allowed_users remains). examples/reusable.yml keeps a cloud-only `models:` override so a public copy works with just the Ollama key. README/CLAUDE.md updated. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitea/workflows/adversarial-review.yml | 22 ++++++--------- .gitea/workflows/review-reusable.yml | 37 +++++++++++++++---------- CLAUDE.md | 8 ++++-- README.md | 3 +- examples/reusable.yml | 21 +++++++++----- 5 files changed, 53 insertions(+), 38 deletions(-) diff --git a/.gitea/workflows/adversarial-review.yml b/.gitea/workflows/adversarial-review.yml index 27dc5db..c384d3e 100644 --- a/.gitea/workflows/adversarial-review.yml +++ b/.gitea/workflows/adversarial-review.yml @@ -1,10 +1,10 @@ -# Gadfly reviewing its OWN PRs — now a thin CALLER of the reusable workflow -# (.gitea/workflows/review-reusable.yml), dogfooding the Phase-4 "subscribe" -# path. The reusable holds the image pin + env plumbing; this file holds only -# the triggers, the actor gate, and gadfly's specific swarm config. +# Gadfly reviewing its OWN PRs — a thin CALLER of the reusable workflow +# (.gitea/workflows/review-reusable.yml), dogfooding the "subscribe" path. The +# reusable holds the image pin, env plumbing, AND the default swarm; this file +# holds only the triggers, the actor gate, secret forwarding, and allow-list. # -# Advisory only — never blocks a merge. Fleet: 6 cloud + Claude Code -# (sonnet, opus, opus:max) competitors. +# Advisory only — never blocks a merge. It inherits the default swarm: 3 cloud +# models + Claude Code (sonnet, opus, opus:max), 5-lens suite, 3 claudes at once. name: Adversarial Review (Gadfly) @@ -48,11 +48,7 @@ jobs: GADFLY_FINDINGS_URL: ${{ secrets.GADFLY_FINDINGS_URL }} GADFLY_FINDINGS_TOKEN: ${{ secrets.GADFLY_FINDINGS_TOKEN }} with: - models: "minimax-m3:cloud,glm-5.2:cloud,glm-5.1:cloud,deepseek-v4-pro:cloud,nemotron-3-super:cloud,qwen3-coder:480b-cloud,claude-code/sonnet,claude-code/opus,claude-code/opus:max" - specialists: "security,correctness,error-handling" - provider_concurrency: "ollama-cloud=3,claude-code=2" - provider_lens_concurrency: "ollama-cloud=3" - timeout_secs: "600" - max_steps: "14" + # Inherit the default swarm (3 cloud + Claude Code sonnet/opus/opus:max, + # 5-lens suite, all three claudes concurrent) from review-reusable.yml. + # Only the consumer-specific allow-list is set here. allowed_users: "steve,fizi,dazed" - timeout_minutes: 90 diff --git a/.gitea/workflows/review-reusable.yml b/.gitea/workflows/review-reusable.yml index fdb0921..68a96e9 100644 --- a/.gitea/workflows/review-reusable.yml +++ b/.gitea/workflows/review-reusable.yml @@ -10,11 +10,13 @@ # secrets: # forward ONLY what the reviewer needs # OLLAMA_CLOUD_API_KEY: ${{ secrets.OLLAMA_CLOUD_API_KEY }} # CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} -# with: { models: "...", allowed_users: "..." } # all optional +# with: { allowed_users: "..." } # config inputs are optional (see below) # -# Inputs are all optional and default to "" — an empty env value makes the -# image/entrypoint use its own built-in default, so the caller only sets what it -# wants to override. Secrets are DECLARED below (workflow_call.secrets) so a +# Inputs ship the DEFAULT swarm (see the inputs block): 3 cloud models + the +# Claude Code engine, 5-lens suite, all three claudes concurrent. A consumer +# inherits it by omitting `with:` entirely, or overrides any field (e.g. +# `models:` for a cloud-only / different-provider setup; "" falls back to the +# image's built-in default). Secrets are DECLARED below (workflow_call.secrets) so a # caller forwards only the credentials the reviewer actually uses — least # privilege — rather than `secrets: inherit`, which leaks every caller secret # (registry/deploy/db creds) into this workflow. `secrets: inherit` still works @@ -30,21 +32,28 @@ name: Gadfly review (reusable) on: workflow_call: + # Inputs ship the DEFAULT Gadfly swarm so a consumer can just call this + # workflow (no `with:` block) and inherit it. The default is opinionated — + # 3 strong cloud models + the Claude Code engine (sonnet/opus/opus:max), the + # 5-lens suite, all three claudes concurrent. It needs OLLAMA_CLOUD_API_KEY + # and CLAUDE_CODE_OAUTH_TOKEN; a consumer with only one (or a different + # provider) overrides `models:` (and forwards just the secrets it uses). + # Set any input to "" to fall back to the image/entrypoint built-in default. inputs: - models: { type: string, default: "" } # GADFLY_MODELS (csv) - specialists: { type: string, default: "" } # GADFLY_SPECIALISTS + models: { type: string, default: "minimax-m3:cloud,glm-5.2:cloud,deepseek-v4-pro:cloud,claude-code/sonnet,claude-code/opus,claude-code/opus:max" } # GADFLY_MODELS (csv) + specialists: { type: string, default: "security,correctness,maintainability,performance,error-handling" } # GADFLY_SPECIALISTS (5-lens default suite) provider: { type: string, default: "" } # GADFLY_PROVIDER base_url: { type: string, default: "" } # GADFLY_BASE_URL - provider_concurrency: { type: string, default: "" } # GADFLY_PROVIDER_CONCURRENCY - provider_lens_concurrency: { type: string, default: "" } # GADFLY_PROVIDER_LENS_CONCURRENCY - timeout_secs: { type: string, default: "" } # GADFLY_TIMEOUT_SECS (per lens) - max_steps: { type: string, default: "" } # GADFLY_MAX_STEPS + provider_concurrency: { type: string, default: "ollama-cloud=3,claude-code=3" } # GADFLY_PROVIDER_CONCURRENCY (all 3 claudes at once) + provider_lens_concurrency: { type: string, default: "ollama-cloud=3" } # GADFLY_PROVIDER_LENS_CONCURRENCY + timeout_secs: { type: string, default: "600" } # GADFLY_TIMEOUT_SECS (per lens) + max_steps: { type: string, default: "14" } # GADFLY_MAX_STEPS worker_model: { type: string, default: "" } # GADFLY_WORKER_MODEL - allowed_users: { type: string, default: "" } # GADFLY_ALLOWED_USERS + allowed_users: { type: string, default: "" } # GADFLY_ALLOWED_USERS (consumer-specific; set in your stub) trigger_phrase: { type: string, default: "" } # GADFLY_TRIGGER_PHRASE - # Job wall-clock cap. 45 > 30 as a default: a multi-model swarm or a slow - # lens (e.g. claude-code with extended thinking) can exceed 30 minutes. - timeout_minutes: { type: number, default: 45 } + # Job wall-clock cap. 90 as a default: the 5-lens suite across a slow lane + # (claude-code with extended thinking) over two passes can run long. + timeout_minutes: { type: number, default: 90 } # Declared so callers can forward ONLY the secrets the reviewer needs # (least privilege) instead of `secrets: inherit`, which would hand this # workflow every secret in the caller's repo (registry/deploy/db creds the diff --git a/CLAUDE.md b/CLAUDE.md index 7d284c6..cb463b7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -46,9 +46,11 @@ entrypoint.sh container brains: trigger gating, PR clone, model loop (t used to live in workflow YAML) Dockerfile multi-stage; private-module creds via BuildKit secrets never reach the final image .gitea/workflows/build-image.yml push main → :latest; tag v* → :+:latest; PR → build-only -.gitea/workflows/review-reusable.yml reusable (workflow_call) review job; consumers subscribe with - an ~8-line caller forwarding only the secrets the reviewer needs (Phase 4). gadfly's own - adversarial-review.yml is a thin caller of it (dogfoods the path). +.gitea/workflows/review-reusable.yml reusable (workflow_call) review job; ships the DEFAULT swarm as + input defaults (3 cloud + Claude Code sonnet/opus/opus:max, 5-lens suite, + claude-code=3) so consumers inherit it by omitting `with:`. Consumers subscribe + with an ~8-line caller forwarding only the secrets the reviewer needs (Phase 4); + gadfly's own adversarial-review.yml is a thin caller of it (dogfoods the path). examples/ copy-paste consumer stub workflows for different providers ``` diff --git a/README.md b/README.md index 2f0bd92..577e574 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,8 @@ it. Drop one file in your repo and set a couple of secrets/vars: 1. Copy a stub from [`examples/`](examples/) to `.gitea/workflows/adversarial-review.yml` in your repo. Two flavors: the slim [`reusable.yml`](examples/reusable.yml) — a tiny caller of Gadfly's **reusable workflow** (`uses: steve/gadfly/.gitea/workflows/review-reusable.yml@…`, - forwarding only the secrets the reviewer needs), best when you take the defaults — or the full self-contained + forwarding only the secrets the reviewer needs), which ships a **default swarm** (3 cloud models + + the Claude Code engine, 5-lens suite) you inherit by omitting `with:` or override per-input — or the full self-contained [`adversarial-review.yml`](examples/adversarial-review.yml) (Ollama Cloud default, with inline notes for every provider / local Ollama / OpenAI-compatible / endpoint aliases). See the [examples index](examples/README.md). diff --git a/examples/reusable.yml b/examples/reusable.yml index 312376f..a582053 100644 --- a/examples/reusable.yml +++ b/examples/reusable.yml @@ -5,7 +5,12 @@ # workflow, which holds the image pin + all the env plumbing. You only declare # the triggers, the comment-trigger actor gate, and any overrides you want. # -# Needs: secret OLLAMA_CLOUD_API_KEY (the default Ollama Cloud provider). +# The reusable ships a DEFAULT swarm: 3 cloud models + the Claude Code engine +# (sonnet/opus/opus:max), 5-lens suite. That default needs BOTH +# OLLAMA_CLOUD_API_KEY and CLAUDE_CODE_OAUTH_TOKEN. This example overrides +# `models:` to a cloud-only set so it works with just OLLAMA_CLOUD_API_KEY — +# delete that override (and forward the Claude token) to inherit the full default. +# # Forward ONLY the secrets the reviewer uses (least privilege) — see the # `secrets:` block below. GITEA_TOKEN is automatic. `secrets: inherit` also works # but hands the reusable EVERY secret in your repo (registry/deploy/db creds the @@ -13,9 +18,8 @@ # Gadfly commit (not @main) so a push there can't change what runs with your # secrets. # -# Prefer this when you're happy with the defaults. For custom named endpoints -# (GADFLY_ENDPOINT_) or a provider the reusable doesn't map, use the full -# stub in adversarial-review.yml instead. +# For custom named endpoints (GADFLY_ENDPOINT_) or a provider the reusable +# doesn't map, use the full stub in adversarial-review.yml instead. name: Adversarial Review (Gadfly) @@ -56,7 +60,10 @@ jobs: # GADFLY_FINDINGS_URL: ${{ secrets.GADFLY_FINDINGS_URL }} # GADFLY_FINDINGS_TOKEN: ${{ secrets.GADFLY_FINDINGS_TOKEN }} with: - # All optional — omit to take Gadfly's defaults. Examples: - # models: "qwen3-coder:480b-cloud,gpt-oss:120b-cloud" - # specialists: "security,correctness,error-handling" + # Cloud-only override so this works with just OLLAMA_CLOUD_API_KEY. Delete + # this line (and forward CLAUDE_CODE_OAUTH_TOKEN above) to inherit the full + # default swarm (3 cloud + Claude Code sonnet/opus/opus:max, 5 lenses). + models: "minimax-m3:cloud,glm-5.2:cloud,deepseek-v4-pro:cloud" + # Other inputs inherit the default (5-lens suite, concurrency, 90-min cap); + # override any of them here (specialists, provider, base_url, timeout_secs…). allowed_users: "your-username" -- 2.52.0 From 6407c0defe1dae5baf9776cd2711969b65dc086c Mon Sep 17 00:00:00 2001 From: Steve Dudenhoeffer Date: Sat, 27 Jun 2026 22:08:47 -0400 Subject: [PATCH 2/4] feat(reusable): run claude lenses concurrently too (claude-code=5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit provider_lens_concurrency default adds claude-code=5 so each claude model runs all 5 lenses at once (was serial — defaultLensConcurrency=1). The engine already supports it: each lens is an independent read-only 'claude -p' (plan mode) in its own process group; no shared mutable state beyond ~/.claude + the API. Peak claude concurrency is now 3 models x 5 lenses = up to 15 concurrent claude -p per pass — documented, dial back either knob if rate-limited. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitea/workflows/review-reusable.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/review-reusable.yml b/.gitea/workflows/review-reusable.yml index 68a96e9..27e932d 100644 --- a/.gitea/workflows/review-reusable.yml +++ b/.gitea/workflows/review-reusable.yml @@ -35,17 +35,22 @@ on: # Inputs ship the DEFAULT Gadfly swarm so a consumer can just call this # workflow (no `with:` block) and inherit it. The default is opinionated — # 3 strong cloud models + the Claude Code engine (sonnet/opus/opus:max), the - # 5-lens suite, all three claudes concurrent. It needs OLLAMA_CLOUD_API_KEY - # and CLAUDE_CODE_OAUTH_TOKEN; a consumer with only one (or a different - # provider) overrides `models:` (and forwards just the secrets it uses). - # Set any input to "" to fall back to the image/entrypoint built-in default. + # 5-lens suite, all three claudes concurrent AND each running its 5 lenses at + # once. It needs OLLAMA_CLOUD_API_KEY and CLAUDE_CODE_OAUTH_TOKEN; a consumer + # with only one (or a different provider) overrides `models:` (and forwards + # just the secrets it uses). Set any input to "" to fall back to the + # image/entrypoint built-in default. + # + # Peak claude concurrency = provider_concurrency × provider_lens_concurrency + # (3 models × 5 lenses = up to 15 concurrent `claude -p` per pass). If you hit + # subscription rate limits or runner load, dial claude-code down in either knob. inputs: models: { type: string, default: "minimax-m3:cloud,glm-5.2:cloud,deepseek-v4-pro:cloud,claude-code/sonnet,claude-code/opus,claude-code/opus:max" } # GADFLY_MODELS (csv) specialists: { type: string, default: "security,correctness,maintainability,performance,error-handling" } # GADFLY_SPECIALISTS (5-lens default suite) provider: { type: string, default: "" } # GADFLY_PROVIDER base_url: { type: string, default: "" } # GADFLY_BASE_URL provider_concurrency: { type: string, default: "ollama-cloud=3,claude-code=3" } # GADFLY_PROVIDER_CONCURRENCY (all 3 claudes at once) - provider_lens_concurrency: { type: string, default: "ollama-cloud=3" } # GADFLY_PROVIDER_LENS_CONCURRENCY + provider_lens_concurrency: { type: string, default: "ollama-cloud=3,claude-code=5" } # GADFLY_PROVIDER_LENS_CONCURRENCY (each claude runs all 5 lenses at once) timeout_secs: { type: string, default: "600" } # GADFLY_TIMEOUT_SECS (per lens) max_steps: { type: string, default: "14" } # GADFLY_MAX_STEPS worker_model: { type: string, default: "" } # GADFLY_WORKER_MODEL -- 2.52.0 From f882b006d19757075cbec5651a63c2efe17e9ab3 Mon Sep 17 00:00:00 2001 From: Steve Dudenhoeffer Date: Sat, 27 Jun 2026 22:12:17 -0400 Subject: [PATCH 3/4] tune(reusable): claude-code=1 model x 5 lenses (cap peak at 5 concurrent) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run claude models one at a time (provider_concurrency claude-code=1) but each with all 5 lenses concurrent (provider_lens_concurrency claude-code=5) — peak 5 concurrent claude -p per pass instead of 15, friendlier to one subscription. Updated all the 'three claudes at once' wording across the workflow + docs. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitea/workflows/adversarial-review.yml | 7 ++++--- .gitea/workflows/review-reusable.yml | 10 +++++----- CLAUDE.md | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/adversarial-review.yml b/.gitea/workflows/adversarial-review.yml index c384d3e..8ef119c 100644 --- a/.gitea/workflows/adversarial-review.yml +++ b/.gitea/workflows/adversarial-review.yml @@ -4,7 +4,8 @@ # holds only the triggers, the actor gate, secret forwarding, and allow-list. # # Advisory only — never blocks a merge. It inherits the default swarm: 3 cloud -# models + Claude Code (sonnet, opus, opus:max), 5-lens suite, 3 claudes at once. +# models + Claude Code (sonnet, opus, opus:max), 5-lens suite (claude models run +# one at a time, each with all 5 lenses at once). name: Adversarial Review (Gadfly) @@ -49,6 +50,6 @@ jobs: GADFLY_FINDINGS_TOKEN: ${{ secrets.GADFLY_FINDINGS_TOKEN }} with: # Inherit the default swarm (3 cloud + Claude Code sonnet/opus/opus:max, - # 5-lens suite, all three claudes concurrent) from review-reusable.yml. - # Only the consumer-specific allow-list is set here. + # 5-lens suite) from review-reusable.yml. Only the consumer-specific + # allow-list is set here. allowed_users: "steve,fizi,dazed" diff --git a/.gitea/workflows/review-reusable.yml b/.gitea/workflows/review-reusable.yml index 27e932d..3958d9c 100644 --- a/.gitea/workflows/review-reusable.yml +++ b/.gitea/workflows/review-reusable.yml @@ -13,7 +13,7 @@ # with: { allowed_users: "..." } # config inputs are optional (see below) # # Inputs ship the DEFAULT swarm (see the inputs block): 3 cloud models + the -# Claude Code engine, 5-lens suite, all three claudes concurrent. A consumer +# Claude Code engine, 5-lens suite (claude models serial, 5 lenses each). A consumer # inherits it by omitting `with:` entirely, or overrides any field (e.g. # `models:` for a cloud-only / different-provider setup; "" falls back to the # image's built-in default). Secrets are DECLARED below (workflow_call.secrets) so a @@ -35,21 +35,21 @@ on: # Inputs ship the DEFAULT Gadfly swarm so a consumer can just call this # workflow (no `with:` block) and inherit it. The default is opinionated — # 3 strong cloud models + the Claude Code engine (sonnet/opus/opus:max), the - # 5-lens suite, all three claudes concurrent AND each running its 5 lenses at + # 5-lens suite. Claude models run ONE at a time, but each runs all 5 lenses at # once. It needs OLLAMA_CLOUD_API_KEY and CLAUDE_CODE_OAUTH_TOKEN; a consumer # with only one (or a different provider) overrides `models:` (and forwards # just the secrets it uses). Set any input to "" to fall back to the # image/entrypoint built-in default. # # Peak claude concurrency = provider_concurrency × provider_lens_concurrency - # (3 models × 5 lenses = up to 15 concurrent `claude -p` per pass). If you hit - # subscription rate limits or runner load, dial claude-code down in either knob. + # (1 model × 5 lenses = up to 5 concurrent `claude -p` per pass) — friendly to + # a single subscription. Raise claude-code in either knob for more parallelism. inputs: models: { type: string, default: "minimax-m3:cloud,glm-5.2:cloud,deepseek-v4-pro:cloud,claude-code/sonnet,claude-code/opus,claude-code/opus:max" } # GADFLY_MODELS (csv) specialists: { type: string, default: "security,correctness,maintainability,performance,error-handling" } # GADFLY_SPECIALISTS (5-lens default suite) provider: { type: string, default: "" } # GADFLY_PROVIDER base_url: { type: string, default: "" } # GADFLY_BASE_URL - provider_concurrency: { type: string, default: "ollama-cloud=3,claude-code=3" } # GADFLY_PROVIDER_CONCURRENCY (all 3 claudes at once) + provider_concurrency: { type: string, default: "ollama-cloud=3,claude-code=1" } # GADFLY_PROVIDER_CONCURRENCY (claude models one at a time) provider_lens_concurrency: { type: string, default: "ollama-cloud=3,claude-code=5" } # GADFLY_PROVIDER_LENS_CONCURRENCY (each claude runs all 5 lenses at once) timeout_secs: { type: string, default: "600" } # GADFLY_TIMEOUT_SECS (per lens) max_steps: { type: string, default: "14" } # GADFLY_MAX_STEPS diff --git a/CLAUDE.md b/CLAUDE.md index cb463b7..e814e3c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -47,8 +47,8 @@ entrypoint.sh container brains: trigger gating, PR clone, model loop (t Dockerfile multi-stage; private-module creds via BuildKit secrets never reach the final image .gitea/workflows/build-image.yml push main → :latest; tag v* → :+:latest; PR → build-only .gitea/workflows/review-reusable.yml reusable (workflow_call) review job; ships the DEFAULT swarm as - input defaults (3 cloud + Claude Code sonnet/opus/opus:max, 5-lens suite, - claude-code=3) so consumers inherit it by omitting `with:`. Consumers subscribe + input defaults (3 cloud + Claude Code sonnet/opus/opus:max, 5-lens suite; + claude models serial, 5 lenses each) so consumers inherit it by omitting `with:`. Consumers subscribe with an ~8-line caller forwarding only the secrets the reviewer needs (Phase 4); gadfly's own adversarial-review.yml is a thin caller of it (dogfoods the path). examples/ copy-paste consumer stub workflows for different providers -- 2.52.0 From 4654036dea14035fd3a58d1c5927ccb65981f351 Mon Sep 17 00:00:00 2001 From: Steve Dudenhoeffer Date: Sat, 27 Jun 2026 22:18:43 -0400 Subject: [PATCH 4/4] docs: reconcile examples/README + CLAUDE.md with the heavier reusable default From PR #10's own review (maintainability/perf lenses): examples/README.md hadn't been updated for the default swarm, and CLAUDE.md's 'keep the default model count low' cost guidance read as contradicting the new heavy default. Clarify that the IMAGE default stays minimal while the REUSABLE ships an opinionated heavier default consumers inherit/override. Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 5 ++++- examples/README.md | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index e814e3c..7c16db1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -100,7 +100,10 @@ comment with a section each. Default suite = security/correctness/maintainabilit error-handling; opt-in built-ins = tests/docs/conventions/improvements. Select via `GADFLY_SPECIALISTS` (csv or `all`); define/override via `GADFLY_SPECIALIST_` env or a repo `.gadfly.yml` (`specialists:` + `define:`). See `cmd/gadfly/specialists.go`. Cost ≈ -specialists × models × 2 passes — keep the default model count low (entrypoint defaults to one). +specialists × models × 2 passes — the **image/entrypoint** default stays minimal (one model) for +that reason; the **reusable workflow** (`review-reusable.yml`) deliberately ships a heavier +opinionated default swarm (3 cloud + Claude Code, 5 lenses) for steve's own fleet, which consumers +inherit or override per-input. **Dynamic `auto`** (`GADFLY_SPECIALISTS=auto`): a selector (`GADFLY_SELECTOR_MODEL` or the review model) picks lenses per-diff and may invent ad-hoc ones (`cmd/gadfly/auto.go`). **Worker-tier** (`GADFLY_WORKER_MODEL`): a `delegate_investigation` tool offloads grep/read legwork to a cheap diff --git a/examples/README.md b/examples/README.md index 4af343e..22b170c 100644 --- a/examples/README.md +++ b/examples/README.md @@ -6,7 +6,7 @@ set the secrets/vars it references. Gadfly is advisory only — it never blocks | File | Backend | Needs | |------|---------|-------| -| [`reusable.yml`](reusable.yml) | **slimmest stub** — calls Gadfly's reusable workflow, forwarding only the secrets the reviewer needs (least privilege, not `secrets: inherit`); take the defaults or override a few inputs | secret `OLLAMA_CLOUD_API_KEY` | +| [`reusable.yml`](reusable.yml) | **slimmest stub** — calls Gadfly's reusable workflow and inherits its **default swarm** (3 cloud + Claude Code, 5-lens suite), forwarding only the secrets it needs (least privilege, not `secrets: inherit`); the stub keeps a cloud-only `models:` override so it runs with just the Ollama key (drop it + add the Claude token to get the full default) | secret `OLLAMA_CLOUD_API_KEY` | | [`adversarial-review.yml`](adversarial-review.yml) | **Ollama Cloud** (default) + inline notes for every provider; full self-contained stub | secret `OLLAMA_CLOUD_API_KEY` | | [`local-ollama.yml`](local-ollama.yml) | a **local/LAN Ollama** daemon | nothing (or `GADFLY_BASE_URL` for a remote host) | | [`openai-compatible.yml`](openai-compatible.yml) | any **OpenAI-compatible** endpoint (local Ollama `/v1`, gateway, vLLM, OpenRouter…) | `GADFLY_BASE_URL` (+ a key for most gateways) | -- 2.52.0