- Python 94.4%
- HTML 3.4%
- Shell 0.9%
- CSS 0.7%
- Dockerfile 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| autopilot | ||
| docker | ||
| docs | ||
| reference | ||
| scripts | ||
| tests | ||
| .env.example | ||
| .gitignore | ||
| CHANGELOG.md | ||
| compose.yaml | ||
| config.example.yaml | ||
| Dockerfile | ||
| pyproject.toml | ||
| README.md | ||
| renovate.json | ||
agent-autopilot (Arbeitstitel)
Forgejo-Issues werden von Claude Code, Codex oder Kimi Code bearbeitet. Ein Dashboard verwaltet
Projekte, Modelle, Agentenkonten, Releases und SSH-Deployments. App und Deployer laufen als zwei
Container mit demselben Image; die SQLite-Daten liegen persistent unter data/.
Betrieb
Einrichten
-
Forgejo-Token: Unter Einstellungen → Anwendungen einen Token mit
repository(Lesen/Schreiben),issue(Lesen/Schreiben) unduser(Lesen; ohne ihn scheitert die Repo-Erkennung über/user/reposmit 403) anlegen und in.envalsFORGEJO_TOKEN=...eintragen.config.example.yamlnachdata/config.yamlkopieren und Forgejo-URL, OAuth und Agentenkonten anpassen. -
OAuth-Dashboard: In Forgejo eine öffentliche OAuth-App mit Authorization Code und PKCE anlegen. Redirect-URL ist
<dashboard.external_url>/oauth/callback. Die Client-ID kommt indashboard.client_id, nur Benutzer ausdashboard.allowed_usersdürfen sich anmelden. Für einen Zugriff über einen Reverse Proxyexternal_urlauf die HTTPS-URL setzen. Der Port wird standardmäßig nur an127.0.0.1:8080veröffentlicht (AUTOPILOT_HOST/AUTOPILOT_PORT). -
Projekte: Vorhandene YAML-Projekte werden nur beim ersten Start nach SQLite importiert. Danach ist die Datenbank führend und alle Projektänderungen erfolgen im Dashboard. Repos, auf die der technische Forgejo-Nutzer neu Zugriff erhält, erscheinen automatisch beim nächsten Poll. Agentenläufe und Deployments bleiben bis zur manuellen Freigabe deaktiviert.
-
Agenten anmelden: Das erste Claude-Konto
claude-defaultnutztdata/claude:docker compose run --rm autopilot claudeWeitere Konten aus
agents.accountsverwenden getrennte Homes. Beispiele:docker compose run --rm -e CLAUDE_CONFIG_DIR=/data/accounts/claude-2 autopilot claude docker compose run --rm -e CODEX_HOME=/data/accounts/codex-1 autopilot codex login docker compose run --rm -e KIMI_CODE_HOME=/data/accounts/kimi-1 autopilot kimiBei Kimi im interaktiven Programm anmelden. Zugangsdaten werden nicht ins Dashboard kopiert. Der Fallback erfolgt nach Priorität nur zwischen Konten desselben Agenten. Sessions und Kontopausen sind pro Konto getrennt; ein erschöpftes Claude-Konto blockiert Codex/Kimi nicht.
-
Starten:
AUTOPILOT_VERSIONin.envsetzen (Tags unter Packages in Forgejo), dann:docker compose pull && docker compose up -d docker compose logs -f autopilot deployerDas Image entsteht in der Release-Pipeline, nicht auf der VM.
max_parallelbegrenzt die gleichzeitigen Agentensitzungen. Agent, Modell und globale Defaults sind im Dashboard einstellbar; leere Projektangaben erben den globalen Default.
Releases und SSH-Deployments
Pro Projekt erstellt release: true nach fertigen Änderungen ein Release. Der Versions-Bump
(patch, minor, major), eigene Release-Regeln und Prüfbedarf sind projektbezogen einstellbar.
Bei release_after_ci: true wird das Forgejo-Release erst nach grüner CI des Release-Commits auf
dem Basis-Branch angelegt. Tag und Release zeigen immer genau auf den geprüften Commit.
Hat das Projekt eine eigene Release-Pipeline auf Tags (Horae, Vigilia, autopilot), gehört es auf
release_mode: tag: autopilot setzt dann nur den Tag, die Pipeline baut das Image und legt das
Release an. autopilot verfolgt den Lauf und meldet das Ergebnis im Issue bzw. PR. So sieht der
Deployer ein Release erst, wenn das Image existiert; Entwürfe ignoriert er. Offene Rückfragen und Nacharbeiten nutzen die gespeicherte Sitzung des
jeweiligen Agentenkontos. delivery: direct pusht ohne PR auf den Basis-Branch.
Für Deployments pro Projekt im Dashboard SSH-Host, Port, Benutzer, Schlüsseldatei,
Known-Hosts-Datei und Remote-Befehl mit {tag} eintragen. Beispiel:
/opt/demo/deploy.sh {tag}. Die Dateien liegen auf dem Host in deploy-keys/ und werden nur dem
Deployer read-only unter /run/deploy-keys eingebunden:
mkdir -p deploy-keys
ssh-keygen -t ed25519 -f deploy-keys/demo-ed25519
ssh-keyscan -H vm.example.net > deploy-keys/known_hosts
chmod 600 deploy-keys/demo-ed25519
Den Hostschlüssel beim ersten ssh-keyscan anhand des vertrauenswürdigen Fingerabdrucks prüfen
und den öffentlichen Schlüssel auf der Ziel-VM für den Deploy-Benutzer hinterlegen. Der Deployer
nutzt BatchMode=yes und StrictHostKeyChecking=yes, daher funktionieren keine interaktiven
Passwort- oder Hostschlüssel-Abfragen.
Der Deployer beobachtet tatsächlich vorhandene Forgejo-Releases, nicht lediglich vorbereitete Release-Jobs. Beim ersten Aktivieren ist der vorhandene Bestand nur eine Baseline und wird nicht nachgeholt. Jedes danach neu erscheinende Release wird genau einmal automatisch eingeplant; Neustarts erzeugen keine Duplikate. Im Projekt kann jedes erkannte Release zusätzlich manuell deployt oder ein Fehlschlag als neuer Versuch wiederholt werden. Pro Projekt läuft höchstens ein Deployment gleichzeitig.
Isolation
Agent-Sitzungen führen Code aus, den niemand geprüft hat: neue Versionen von Abhängigkeiten,
Tests, Build-Skripte. autopilot läuft deshalb ohne Docker-Socket und mit Obergrenzen für Speicher
und CPU (AUTOPILOT_MEM_LIMIT, AUTOPILOT_CPUS). Vorerst teilt er sich services-collab mit
Forgejo und der Produktion; eine eigene VM ist Stufe 3 in docs/08-isolation-plan.md. Im Container
laufen zwei Nutzer:
| Nutzer | Was | Darf |
|---|---|---|
autopilot |
Dienst, Deployer, Dashboard | Forgejo-Token, state.db, config.yaml, Logs, Push |
agent |
jede Agent-Sitzung, docker compose run … claude |
Konten unter data/claude, data/accounts, eigenes Home |
Gemeinsam haben beide nur die Worktrees unter data/work (Gruppe work). Der Container startet
als root, setzt die Rechte unter data/ (docker/entrypoint.sh) und wechselt dann den Nutzer.
Sitzungen, die eine Datenbank brauchen, erreichen den Wegwerf-Postgres testdb
(postgres://test:test@testdb:5432/test); das gehört in prompt_extra des Projekts.
Was eine übernommene Sitzung trotzdem erreicht: das Agentenkonto, die Worktrees und alles, was der Host im Netz anbietet. Aus dem Container käme sie nur über eine Kernel-Lücke.
Benutzen
- Issue im freigegebenen Projekt anlegen (Autor muss in
allowed_usersstehen), Labelautopilotsetzen. Der Dienst legt fehlende Labels selbst an. - Ein Issue-PR wird erst nach grüner CI gemergt und released. Ist sie rot, bekommt die Sitzung die
fehlgeschlagenen Jobs und repariert auf demselben Branch (zählt gegen
max_attempts). Liegt die Ursache nicht in der Änderung (CI-Infrastruktur, flaky), meldet sie das und der Issue wirdblockiert. Repos ohne CI gehen nach 15 Minuten ohne Status weiter. in-arbeitkennzeichnet einen Lauf,rückfragewartet auf einen Kommentar,blockiertnach maximalen Versuchen,zu-prüfenauf menschliche Kontrolle. Zum Wiederholen Issue öffnen undzu-prüfen/blockiertentfernen.- Rote Renovate-PRs können projektbezogen übernommen werden (
renovate); auch dabei gelten Agenten- und Kontoeinstellungen. Übersprungen werden der Onboarding-PR und PRs, solange der Basis-Branch selbst rot ist. Ist die CI nach der Reparatur grün, bekommt der PRzu-prüfen: Mergen oder das Label entfernen löst Merge und Release aus (renovate_automergemergt ohne Prüfung). Ändert eine Reparatur CI-Workflows, wird nichts gepusht und der PRblockiert. Gemergte Sicherheitsupdates (Labelsecurity) lösen ein Release aus (renovate_security_release, Standard an); grüne Updates mergt Renovate selbst. Die Release-Beobachtung behandelt manuelle, Issue- und Renovate-Releases gleich. - Zustand:
data/state.db(Projekte, Jobs, Runs, Konten, Releases, Deployments), Agentenlogs indata/logs/, Arbeitsverzeichnisse indata/work/.
Entwickeln
uv venv .venv && uv pip install --python .venv/bin/python -e '.[dev]'
AUTOPILOT_DATA=/tmp .venv/bin/python -m pytest
Releases dieses Repos
Nicht zu verwechseln mit den Releases, die autopilot für seine Projekte macht (oben): hier geht es um autopilot selbst. Dieselbe Strategie wie bei Horae und Vigilia:
- CI (
.forgejo/workflows/ci.yaml) bei jedem Push aufmainund bei Pull Requests: Tests undpip-audit. Baut kein Image. - Release nur per Tag
vX.Y.Z(.forgejo/workflows/release.yaml): wartet auf die grüne CI desselben Commits (scripts/ci_gate.py), prüft Tag gegen die Version inpyproject.tomlund einen Abschnitt inCHANGELOG.md(scripts/release_check.py), baut und pushtgit.mila-hofmann.de/mila/autopilot:<version>(dazu:X.Yund:latest) und legt das Forgejo-Release mit dem Changelog-Text an. Braucht das Actions-SecretREGISTRYwie Horae. - Ablauf:
scripts/bump-version.sh 0.2.0 # schreibt die Version in pyproject.toml $EDITOR CHANGELOG.md # [Unreleased] -> ## [0.2.0] - <Datum>, neues leeres [Unreleased] git commit -am "chore: release 0.2.0" && git push # CI von main abwarten, dann: git tag v0.2.0 && git push origin v0.2.0 - Auf der VM (
~/docker-compose-files/autopilot) liegen nurcompose.yaml,.env,deploy-keys/unddata/. Ein Update istAUTOPILOT_VERSIONin.envplusdocker compose pull && docker compose up -d; zurück geht es mit der alten Nummer. Seit 0.2.0 (2026-10-27).
Zielbild
Ein autonomer Agent, der als installierte App läuft und
- beliebig vielen Projekten auf dem eigenen Forgejo zugewiesen werden kann,
- diese Projekte periodisch überwacht (Issues, PR-Kommentare, CI-Status und Releases),
- sobald es etwas zu tun gibt, eine Agent-Sitzung startet, die Arbeit erledigt und im Issue antwortet,
- dabei Claude Code, Codex und Kimi Code projektbezogen nutzt und bei erschöpftem Kontingent zwischen mehreren Konten desselben Agenten wechselt.
Regel Nr. 1: erst suchen, dann bauen
Bevor wir irgendetwas davon selbst bauen und dauerhaft pflegen, suchen wir nach fertigen
Lösungen. Eigenbau nur für die Lücke, die danach übrig bleibt. Siehe docs/03-build-vs-buy.md
für Suchbegriffe und Kriterien. Der Eigenbau in Vigilia entstand pragmatisch, nicht nach einer
solchen Suche.
Inhalt
| Datei | Inhalt |
|---|---|
docs/01-current-implementation.md |
Wie der Autopilot in Vigilia heute funktioniert |
docs/02-ideas.md |
Frühe Ideen aus dem Chat |
docs/03-build-vs-buy.md |
Suchauftrag nach fertigen Lösungen, Bewertungskriterien |
docs/07-renovate-handover.md |
Spezifikation der inzwischen integrierten Renovate-Übernahme |
docs/08-isolation-plan.md |
Isolation von Sitzungen und CI: was umgesetzt ist, was als Nächstes kommt |
reference/autopilot.py, reference/autopilot_prompt.md |
Schnappschuss des Vigilia-Stands vom 2026-10-23 (nur Referenz, nicht pflegen) |