Self-hosted bot that posts PR fixes after testing in air-gapped Docker
An autonomous, zero-data-retention AI DevOps pipeline that ingests GitHub webhooks, constructs code patches via LLM, runs them in air-gapped Docker sandboxes (Pytest/Jest), and posts validated fixes as PR comments for your review — all self-hosted with one docker compose command.
Notifications You must be signed in to change notification settings
Fork 0
Star 0
BranchesTags
Open more actions menu
Folders and files
NameName
Last commit message
Last commit date
Latest commit
History
16 Commits
16 Commits
.github
.github
billing-collector
billing-collector
core-brain
core-brain
django-dashboard
django-dashboard
infra
infra
ingestion-service
ingestion-service
sandbox-env
sandbox-env
.env.example
.env.example
.gitignore
.gitignore
1
1
Caddyfile
Caddyfile
Caddyfile.local
Caddyfile.local
FOR_BUSINESS_OWNERS.md
FOR_BUSINESS_OWNERS.md
FOR_TECHNICAL_AUDIENCE.md
FOR_TECHNICAL_AUDIENCE.md
LICENSE
LICENSE
Makefile
Makefile
README.md
README.md
calculator.py
calculator.py
check_pr6_comment.py
check_pr6_comment.py
check_pr_comments.py
check_pr_comments.py
debug_git.py
debug_git.py
debug_token.py
debug_token.py
docker-compose.local.yml
docker-compose.local.yml
docker-compose.web.yml
docker-compose.web.yml
docker-compose.worker.yml
docker-compose.worker.yml
docker-compose.yml
docker-compose.yml
list_repos.py
list_repos.py
setup.ps1
setup.ps1
setup_better_test.py
setup_better_test.py
setup_endtoend_test.py
setup_endtoend_test.py
target_bug.py
target_bug.py
trigger_fix.py
trigger_fix.py
trigger_pr6.py
trigger_pr6.py
Repository files navigation
An autonomous, zero-data-retention AI DevOps pipeline that ingests GitHub webhooks, constructs code patches via LLM, runs them in air-gapped Docker sandboxes (Pytest/Jest), and posts validated fixes as PR comments for your review — all self-hosted with one docker compose command.
No SaaS fees — you only pay the AI provider directly for tokens used
Zero data retention — code scrubbed in memory, destroyed after inference
Air-gapped sandbox — patches run in network-isolated, resource-throttled containers
Multi-tenant — PostgreSQL Row-Level Security isolates tenants at the database engine level
Quickstart (from zero to running in ~2 minutes)
Prerequisites
Docker & Docker Compose (v2+)
Python 3.11+, Node.js 18+
OpenRouter API key — free tier works
ngrok — free tier, exposes your local webhook to GitHub
Fast Path (3 commands)
macOS / Linux:
1. Auto-generate secrets, prompt for your OpenRouter key
make setup
2. Pre-bake sandbox images (one-time)
make sandbox
3. Launch the full stack
make up
Windows (PowerShell):
1. Auto-generate secrets, prompt for your OpenRouter key
.\setup.ps1 setup
2. Pre-bake sandbox images (one-time)
.\setup.ps1 sandbox
3. Launch the full stack
.\setup.ps1 up
Dashboard: http://localhost:8000 · Gateway: http://localhost:3000
Then expose your webhook and open a PR:
4. Expose via ngrok (separate terminal)
ngrok http http://localhost:3000
5. Open any PR on your repo — the engine handles the rest
Detailed Setup (for first-time configuration)
- Configure Environment
make setup copies .env.example → .env, generates secure random values for DJANGO_SECRET_KEY and FERNET_KEY, then prompts for your OpenRouter key. After that, set two more values manually:
Variable What to put Required
GITHUB_APP_IDENTIFIER GitHub App ID number Yes
GITHUB_WEBHOOK_SECRET Webhook secret you set in GitHub App settings Yes
Place the GitHub App .pem file at certs/github_app.pem.
- Create a GitHub App
GitHub Settings → Developer settings → GitHub Apps → New GitHub App
Settings:
GitHub App name: ai-devops-bot
Homepage URL: http://localhost:3000
Webhook URL: https://.ngrok-free.app/webhooks/github
Webhook secret: pick a random string → set as GITHUB_WEBHOOK_SECRET in .env
Permissions: Contents: Write, Pull requests: Read & Write, Checks: Write, Metadata: Read
Events: Pull request, Push
Generate a private key → save as certs/github_app.pem
Copy the App ID → set as GITHUB_APP_IDENTIFIER in .env
Install the app on a repo
- Pre-Bake & Launch
make sandbox # build local-pytest-sandbox + local-jest-sandbox images make up # docker compose up -d
- Test with a Curl
make demo
Or manually:
WEBHOOK_SECRET="${GITHUB_WEBHOOK_SECRET?}" payload='{"action":"opened","pull_request":{"number":1},"repository":{"id":101,"full_name":"local-org/test-repo","clone_url":"local_vfs"},"installation":{"id":202}}' sig=$(printf '%s' "$payload" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $NF}') curl -X POST http://localhost:3000/webhooks/github \ -H "Content-Type: application/json" \ -H "x-github-event: pull_request" \ -H "x-hub-signature-256: sha256=$sig" \ -d "$payload"
How It Works
When a PR is opened on your repo:
GitHub sends a webhook → gateway verifies HMAC signature
Gateway filters to default branch → enqueues task in Redis
Celery worker picks up → AI engine scrubs secrets → calls OpenRouter
Generated patch runs in air-gapped Docker sandbox (Pytest/Jest)
On test pass: bot posts the fix as a PR comment for your review
Dashboard logs every step at http://localhost:8000
Optional CLI
chmod +x infra/patch-bot.sh alias patch-bot=./infra/patch-bot.sh patch-bot my_app/main.py "pagination breaks when page number exceeds total pages"
Architecture
graph TB classDef external fill:#2da44e,color:#fff,stroke:#1a7f37 classDef cloud fill:#6366f1,color:#fff,stroke:#4f46e5 classDef gateway fill:#0ea5e9,color:#fff,stroke:#0284c7 classDef queue fill:#f59e0b,color:#fff,stroke:#d97706 classDef worker fill:#8b5cf6,color:#fff,stroke:#7c3aed classDef brain fill:#ec4899,color:#fff,stroke:#db2777 classDef sandbox fill:#e17055,color:#fff,stroke:#d35400 classDef dashboard fill:#14b8a6,color:#fff,stroke:#0d9488 classDef db fill:#64748b,color:#fff,stroke:#475569 classDef billing fill:#f43f5e,color:#fff,stroke:#e11d48
subgraph External["☁️ External Services"] GH["GitHub Repo Push / PR Events"] OR["OpenRouter API GPT-4o-mini"] end
subgraph Proxy["🚀 Reverse Proxy (Caddy) :80"] CADDY["Caddy Proxy Routes: /webhooks/* → Gateway /* → Dashboard"] end
subgraph Ingest["📡 Ingestion Gateway :3000"] GW["Express.js Ingestion Service HMAC Signature Verify Branch Filtration Logic"] end
subgraph Broker["📬 Message Broker"] REDIS[(Redis Queue Celery Broker + Backend)] end
subgraph Workers["⚙️ Task Workers"] CELERY["Celery Worker Process Remediation Tasks"] BEAT["Celery Beat Scheduled Cron Jobs"] end
subgraph AIEngine["🧠 AI Engine :8010"] BRAIN["FastAPI Core Brain Orchestration Layer"] SCRUBBER["🔒 Secret Scrubber In-Memory Regex Redaction AWS Keys / GH Tokens / DB Creds"] AI_INF["OpenRouter Inference Zero-Data-Retention Code Analysis + Patch Gen"] HANDLER["GitHub API Handler Post PR Comments"] end
subgraph Sandbox["🛡️ Air-Gapped Sandbox"] SBX["Docker Sandbox Container No Network · 512MB RAM Read-Only Mount"] PYT["Pytest / Jest Execution Test Suite Validation"] end
subgraph Dashboard["📊 Django Dashboard :8000"] DJANGO["Django 6 + Daphne ASGI Web UI / Admin"] POLL["Live Status Polling API /api/v1/logs-stream/"] UI["Execution Logs Cards Auto-Refresh Every 5s"] end
subgraph Storage["💾 Database Layer"] PG[("PostgreSQL Multi-Tenant")] RLS["🔐 Row-Level Security Tenant Isolation at DB Engine"] AUDIT["Audit Logs Zero Data Retention Policy"] end
subgraph Billing["💰 Billing"] BC["Billing Collector Usage Metering"] STRIPE["Stripe / Manual Cost Forecasting"] end
GH -- "Webhook: Push / Pull Request" --> NGROK[ngrok Tunnel] NGROK --> CADDY CADDY -- "/webhooks/github" --> GW CADDY -- "/*" --> DJANGO
GW -- "HMAC Verify" --> HMAC_OK{Valid Signature?} HMAC_OK -- "✅ Yes" --> FILTER{Default Branch?} HMAC_OK -- "❌ No → 401" --> ERR[Rejected] FILTER -- "✅ main" --> REDIS FILTER -- "❌ feature branch" --> FILT_LOG["[Filtration] Skipped — not default branch"]
REDIS -- "Tasks" --> CELERY REDIS -- "Schedule" --> BEAT
CELERY -- "POST /api/v1/verify-infrastructure" --> BRAIN BRAIN --> SCRUBBER SCRUBBER -- "Compliance Alert: Intercepted & Scrubbed" --> LOG_SCRUB[Logged] SCRUBBER --> AI_INF AI_INF --> OR AI_INF --> BRAIN
BRAIN -- "Generate Patch" --> SBX SBX --> PYT PYT -- "exit_code=0 ✅" --> HANDLER PYT -- "exit_code≠0 ❌" --> HANDLER HANDLER -- "Post PR Comment" --> GH
DJANGO --> POLL POLL --> UI UI --> PG
BEAT --> BC BC --> PG BC --> STRIPE
PG --> RLS PG --> AUDIT
class GH,OR external class CADDY cloud class GW,NGROK gateway class REDIS queue class CELERY,BEAT worker class BRAIN,SCRUBBER,AI_INF,HANDLER brain class SBX,PYT sandbox class DJANGO,POLL,UI dashboard class PG,RLS,AUDIT db class BC,STRIPE billing
Loading
Services
Service Technology Role
ingestion-service Node.js + Express GitHub webhook receiver, path filtering, task queuing
core-brain FastAPI + Celery AI orchestration, secret scrubbing, Docker sandbox control
django-dashboard Django 6 + Daphne ASGI Web UI, audit logs, multi-tenant admin, billing
sandbox-env Docker (air-gapped) Pre-baked Pytest/Jest images, no network, 512MB RAM cap
billing-collector Python Cost forecasting, usage metering, AWS/GCP poll
redis-broker Redis 7 Celery message queue + result backend
Security
Layer Mechanism
Code storage Zero persistence — PostgreSQL stores only operational metadata, never source code
LLM privacy data_collection: deny on every OpenRouter request — legally blocks training on your code
Secret scrubbing In-memory regex — AWS keys, GH tokens, DB credentials masked before transit
Patch execution Air-gapped Docker — no network access, 512MB RAM / 2 CPU hard limit, no host FS mount
Tenant isolation PostgreSQL RLS — database-enforced row separation, bypasses Django .filter()
Container leaks Background cron — auto-prunes orphaned sandbox containers on execution freeze
About
Autonomous AI DevOps pipeline with air-gapped sandboxing, zero-data-retention LLM routing, PostgreSQL RLS multi-tenancy, and pluggable billing. Self-hosted, open-source, one docker-compose command.
Resources
Readme
License
Apache-2.0 license
Uh oh!
There was an error while loading. Please reload this page.
Activity
Stars
0 stars
Watchers
0 watching
Forks
0 forks
Report repository
Releases
No releases published
Packages 0
Uh oh!
There was an error while loading. Please reload this page.
Contributors
Uh oh!
There was an error while loading. Please reload this page.
Languages
Python 46.2%
HTML 38.5%
JavaScript 5.3%
Shell 4.3%
TypeScript 2.4%
PowerShell 1.8%
Other 1.5%