Autonomous GitHub issue triage agent for AetherSDR — a security-first AI coding agent that triages issues, implements fixes, reviews community PRs, detects duplicates, explains CI failures, and compiles release notes.
Runs on a dedicated Mac Mini, triggered by GitHub webhooks in real time (with an hourly fallback timer). Each cycle:
- Detects issue state from a SQLite action log
- Triages new issues (Claude Code with the AetherSDR CLAUDE.md in context)
- Posts analysis, requests missing info, or transitions to implementation
- Implements fixes in a clean git worktree, runs validation, creates a PR
- Reviews incoming community PRs for convention compliance
- Auto-closes zero-effort submissions
- Logs every run to Galileo and scores its own triage/implement/review quality against curated datasets (the "is the agent any good?" layer)
Every agent run is wrapped in multiple enforcement layers:
- pf firewall —
aetherclaudeUID can only reach GitHub, Anthropic, Cloudflare tunnel, and telemetry endpoints. Everything else dropped. - tinyproxy — HTTP proxy with domain allowlist
- Cisco DefenseClaw CodeGuard — static analysis of every changed file before a PR is pushed (blocks HIGH/CRITICAL findings)
- Cisco MCP Scanner — YARA + prompt-defense scan of MCP tool declarations
- Cisco Skill Scanner — blocks injected
.claude/skills in the workspace - Validation gate — blocks modifications to
.github/,Dockerfile, and other protected paths - DB-driven state machine — no "proceeding with best judgment" bypass;
issues in
waitingstate stay there until user replies or 7 days elapse - Tetragon (eBPF observability) — records every tool invocation
- Token scrubbing — session JSONL files are scanned on every run for
ghs_,ghp_,github_pat_,sk-ant-, and Galileo key leaks
Enforcement proves a run stayed contained; evaluation measures whether it was good. Every Claude invocation is logged to Galileo as a trace, and the three flows are scored against datasets built from our own action history:
- Trace path — the sandboxed agent never touches Galileo.
run_claudePOSTs a compact record to the dashboard over localhost (/api/eval-ingest); only the trusted dashboard holdsGALILEO_API_KEYand forwards the trace. The agent is additionally deniedgalileo.aiat the tinyproxy layer (defense in depth). - Scorecard —
bin/build-eval-datasets.pycurates triage / implement / review cases (incl. a known stale-code regression);bin/run-eval.shscores the flows and publishes per-flow results to Galileo and the dashboard's Eval panel, each run deep-linking to the Agent Walk swimlane and its Galileo trace. - Operator skills — the pinned, scanner-vetted
eval-*skill pack (.claude/skills/PROVENANCE.md) drives interactive fetch / measure / diagnose.
bin/ Scripts executed by the agent
skills/ Claude Code prompt templates (triage, implement, review, …)
config/
launchd/ macOS service definitions
pf/ firewall anchor
cloudflared/ tunnel config (no credentials)
scripts/
deploy.sh pull + restart on the Mac Mini
Copy .env.example to ~/.env and fill in the two values to bootstrap.
On the Mac Mini:
git clone https://github.com/ten9876/aetherclaude.git ~/src/aetherclaude
cd ~/src/aetherclaude
./scripts/deploy.shThe deploy script symlinks bin/ scripts into /Users/aetherclaude/bin/,
copies configs into their system locations, and restarts affected launchd
services.
Subsequent edits: commit to main, then on the Mac Mini run
~/src/aetherclaude/scripts/deploy.sh.
Standing up an independent instance against your own repo (not the AetherSDR Mac Mini)? See docs/SELF-HOSTING.md.
GNU Affero General Public License v3.0 — see LICENSE.
AGPL-3.0's network copyleft clause matters here: AetherClaude is a hosted agent that interacts with users over GitHub. Anyone running a modified version of this code as a hosted service must make their modifications available to the users they're serving.
Part of the AetherSDR project. Maintained by Jeremy KK7GWY with AI assistance.