Gadfly: agentic adversarial PR reviewer (initial extraction)

Standalone, Docker-packaged extraction of the agentic PR reviewer that runs in
Gitea Actions: reads the checked-out repo with read-only tools (read_file/grep/
find_files/get_diff), verifies findings before reporting, two-pass review +
adversarial recheck, posts one labeled comment per model. Advisory only.

- cmd/gadfly: reviewer binary (majordomo + Ollama Cloud), zero deps beyond stdlib + majordomo
- entrypoint.sh: container brains — trigger gating, PR clone, model loop (logic out of YAML)
- Dockerfile: multi-stage; build-time module token never reaches the final image
- .gitea/workflows/build-image.yml: tag v* → build & push image
- examples/: ~15-line consumer stub
- system prompt genericized + hardened to re-derive constants/formulas (semantic bugs)

Vibe-coded with Claude Code; see README disclosure. Advisory, never blocks merge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Steve Dudenhoeffer
2026-06-25 18:42:20 -04:00
commit c0d0152a34
18 changed files with 1879 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
name: Build & push image
# Builds the Gadfly reviewer container and pushes it to the Gitea container
# registry. Tag a release (v1, v1.2.0, …) to publish that version + :latest.
#
# Required repo secrets:
# REGISTRY_USER / REGISTRY_PASSWORD Gitea creds with registry push + read
# access to the private majordomo module.
on:
push:
tags: ["v*"]
workflow_dispatch: {}
env:
IMAGE: gitea.stevedudenhoeffer.com/steve/gadfly
jobs:
image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Log in to the registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" \
| docker login gitea.stevedudenhoeffer.com -u "${{ secrets.REGISTRY_USER }}" --password-stdin
- name: Resolve tags
id: tags
run: |
if [ "${{ github.ref_type }}" = "tag" ]; then
echo "version=${{ github.ref_name }}" >> "$GITHUB_OUTPUT"
else
echo "version=dev-$(echo ${{ github.sha }} | cut -c1-8)" >> "$GITHUB_OUTPUT"
fi
- name: Build & push
run: |
docker build \
--build-arg GIT_USER="${{ secrets.REGISTRY_USER }}" \
--build-arg GIT_TOKEN="${{ secrets.REGISTRY_PASSWORD }}" \
-t "${IMAGE}:${{ steps.tags.outputs.version }}" \
-t "${IMAGE}:latest" \
.
docker push "${IMAGE}:${{ steps.tags.outputs.version }}"
docker push "${IMAGE}:latest"