Add a third review harness alongside the in-process majordomo loop and the
claude-code CLI shell-out: the OpenCode CLI (opencode.ai) driving an ollama-cloud
model, selected by an "opencode/<model>" spec. The goal is to benchmark gadfly's
boutique executus harness against a freely-available agentic harness on the SAME
model (e.g. "ollama-cloud/glm-5.2" vs "opencode/glm-5.2").
OpenCode has no --append-system-prompt flag, so the lens system prompt and the
read-only discipline are delivered through a generated config injected via
OPENCODE_CONFIG_CONTENT: a "gadfly" agent whose prompt is the system prompt with
edit/bash denied at both the global and agent level, plus a "gadfly" ollama-cloud
provider. That env var is the highest-precedence config source in the container,
so a reviewed repo's own opencode.json can't re-enable edits on the reviewer.
Spec forms: "opencode/<model>" (wrapped in the generated provider), the
"open-code/" alias, "opencode/<provider>/<model>" pass-through to OpenCode's own
registry, and bare "opencode". Model ids are taken verbatim so colon-bearing
ollama ids (qwen3-coder:480b-cloud) survive. Auth reuses OLLAMA_CLOUD_API_KEY
(mapped to OLLAMA_API_KEY, referenced as {env:OLLAMA_API_KEY} in config, never a
literal secret). Knobs mirror GADFLY_CLAUDE_*: GADFLY_OPENCODE_BIN/MODEL/BASE_URL/
EXTRA_ARGS. openCodeEnv() forwards OLLAMA_API_KEY (the inverse of claudeEnv) but
still withholds the Gitea/findings/Anthropic secrets.
main.go engine selection is now a switch (claude-code / opencode / majordomo), and
the auto-select path uses a type-check instead of a boolean so a shell-out engine
can never hit the *majordomoEngine assertion. auto-select and delegate_investigation
stay majordomo-only and are skipped for opencode (the CLI does its own legwork).
Dockerfile bundles opencode-ai (npm auto-selects its musl build on alpine) with a
best-effort version check + provider pre-warm that never fails the shared image
build. README/examples/CLAUDE.md/scripts updated per the maintenance rules.
Tests: new opencode_test.go mirrors engine_test.go (spec/model/args/config/env-
filter + stub-CLI runtime tests). Verified end-to-end with a fake opencode CLI:
correct argv, injected config, and consolidated markdown output.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
77 lines
3.5 KiB
YAML
77 lines
3.5 KiB
YAML
# Gadfly reviewing via the OpenCode CLI engine.
|
|
# Copy to .gitea/workflows/adversarial-review.yml in your repo.
|
|
#
|
|
# Instead of gadfly's own majordomo loop, each lens shells out to the bundled
|
|
# `opencode` CLI (opencode.ai) inside the checked-out repo — it uses its own read
|
|
# tools to verify findings — while driving an ollama-cloud model. Gadfly then runs
|
|
# its usual verdict + recheck + consolidate pipeline.
|
|
#
|
|
# Why: benchmark gadfly's boutique harness against a freely-available one ON THE
|
|
# SAME MODEL. List both entries to get one comment section each and compare:
|
|
# GADFLY_MODELS: "ollama-cloud/glm-5.2,opencode/glm-5.2"
|
|
#
|
|
# Auth: reuses the OLLAMA_CLOUD_API_KEY secret (same as the ollama-cloud path) —
|
|
# no OpenCode-specific credential is needed for the ollama-cloud provider.
|
|
#
|
|
# Heads-up: this engine is newly wired and lightly tested — read the README's
|
|
# "OpenCode engine" note before relying on it.
|
|
|
|
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. 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:latest
|
|
env:
|
|
GITEA_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
# --- OpenCode engine ---
|
|
# Reuses the ollama-cloud key; mapped to OLLAMA_API_KEY in-container and
|
|
# referenced by the generated provider as {env:OLLAMA_API_KEY}.
|
|
OLLAMA_CLOUD_API_KEY: ${{ secrets.OLLAMA_CLOUD_API_KEY }}
|
|
# "opencode/<model>" serves that model via ollama-cloud through OpenCode.
|
|
# Model ids are verbatim (colons preserved). List an "ollama-cloud/<model>"
|
|
# entry too to benchmark the two harnesses on the same model.
|
|
GADFLY_MODELS: "opencode/glm-5.2"
|
|
# Optional CLI tuning:
|
|
# GADFLY_OPENCODE_BASE_URL: "https://ollama.com/v1" # or a local Ollama /v1
|
|
# GADFLY_OPENCODE_MODEL: "glm-5.2" # overrides the spec suffix
|
|
# GADFLY_OPENCODE_EXTRA_ARGS: "--variant reasoning" # whitespace-split
|
|
# Escape hatch: "opencode/<provider>/<model>" passes straight to OpenCode's
|
|
# own provider registry/auth (e.g. opencode/anthropic/claude-sonnet-4-6).
|
|
GADFLY_ALLOWED_USERS: "your-username"
|
|
# --- event context (leave as-is) ---
|
|
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 }}
|