Files
gadfly/examples/adversarial-review.yml
T
steve c3d09d3bd4
Build & push image / build-and-push (push) Successful in 6s
feat: live status-board comment + full-fleet dogfood (#1)
Phase 3: one consolidated, live-updating PR comment aggregating every
model's per-lens progress (queued -> running -> finished + verdict), so
the swarm's progress is visible at a glance and a watcher can tell when
it's done. Opt-in statusWriter in the binary (atomic writes) + a
background status-board.sh renderer wired through entrypoint.sh; default
on, GADFLY_STATUS_BOARD=0 to disable.

Also restores gadfly's dogfood swarm to the full cloud fleet (9 cloud +
M5; M1 dropped as too slow) matching mort, and folds in the 3 real bugs
the swarm found on its own PR (skip-binary stuck-waiting, panic-stuck
lens, busy-loop on bad poll interval). All 36 findings graded via the
gadfly MCP (18 real / 18 false-positive).

gofmt clean, go vet quiet, go build + go test -race green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Steve Dudenhoeffer <steve@stevedudenhoeffer.com>
Co-committed-by: Steve Dudenhoeffer <steve@stevedudenhoeffer.com>
2026-06-27 19:00:12 +00:00

112 lines
5.8 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Drop this in ANY Gitea repo at .gitea/workflows/adversarial-review.yml to turn
# Gadfly on. The image holds all the logic; this stub just forwards the event
# context. Advisory only — it never blocks a merge.
#
# Per-repo setup (no code changes needed):
# secret OLLAMA_CLOUD_API_KEY your Ollama Cloud key
# var OLLAMA_REVIEW_MODELS (optional) comma-separated model ids
# var GADFLY_ALLOWED_USERS (optional) who may "@gadfly review"; empty =
# any repo collaborator
# GITEA_TOKEN is provided automatically; comments post as the gitea-actions user.
name: Adversarial Review (Gadfly)
on:
pull_request:
types: [opened, reopened, ready_for_review]
issue_comment:
types: [created]
workflow_dispatch:
inputs:
pr_number:
description: "PR number to review"
required: true
permissions:
contents: read
issues: write
pull-requests: write
concurrency:
group: gadfly-${{ github.event.issue.number || github.event.pull_request.number || github.event.inputs.pr_number }}
cancel-in-progress: true
jobs:
review:
# Security: only trusted users may trigger a secret-bearing run via a PR
# comment (pull_request + workflow_dispatch are already trusted). Replace the
# username(s) below with your maintainers — keep them in sync with
# GADFLY_ALLOWED_USERS (the in-container belt-and-suspenders check).
if: >-
github.event_name != 'issue_comment'
|| github.actor == 'your-username'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: docker://gitea.stevedudenhoeffer.com/steve/gadfly:v1
env:
GITEA_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
OLLAMA_CLOUD_API_KEY: ${{ secrets.OLLAMA_CLOUD_API_KEY }}
OLLAMA_REVIEW_MODELS: ${{ vars.OLLAMA_REVIEW_MODELS }}
GADFLY_ALLOWED_USERS: ${{ vars.GADFLY_ALLOWED_USERS }}
# Specialist suite (optional). Empty = default suite
# (security,correctness,maintainability,performance,error-handling).
# csv to choose; "all" for everything; or define custom ones via a repo
# .gadfly.yml / GADFLY_SPECIALIST_<NAME>. See README "Specialists".
GADFLY_SPECIALISTS: ${{ vars.GADFLY_SPECIALISTS }}
# Lens fan-out (optional; default 1 = lenses run sequentially within a
# model). Raise it to run a model's lenses concurrently so each model
# posts its comment sooner. Total in-flight requests = (models at once)
# × (lenses at once), so to fan out without oversubscribing a backend,
# keep its model cap low and raise its lens cap. Per-provider configurable
# via GADFLY_PROVIDER_LENS_CONCURRENCY (same lanes as the model map):
# GADFLY_PROVIDER_CONCURRENCY: "ollama-cloud=1,m1=1"
# GADFLY_PROVIDER_LENS_CONCURRENCY: "ollama-cloud=3,m1=1"
# GADFLY_LENS_CONCURRENCY: ${{ vars.GADFLY_LENS_CONCURRENCY }}
# GADFLY_PROVIDER_LENS_CONCURRENCY: ${{ vars.GADFLY_PROVIDER_LENS_CONCURRENCY }}
# Live status board (optional; ON by default): one consolidated comment
# showing every model's per-lens progress as it runs. Disable with
# GADFLY_STATUS_BOARD=0; tune the refresh with GADFLY_STATUS_POLL_SECS.
# GADFLY_STATUS_BOARD: ${{ vars.GADFLY_STATUS_BOARD }}
# --- Models & providers (optional; default = Ollama Cloud) ----------
# Gadfly is majordomo-powered, so it can target other backends. Set a
# provider for bare model ids; point at a different endpoint with a
# base URL; supply a key (or the provider's standard env var). Examples:
#
# Local Ollama daemon (no key):
# GADFLY_PROVIDER: ollama
# GADFLY_MODELS: qwen2.5-coder:7b
# # GADFLY_BASE_URL: http://my-ollama-host:11434 # if not localhost
#
# OpenAI-compatible endpoint (incl. local Ollama's /v1):
# GADFLY_PROVIDER: openai
# GADFLY_BASE_URL: http://localhost:11434/v1
# GADFLY_MODELS: qwen2.5-coder:7b
#
# OpenAI / Anthropic / Google (supported via majordomo, UNTESTED — see README):
# GADFLY_PROVIDER: openai # then set OPENAI_API_KEY below
# OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
#
# Named endpoint aliases (reference as name/model in GADFLY_MODELS).
# vars/secrets aren't auto-exposed, so map each one explicitly:
# GADFLY_ENDPOINT_BIGBOX: ${{ vars.GADFLY_ENDPOINT_BIGBOX }} # "ollama|http://192.168.1.50:11434"
# GADFLY_MODELS: bigbox/qwen2.5-coder:7b
GADFLY_PROVIDER: ${{ vars.GADFLY_PROVIDER }}
GADFLY_BASE_URL: ${{ vars.GADFLY_BASE_URL }}
GADFLY_MODELS: ${{ vars.GADFLY_MODELS }}
# --- Findings telemetry (optional; OFF by default) ------------------
# Set GADFLY_FINDINGS_URL to a gadfly-reports store base URL to POST each run +
# its findings for model-quality tracking. Advisory only: failures are
# logged to stderr and never affect the review. Add a bearer token if
# the store requires auth. (GADFLY_REPO / GADFLY_PR are derived for you.)
# GADFLY_FINDINGS_URL: ${{ vars.GADFLY_FINDINGS_URL }}
# GADFLY_FINDINGS_TOKEN: ${{ secrets.GADFLY_FINDINGS_TOKEN }}
EVENT_NAME: ${{ github.event_name }}
PR: ${{ github.event.pull_request.number || github.event.issue.number || github.event.inputs.pr_number }}
PR_BRANCH: ${{ github.head_ref }}
IS_DRAFT: ${{ github.event.pull_request.draft }}
COMMENT_BODY: ${{ github.event.comment.body }}
COMMENT_ID: ${{ github.event.comment.id }}
ACTOR: ${{ github.actor }}