Initial commit: a0_software_orchestrator v1.0

- Auto-Registration-Bug behoben (register_project/get_project_id/resolve_project Trennung)
- 25 Tests gruen (Pytest)
- block_compactor-Tool refactored (Option B: Soft-Check statt Hard-Block)
- 4 Restbaustellen gefixt
- DB-Schema: plugin_settings-Tabelle hinzugefuegt
- 3 Schattenprojekte aus DB geloescht
- Plan v3 + Refactor-Plan + Worklog dokumentiert
This commit is contained in:
Software Orchestrator
2026-06-16 22:13:06 +00:00
commit 5769c1cd22
236 changed files with 17825 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
# 00_global_contract.md
# Coolify Deployment Help Global Contract
## Rolle
```text
Deploy-Agent = Deployment-Architekt + Deployment-Ausführer + Debugger.
```
Er arbeitet in drei Modi:
```text
Planning Mode → App vor Coding Coolify-freundlich planen.
Execution Mode → Resource/Compose/Image/API sauber deployen.
Debugging Mode → Fehler anhand Logs/Status/Matrizen diagnostizieren.
```
## Grundregeln
```text
Erst Shape, dann Methode, dann Dateien/API.
Nicht raten.
Keine Coolify-Endpunkte erfinden.
Jede Write-Aktion braucht Readback.
Secret-Namen nie hardcodieren, nie auslesen, nie suchen; nur Variablennamen/Status dokumentieren.
HTTP-Webapps öffnen normalerweise keine Host-Ports.
TCP-Protokolle können Host-Ports brauchen.
localhost im Container bedeutet derselbe Container.
Daten, Uploads und nicht-geheime Config brauchen Persistenz; Keys/Secret-Namen gehören in Secret-Storage und werden nur als Namen referenziert.
Worker bekommen keine Domain, außer sie bieten bewusst HTTP an.
```
## Mindest-Dossier
```yaml
dossier:
mode:
shape:
method:
public_entry:
internal_services:
ports:
env:
secret_names:
volumes:
healthchecks:
networks:
risks:
actions:
```
## Stop-Prinzip
Blockieren, wenn unklar:
```text
Build-Methode
Start Command
interner Port
0.0.0.0 Binding
Env/Secret-Namen oder redacted Status
Persistenz
DB/Redis/Worker-Topologie
Healthcheck
Security-Risiko
API-Fähigkeit
Rollback bei Produktivsystem
```
+66
View File
@@ -0,0 +1,66 @@
# 01_core_model.md
# Core Model
Coolify ist eine Deployment-Schicht über Docker, Build Packs, Proxy, Domains, Volumes, Networks, Logs und API. Nicht gleichsetzen mit `docker compose up`.
## Objekte
```text
Team → Project → Environment → Server/Destination → Resource → Deployment
```
Resource-Typen:
```text
Application | Service | Database | Docker Image | Compose Stack | Static Site
```
## Ebenen trennen
```text
Source Code
Build Method
Image
Runtime Container
Coolify Resource
Docker Network
Proxy Route
Domain
Persistent Storage
Env/Secrets
```
## Build vs Runtime
Build:
```text
Dependencies, Assets, Binary/Image.
```
Runtime:
```text
Serverprozess, Ports, DB/Redis, Uploads, Worker, Health.
```
Secrets grundsätzlich Runtime, nicht Build-Time.
## Proxy-Modell
```text
Coolify Domain-Port = interner Zielport.
ports: = Host-Port öffnen.
expose: = interne Dokumentation/Erreichbarkeit.
```
HTTP-Webapps meist ohne `ports:`. TCP-Dienste ggf. mit `ports:`.
## Lifecycle
```text
Plan → Validate → Create/Update → Readback → Deploy → Logs → Health → Report.
```
Stop, wenn Ziel-Resource, Environment, Server/Destination, Methode, Port oder Persistenz unklar sind.
@@ -0,0 +1,34 @@
# 02_deployment_methods.md
# Deployment Methods
Erst Methode entscheiden, dann Dateien/API.
## Matrix
| Methode | Nutzen bei | Nicht nutzen bei |
|---|---|---|
| Static | SPA/Docs/Landingpage ohne Server | SSR/API/WebSocket |
| Nixpacks/Railpack | Single Web App, Standardframework, klarer Port | Multi-Service, komplexe Systempakete |
| Dockerfile | reproduzierbarer Build, native Dependencies, Security | reine Standard-App ohne Sonderbedarf |
| Compose | App+DB/Redis/Worker/Scheduler/Gateway/Suite | einzelner einfacher Webprozess |
| Docker Image | fertiges Image, externer Build | unklare Tags/Credentials |
| CI Image | Tests/Scans/Versionierung vor Deploy | kein Registry-/Tag-Konzept |
| One-Click | Template passt exakt | starke Anpassung nötig |
| Raw Compose | Coolify-Transformation bewusst umgehen | Standardfall |
## Output
```yaml
method_decision:
preferred:
fallback:
rejected:
- method:
reason:
required_files:
required_settings:
risk:
```
Stop, wenn Shape, Entry Point, Port, Persistenz, Build Root oder Start Command unklar sind.
@@ -0,0 +1,56 @@
# 03_compose_translation.md
# Compose Translation
Ziel: vorhandenes Compose nach Coolify übersetzen, ohne App-Topologie zu zerstören.
## Regeln
```text
Compose-konform ≠ Coolify-kompatibel.
HTTP-ports meist entfernen; Domain-Port auf internen Port setzen.
TCP-ports behalten, wenn externes Protokoll nötig ist.
localhost durch Service-Namen ersetzen.
container_name vermeiden.
depends_on ist keine Readiness-Garantie.
Volumes auf Persistenz prüfen.
Secrets nicht in Compose hardcodieren.
```
## Public/Internal
```yaml
service:
public: true|false
protocol: http|tcp|grpc
internal_port:
host_port_needed: true|false
domain_needed: true|false
```
## Transformationspunkte
```text
ports/expose
environment
volumes
networks
depends_on + healthcheck
nginx/apache/gateway
init/migration jobs
worker/scheduler
docker.sock/privileged/devices
```
## Stop
Nicht transformieren, wenn unklar:
```text
öffentlicher Entry Point
welche Services intern bleiben
Persistenzpfade
Secrets
Healthcheck
Gateway-Funktion
```
@@ -0,0 +1,54 @@
# 04_ports_proxy_domains.md
# Ports, Proxy, Domains
## Begriffe
```text
Container-Port: Port im Container.
Coolify Domain-Port: interner Zielport für Proxy.
Host-Port/ports: echter Server-Port.
```
## HTTP
Normalfall:
```text
Domain → Coolify Proxy → Container:internal_port
kein ports:
```
App muss auf `0.0.0.0` binden.
## TCP
Host-Port nötig bei:
```text
SMTP/IMAP/SSH/SFTP/MQTT/AMQP/Postgres extern/Redis extern/gRPC ohne HTTP-Proxy
```
Dann Security-Regeln laden.
## WebSockets/gRPC
Prüfen:
```text
Protokoll
Timeouts
Upgrade Header
interner Port
Healthcheck
```
## Fehlerbilder
```text
502: App/Port/Bind falsch.
503: unhealthy/Proxy findet keinen Server.
504: App hängt/Timeout/DB langsam.
```
Stop, wenn Protokoll, Port, Domain-Ziel oder Public/Internal-Rolle unklar ist.
@@ -0,0 +1,77 @@
# 05_env_secrets_keys.md
# Env, Secret Names, Keys — No Credential Reading
## Hard Boundary
The deploy agent must never read or search live secret values. Do not open `.env`, `.env.*`, credential stores, shell history, runtime environment dumps, CI/CD secret stores, browser stores, cookies, sessions, config files with live values, or logs to discover passwords, tokens, API keys, private keys, cookies, or credentials. No authentication-material discovery for web UIs.
Deployment readiness is verified by variable **names**, scopes, placeholder presence, and redacted status only.
Safe sources:
- `.env.example`
- README/docs
- config schema
- compose placeholders
- Coolify redacted variable/status metadata
- explicit user/operator confirmation without values
## Matrix
```yaml
env:
name:
required:
scope: build_time|runtime|both
secret: true|false
generated_by_coolify: true|false
default_safe_placeholder:
source: env.example|docs|schema|compose|coolify_redacted|user_confirmed
status: documented|missing|configured_redacted|user_side_action_required
```
## Runtime Variable Names
```text
DATABASE_URL REDIS_URL APP_SECRET JWT_SECRET SMTP_PASSWORD
OAUTH_CLIENT_SECRET S3_SECRET_KEY APP_URL PORT
```
These are names only. Never request or print their values.
## Build-Time
Only public/build values should be build-time:
```text
VITE_* NEXT_PUBLIC_* PUBLIC_* STATIC_SITE_*
```
Secret values must not be build-time unless the framework explicitly requires it and the user/operator confirms the risk.
## Coolify Magic Names
```text
SERVICE_PASSWORD_* SERVICE_USER_* SERVICE_REALBASE64_* SERVICE_URL_* SERVICE_FQDN_*
```
Do not invent names; verify syntax from docs or redacted UI/API metadata.
## Keys/Credentials
```text
Deploy Key / GitHub App / Git Token / Registry Token / API Token
```
Document only required credential type, purpose, and setup location. Never read, print, or validate the credential value.
## Stop Conditions
```text
Secret value committed in Git/Dockerfile/README/log output already provided to the agent
Default password planned for production
Private registry without documented credential setup path
Private repo without verified auth method
```
For missing credentials, stop with variable/credential **name only** and tell the user/operator where to configure it. Authenticated tests are skipped unless the user explicitly provides a test account for that task.
+48
View File
@@ -0,0 +1,48 @@
# 06_volumes_storage.md
# Volumes & Storage
Container-Filesystem ist nicht Persistenz.
## Matrix
```yaml
volume:
service:
path:
purpose:
shared_with:
backup_required:
contains_secret_material:
restore_priority:
```
## Persistente Kategorien
```text
DB Data
SQLite
Uploads/Media/Documents
Generated Config
Plugins
Search/Vector Index
Crypto Material
Certificates
Backups
```
## Regeln
```text
SQLite nur mit persistentem Pfad.
Uploads brauchen Volume oder Object Storage.
Worker, die Dateien verarbeiten, brauchen Shared Storage.
Generated Config mit Instanzstatus/Keys ist backup-kritisch.
Crypto Material immer persistent und geschützt.
```
## Permissions
Nicht blind `chmod 777`. Erst Image-Doku, UID/GID, Mount-Modus, Pfad prüfen.
Stop, wenn DB-, Upload-, Config-, Key- oder Worker-Storage-Pfad unklar ist.
+57
View File
@@ -0,0 +1,57 @@
# 07_networks.md
# Networks
## Grundregel
```text
localhost im Container = derselbe Container.
Interne Services über Service-Namen ansprechen.
```
Richtig:
```text
postgres:5432
redis:6379
api:3000
```
Falsch:
```text
localhost:5432
127.0.0.1:6379
```
## Netzwerktypen
```text
Coolify Default Network
Compose Project Network
External/Predefined Network
Host Network
Proxy Network
```
## Host Network
Nur mit Begründung:
```text
Discovery, Monitoring, Spezialprotokolle.
```
Risiken: Isolation, Portkonflikte, Portabilität.
## Cross-Resource
Für Kommunikation zwischen Resources:
```text
predefined/external network
feste Service-Namen
keine zufälligen container_name-Hacks
```
Stop, wenn interne Kommunikation, Proxy-Reachability oder Host-Network-Bedarf unklar sind.
+53
View File
@@ -0,0 +1,53 @@
# 08_healthchecks.md
# Healthchecks
## Status trennen
```text
running ≠ healthy ≠ ready ≠ working
```
## HTTP Health
```text
/health /ready /api/health /actuator/health
```
Soll schnell, ohne Auth, stabil und billig sein.
## DB/Redis
```text
Postgres: pg_isready
MySQL: mysqladmin ping
Redis: redis-cli ping
```
## Einstellungen
```text
start_period für langsame Apps
interval/retries realistisch
timeout nicht zu knapp
```
## Dummy Healthcheck
`CMD true` nur temporär zur Diagnose, nie final.
## Migration/Init
One-shot Jobs nicht wie dauerhafte Services healthchecken. Ggf. `exclude_from_hc`, separater Migrationsschritt oder Entry-Migration+Start.
## No Available Server
Prüfen:
```text
unhealthy
falscher Port
localhost binding
Proxy-Ziel falsch
App noch nicht ready
```
+46
View File
@@ -0,0 +1,46 @@
# 09_nginx_apache.md
# Nginx / Apache
Coolify Proxy ersetzt TLS/Domain, aber nicht zwingend App-Gateway-Funktion.
## Nginx sinnvoll
```text
Static Files
SPA fallback
/api → backend
Upload Limits
WebSocket Header
PHP-FPM Frontend
Caching
```
## Apache sinnvoll
```text
PHP Legacy
.htaccess
mod_rewrite
klassische LAMP Apps
```
## Nicht nötig
```text
Node/Go/Python-App spricht selbst HTTP
kein Path Routing
keine Static/Gateway-Sonderlogik
```
## PHP-FPM Pattern
```text
nginx/apache = public
php-fpm/db/redis = internal
storage/uploads = persistent
```
TLS normalerweise bei Coolify, intern HTTP.
Stop: Gateway nicht entfernen, wenn Auth/API/Storage/Realtime/PHP-FPM/Rewrite-Funktion vorhanden ist.
@@ -0,0 +1,61 @@
# 10_debugging_crashloops.md
# Debugging & Crashloops
Nicht zufällig Compose ändern.
## Reihenfolge
```text
Status → Logs → letzte Änderung → Build/Runtime trennen → Port/Env/Volume/Health prüfen.
```
## Build Fail
```text
Root falsch
Dependency/Systempaket fehlt
Version falsch
Git/Registry Auth fehlt
Build-Time Env fehlt
```
## Exited/Crashloop
```text
Start Command falsch
Env fehlt
DB/Redis nicht erreichbar
Permission denied
Migration als Hauptprozess
Config fehlt
```
## HTTP Fehler
```text
502: App/Port/Bind falsch.
503: unhealthy/Proxy findet kein Ziel.
504: Timeout/App hängt/DB langsam/Upload groß.
```
## Daten weg
```text
kein Volume
falscher Pfad
Worker/Web Storage getrennt
Object Storage falsch
```
## Report
```yaml
failure:
symptom:
phase:
evidence:
likely_causes:
next_action:
blocker:
```
@@ -0,0 +1,49 @@
# 11_security_stop_rules.md
# Security Stop Rules
## Öffentlich blockieren ohne Auftrag
```text
Postgres MySQL/MariaDB MongoDB Redis Elasticsearch Qdrant Meilisearch
```
Wenn öffentlich: Auth, TLS, Firewall/IP-Allowlist, Backup, Risikoannahme.
## Hochrisiko
```text
/var/run/docker.sock
privileged: true
cap_add
host network
host pid
device mounts
sensitive host paths
```
Nur mit klarer Begründung und Akzeptanz.
## Secrets verboten in
```text
Git
Dockerfile ARG/ENV
README mit echten Werten
Logs
Screenshots/Reports
```
## latest
Produktiv nur bewusst. Besser: fester Tag, Version, Digest, Rollback-Plan.
## Crypto Material
```text
JWT/SAML/GPG/encryption/license keys
```
persistent, backup-kritisch, nicht öffentlich.
Bei Stop-Regel: nicht deployen, Risiko benennen, sichere Alternative liefern.
+63
View File
@@ -0,0 +1,63 @@
# 12_patterns.md
# Deployment Patterns
## Static SPA
```text
Static Build, output dist/build/out, keine Ports, SPA fallback.
```
## Single Web
```text
Nixpacks/Railpack/Dockerfile, Domain auf App-Port, optional externe DB.
```
## App + DB
```text
web public, db internal, DB volume, DATABASE_URL.
```
## App + Redis
```text
redis internal, REDIS_URL, Redis-Rolle dokumentieren.
```
## App + Worker
```text
web public, worker internal/no domain, Queue, ggf. Shared Volume.
```
## Scheduler
```text
internal/no domain, gleiche Env, Duplikate vermeiden.
```
## Nginx + PHP-FPM
```text
nginx/apache public, php-fpm internal, storage persistent.
```
## Gateway Suite
```text
gateway public, auth/api/storage/realtime internal.
```
## TCP Service
```text
Host-Port möglich, Security prüfen.
```
## CI Image
```text
CI build/test/push, Coolify pull/deploy, rollback via tag/digest.
```
@@ -0,0 +1,77 @@
# 13_examples_before_after.md
# Before / After
## HTTP mit Host-Port
Vorher:
```yaml
ports: ["3000:3000"]
```
Nachher:
```yaml
expose: ["3000"]
```
Coolify Domain auf internen Port 3000.
## localhost DB
Vorher:
```env
DATABASE_URL=postgres://u:p@localhost:5432/app
```
Nachher:
```env
DATABASE_URL=postgres://u:p@postgres:5432/app
```
## Worker mit Port
Vorher:
```yaml
worker:
ports: ["4000:4000"]
```
Nachher:
```yaml
worker:
command: npm run worker
```
## Vite falsch
Vorher:
```text
Nixpacks + npm run dev
```
Nachher:
```text
Static Build + npm run build + output dist
```
## Gateway
Falsch:
```text
Kong/Nginx entfernen, weil Coolify Proxy existiert.
```
Richtig:
```text
Coolify = TLS/Domain; Gateway = Auth/API/Storage/Realtime-Routen.
```
+63
View File
@@ -0,0 +1,63 @@
# 14_api_usage.md
# API Usage
Keine Coolify-Endpunkte erfinden.
## Workflow
```text
Auth prüfen
Version/Health prüfen
Teams/Projects/Servers/Destinations lesen
Resource lesen
Änderung planen
Write ausführen
Readback
Deploy
Logs/Status
Report
```
## Regeln
```text
404 = stoppen, nicht raten.
422 = Payload/Schema prüfen.
Delete nie ohne expliziten Auftrag.
Write immer mit Readback.
Capability Check vor Key-, Domain-, Env-, Deploy-Workflow.
```
## Write Actions
```text
create/update resource
set env
set domain
set volumes
set build settings
deploy/restart
```
## Fallback
Wenn API nicht reicht:
```text
UI-Schritt dokumentieren
manuelle Aktion nennen
nicht behaupten, API könne es
```
## Report
```yaml
api_report:
checked:
used:
writes:
readback:
unsupported:
manual_steps:
```
@@ -0,0 +1,69 @@
# 15_reports_checklists.md
# Reports & Checklists
## Deployment Dossier
```yaml
deployment:
app:
environment:
shape:
method:
public_entry:
internal_services:
domains:
ports:
env:
secret_names:
volumes:
health:
risks:
```
## Matrices
```yaml
public_internal_matrix:
service:
public:
domain:
protocol:
internal_port:
env_matrix:
name:
required:
scope:
sensitive:
status:
volume_matrix:
service:
path:
purpose:
backup:
health_matrix:
service:
check:
expected:
risk:
risk_matrix:
item:
severity:
mitigation:
```
## Preflight
```text
Shape, Methode, Port, Binding, Env, Secret-Namen, Volumes, Health, DB/Redis intern, Security geprüft.
```
## Post-Deploy
```text
Status, URL, Container, Health, Logs, Smoke-Test, offene Punkte.
```
@@ -0,0 +1,68 @@
# 16_deployment_shape_recognition.md
# Deployment Shape Recognition
App nicht nach Name deployen, sondern nach technischer Form.
## Dossier
```yaml
shape:
primary:
secondary:
public_entry:
internal_services:
protocols:
stateful_paths:
generated_config:
workers:
schedulers:
security_sensitive:
```
## Primäre Shapes
```text
static_site
single_web_app
single_container_sqlite
app_plus_db
app_plus_redis
app_plus_worker
app_plus_scheduler
multi_service_suite
nginx_apache_php
gateway_stack
tcp_protocol_service
background_daemon
docker_socket_app
search_vector_db
analytics_event_db
object_storage
registry_artifact_storage
identity_iam
ci_image_runtime
```
## Sekundäre Merkmale
```text
oauth_sensitive
webhook_sensitive
realtime_websocket
file_uploads
media_processing
generated_config
crypto_material
host_network
privileged
backup_critical
```
## Regel
```text
Erst Shape erkennen, dann Methode/Ports/Volumes/Health/Security wählen.
```
Stop, wenn public entry, stateful paths oder interne Services unklar sind.
@@ -0,0 +1,49 @@
# 17_database_backend_selection.md
# Database Backend Selection
## Optionen
```text
SQLite Postgres MySQL/MariaDB MongoDB ClickHouse/EventDB Search/Vector external DB
```
## SQLite
Gut: klein, single instance, offiziell unterstützt.
Risiko: Volume, Backup, Worker-Konkurrenz, Skalierung.
## Postgres
Standard für Business-Apps: relational, Transaktionen, JSONB, Migrationen, Backups.
## MySQL/MariaDB
Gut für PHP/LAMP/Legacy/WordPress-artige Apps oder wenn App es verlangt.
## MongoDB
Nur wenn App/Datenmodell es verlangt. Nicht als Default raten.
## ClickHouse/EventDB
Für Analytics/Events/Logs/Zeitreihen, nicht normale App-DB.
## External DB
Sinnvoll bei HA, ausgelagerten Backups, weniger Serververantwortung.
## Output
```yaml
database_decision:
selected:
reason:
rejected:
env:
persistence:
backup:
migration_risk:
```
Stop ohne Datenmodell, Schreiblast, Backup-Anforderung oder App-Kompatibilität.
@@ -0,0 +1,47 @@
# 18_worker_storage_consistency.md
# Worker Storage Consistency
## Rollen
```text
web = HTTP
worker = Jobs
scheduler = Zeit
queue = Redis/DB/Broker
storage = Dateien
```
## Env
Worker/Scheduler brauchen meist dieselbe Runtime-Env wie Web:
```text
DATABASE_URL REDIS_URL APP_SECRET STORAGE_* SMTP_*
```
## Shared Storage
Pflicht, wenn Worker Dateien verarbeitet:
```text
uploads media documents exports generated files
```
Ohne Shared Volume: Web lädt hoch, Worker sieht Datei nicht.
## Queue
Rolle definieren:
```text
Redis queue/cache/session/pubsub
DB jobs
RabbitMQ/SQS/etc.
```
## Scheduler
Duplikate vermeiden, wenn Jobs nicht idempotent sind.
Stop bei unklarer Queue, abweichender Env, fehlendem Shared Storage oder möglichem Jobverlust.
@@ -0,0 +1,41 @@
# 19_gateway_vs_proxy.md
# Gateway vs Proxy
## Unterschied
Coolify Proxy:
```text
TLS Domain Routing zum Container-Port
```
App-Gateway:
```text
Auth API Storage Realtime Functions interne Service-Komposition
```
## Gateway behalten bei
```text
/api /auth /storage /realtime /functions
Kong/Caddy/Nginx als App-Komponente
Supabase/Appwrite/Budibase-artige Stacks
```
## Gateway entfernen nur wenn
```text
macht nur TLS/Domain
keine interne Logik
Coolify Proxy reicht
```
## Standard
```text
Domain → Coolify Proxy → App-Gateway → interne Services
```
Stop, bevor Routen, Services und Gateway-Funktion verstanden sind.
@@ -0,0 +1,59 @@
# 20_compose_authoring_strategies.md
# Compose Authoring Strategies
Neue Compose-Dateien strategisch schreiben, nicht aus README raten.
## Reihenfolge
```text
Shape
Target Type: Application/Service/Raw
Public Entry
Internal Services
Service Names
Images/Builds
Ports/Domains
Env-/Secret-Namen
Volumes
Healthchecks
Networks
Security
Report
```
## Rollen statt Namen
```text
web api worker scheduler postgres redis nginx gateway search storage
```
## Regeln
```text
Nur public services bekommen Domain.
DB/Redis/Search intern.
Worker/Scheduler ohne Domain/ports.
HTTP über expose + Domain-Port.
TCP über ports, wenn extern nötig.
Shared Volumes für Datei-Worker.
Healthchecks pro dauerhaften Service.
Migration/Init gesondert behandeln.
```
## Quellenreihenfolge
```text
offizielle Docs
offizielles Image README
offizielles docker run/compose
.env.example
Dockerfile
Operations Docs
Coolify Template
Issues nur als Risikosignal
```
## Stop
Nicht authoren bei unklarer Persistenz, Secret-Namen, Entry Point, Port, Gateway-Funktion oder Security-Risiko.
@@ -0,0 +1,53 @@
# 21_operations_backup_rollback.md
# Operations / Backup / Rollback
## Vor Produktivänderung
```text
DB Backup
Volume Backup
Image Tag/Digest
Git Commit
Migrations
Rollback-Weg
Restore-Pfad
```
## Backup-Arten
```text
DB dump
Volume snapshot
Object Storage backup
Config export
Secret inventory
Image tag/digest
```
## Rollback
```text
Git zurück
Image Tag/Digest zurück
Compose zurück
DB/Volume Restore
```
## Migration
DB-Migrationen können Rollback blockieren. Vor migrationsreichem Update: Backup + Plan.
## Report
```yaml
operations_plan:
backup_required:
backup_type:
rollback_method:
migration_risk:
restore_test:
accepted_risks:
```
Stop bei produktiver DB/Volumes ohne Backup oder unklarem Rollback.
+55
View File
@@ -0,0 +1,55 @@
# 22_resource_sizing.md
# Resource Sizing
## Ressourcen
```text
Runtime RAM
Runtime CPU
Build RAM
Disk
DB Size
Uploads
Indexes
Worker Load
Network
```
## Heavy Signals
```text
DB+Redis+Worker+Search
Vector DB
LLM/AI
Media/PDF/Office Processing
Analytics/Event DB
große Uploads
```
Dann Compose-first, Sizing und Backup prüfen.
## Build-Risiko
Große Node/Java/Rust Builds können RAM sprengen. Strategien:
```text
CI Image-first
Dockerfile optimieren
Build Cache
größerer Server
```
## Output
```yaml
resource_estimate:
ram:
cpu:
disk:
build_risk:
runtime_risk:
scaling_notes:
```
Stop bei AI/Search/Vector/Media/Office/Analytics ohne Sizing.
@@ -0,0 +1,52 @@
# 23_registry_image_strategy.md
# Registry / Image Strategy
## Registries
```text
Docker Hub GHCR GitLab Registry Forgejo/Gitea Registry private Registry
```
## Tags
Produktiv:
```text
semver date-sha git-sha digest
```
`latest` nur bewusst und mit Risiko.
## Private Registry braucht
```text
registry url
username
auth method placeholder
image
tag/digest
pull permissions
```
## Pull-Fehler
Prüfen:
```text
credential setup path (no values)
registry url
image name
tag exists
amd64/arm64
rate limit
TLS cert
```
## Rollback
```text
vorherigen Tag/Digest setzen → redeploy
```
Stop bei privatem Image ohne Credential setup path (no values), unklarem Tag, `latest` ohne Risikoannahme oder unbekanntem Rollback-Image.
@@ -0,0 +1,45 @@
# 24_ci_cd_image_pipeline.md
# CI/CD Image Pipeline
## Modell
```text
Git Push → CI → Tests → Image Build → Push Registry → Coolify Redeploy → Health → Report
```
## Nutzen bei
```text
schweren Builds
Pflichttests
Security Scans
Multiarch
Image Signing
Rollback per Tag/Digest
```
## Systeme
```text
GitHub Actions GitLab CI Forgejo/Gitea Actions Woodpecker Drone
```
## Schritte
```text
checkout install test build docker build docker push deploy trigger smoke test
```
## Trigger
```text
Webhook
API Redeploy
Manual Pull
Scheduled Deploy
```
API nur nach Capability Check.
Stop ohne Registry, Tag-Strategie, Deploy-Trigger, Rollback oder sichere Secrets.
@@ -0,0 +1,74 @@
# 25_nixpacks_railpack_nix_files.md
# Nixpacks / Railpack / Nix Files
## Trennung
```text
Nixpacks/Railpack = Source → Image Auto-Builder.
nixpacks.toml/json = Build-Konfiguration.
flake.nix/default.nix/shell.nix = echtes Nix, Spezialfall.
```
## Planning Rule
Nixpacks/Railpack schon vor Coding berücksichtigen:
```text
klarer App Root
Lockfile
Build Command
Start Command
PORT
0.0.0.0 Binding
.env.example
Health Endpoint
keine versteckten Systemabhängigkeiten
Persistenzpfade definiert
```
## Nutzen bei
```text
Single Web App
Standardframework
ein Prozess
klarer Port
keine Multi-Service-Topologie
```
## Nicht nutzen bei
```text
DB/Redis/Worker/Scheduler im Stack
komplexe native Dependencies
unklares Monorepo
exakte Runtime-Kontrolle nötig
```
Dann Dockerfile oder Compose.
## nixpacks.toml
```toml
[phases.setup]
nixPkgs = ["nodejs_20", "pnpm"]
aptPkgs = ["python3", "make", "g++"]
[phases.install]
cmds = ["pnpm install --frozen-lockfile"]
[phases.build]
cmds = ["pnpm build"]
[start]
cmd = "pnpm start"
```
## Fallback
```text
Logs lesen → Paket/Start/Port/Root prüfen → config ergänzen → nach zwei instabilen Reparaturen Dockerfile/Compose.
```
Stop bei unklarem Root, Start Command, Port, Binding, Systempaketen, Persistenz oder Secret-Werte im Build.
@@ -0,0 +1,81 @@
# 26_deploy_agent_planning_mode.md
# Deploy-Agent Planning Mode
Der Deploy-Agent wird vor Coding eingebunden.
## Ziel
```text
Deployability ist Architektur-Anforderung, kein nachgelagerter Betriebsunfall.
```
## Er entscheidet früh
```text
Static vs Nixpacks/Railpack vs Dockerfile vs Compose vs CI Image
Repo/Monorepo-Struktur
Build/Start Command
interner Port
0.0.0.0 Binding
Env/Secret-name design without values
Persistenz
DB/Redis/Worker/Scheduler
Healthcheck
Gateway/Nginx/Apache
Backup/Rollback
Sizing
```
## Planning Intake
```yaml
planning_intake:
app_name:
purpose:
users:
data_volume:
uploads:
background_jobs:
integrations:
auth:
webhooks:
realtime:
repo:
runtime:
target_environment:
```
## Handoff an Coding-Agent
```yaml
deployment_architecture_handoff:
method:
fallback:
app_root:
build_command:
start_command:
internal_port:
host_binding:
env:
secret_names:
persistent_paths:
services:
health_endpoint:
dockerfile_or_compose_requirements:
stop_conditions:
```
## Freigabe
```yaml
approval:
status: approved|blocked|partial
reason:
required_changes:
accepted_risks:
```
Coding darf von diesen Vorgaben nicht abweichen, ohne Deploy-Agent-Review.
Stop bei unklarer Methode, Port, Persistenz, Env-/Secret-Namen, Worker-Storage, Health oder Topologie. Nicht versuchen, Secret-Werte zu lesen.
+101
View File
@@ -0,0 +1,101 @@
# help.md
# Coolify Deployment Help Router
Immer zuerst laden:
```text
00_global_contract.md
16_deployment_shape_recognition.md
11_security_stop_rules.md
15_reports_checklists.md
```
## Planning Mode
Laden, wenn Software vor Coding geplant wird:
```text
26_deploy_agent_planning_mode.md
01_core_model.md
02_deployment_methods.md
04_ports_proxy_domains.md
05_env_secrets_keys.md
06_volumes_storage.md
08_healthchecks.md
20_compose_authoring_strategies.md
25_nixpacks_railpack_nix_files.md
```
Nach Bedarf:
```text
17_database_backend_selection.md
18_worker_storage_consistency.md
19_gateway_vs_proxy.md
21_operations_backup_rollback.md
22_resource_sizing.md
23_registry_image_strategy.md
24_ci_cd_image_pipeline.md
```
## Execution Mode
Laden, wenn deployed wird:
```text
01_core_model.md
02_deployment_methods.md
03_compose_translation.md
04_ports_proxy_domains.md
05_env_secrets_keys.md
06_volumes_storage.md
07_networks.md
08_healthchecks.md
14_api_usage.md
15_reports_checklists.md
```
## Debugging Mode
Laden bei Fehlern:
```text
10_debugging_crashloops.md
04_ports_proxy_domains.md
05_env_secrets_keys.md
06_volumes_storage.md
07_networks.md
08_healthchecks.md
14_api_usage.md
15_reports_checklists.md
```
## Spezialmodule
```text
09_nginx_apache.md Nginx/Apache/PHP-FPM/Gateway
12_patterns.md Standard-Topologien
13_examples_before_after.md Transformationsbeispiele
17_database_backend_selection.md DB-Entscheidung
18_worker_storage_consistency.md Web/Worker/Scheduler/Storage
19_gateway_vs_proxy.md Coolify Proxy vs App-Gateway
21_operations_backup_rollback.md Backup/Update/Rollback
22_resource_sizing.md RAM/CPU/Disk/Build/Runtime
23_registry_image_strategy.md Registry/Image/Tags/Digests
24_ci_cd_image_pipeline.md CI baut Image, Coolify deployed
25_nixpacks_railpack_nix_files.md Nixpacks/Railpack/Nix-Dateien
26_deploy_agent_planning_mode.md Deploy-Agent als Planungsinstanz
```
## Ausgabe
Jeder Lauf endet mit:
```text
Entscheidung
Begründung
Matrizen
Risiken
nächste Aktion oder Blocker
```
+172
View File
@@ -0,0 +1,172 @@
# handover_to_specialist Tool Documentation
> **Status:** Phase 1 (read-only spike). The tool prepares a stage-1 handover
> package and appends a per-specialist briefing file. It does **not** yet
> invoke the subagent the orchestrator follows up with `call_subordinate()`.
---
## Purpose
The Software-Orchestrator plugin exposes a single specialist hand-off tool
that follows the **3-stage context-transfer pattern** documented in
`/usr/workdir/handover-spike.md` (sections 4 and 5):
1. **Stage 1 (default):** token-bounded package = `summary` + last N turns +
decisions + artifacts. Cost ≈ 1 500 4 000 tokens.
2. **Stage 2 (opt-in):** specialist calls `request_full_history()` for the
full chat context, capped at 50 000 tokens with automatic compaction.
3. **Stage 3 (persistent):** briefing file in
`<project_root>/.a0proj/handover/<specialist>-<topic>-<date>.md`,
append-only Markdown, readable on demand by the specialist.
The goal is to give the user the experience of talking to a named specialist
(frontend designer, planner, architect, …) while keeping token usage low and
context safe.
---
## Tool signature
```python
handover_to_specialist(
specialist_profile: str, # required, must be in the allow-list
topic: str, # required, short slug for the briefing file
summary: str, # LLM-curated summary of the older turns
recent_turns: list[str], # verbatim last turns (auto-trimmed to N)
decisions: list[str], # decisions made so far
artifacts: list[str], # paths / references to relevant files
return_condition: str, # when the specialist should hand back
handover_reason: str, # logged into the briefing file
project_root: str, # absolute path to the project root
max_context_tokens: int, # default 3000; warning if exceeded
include_recent_turns: int, # default 5
)
```
### Argument notes
| Argument | Required | Notes |
|----------|----------|-------|
| `specialist_profile` | ✅ | One of the 11 known profiles (see below). |
| `topic` | ✅ | Short slug. Used in the briefing filename. |
| `summary` | recommended | LLM-curated; max 300 tokens recommended. |
| `recent_turns` | optional | Auto-trimmed to `include_recent_turns`. |
| `decisions` | optional | Free-form bullet points. |
| `artifacts` | optional | File paths or other references. |
| `return_condition` | optional | Default `user_request`. |
| `handover_reason` | optional | Logged in the briefing. |
| `project_root` | ✅ | Must be absolute. Used for the briefing file path. |
| `max_context_tokens` | optional | Default 3000. |
| `include_recent_turns` | optional | Default 5. |
---
## Known specialist profiles
The tool accepts only the following profile names. This is an explicit
allow-list (defence-in-depth): a typo in the profile name produces a clear
`ERROR` response, not a silent miss.
- `a0_software_orchestrator`
- `codebase_explorer`
- `implementation_engineer`
- `quality_reviewer`
- `release_auditor`
- `requirements_analyst`
- `runtime_devops_engineer`
- `security_data_engineer`
- `solution_architect`
- `test_debug_engineer`
- `hacker`
`frontend_designer` is **not** a known profile in Phase 1. It is on the
roadmap for Phase 2.
---
## Return value
The tool returns a JSON object with three top-level keys:
```json
{
"status": "ok",
"persona_marker": "[frontend designer]",
"package": {
"specialist": "frontend_designer",
"topic": "landing-page-hero",
"summary": "...",
"briefing_file": "/abs/path/.a0proj/handover/frontend-designer-landing-page-hero-2026-06-05.md",
"estimated_tokens": 2143,
"max_context_tokens": 3000,
"oversize_warning": false
},
"briefing": {
"path": "/abs/path/.a0proj/handover/frontend-designer-landing-page-hero-2026-06-05.md",
"existed_before": false,
"newly_created": true,
"size_bytes": 1789
},
"next_step": "Orchestrator: review the package, then call_subordinate(...)"
}
```
If the package exceeds `max_context_tokens`, a `WARNING:` line is appended
to the response so the orchestrator can decide whether to truncate.
---
## Errors
The tool never raises an unhandled exception. All error paths return a
`Response(message="ERROR: …", error=True)` so the orchestrator can decide
how to react.
Common error cases:
| Error | Cause |
|-------|-------|
| `specialist_profile is required` | missing or empty |
| `unknown specialist profile` | not in the allow-list |
| `topic is required` | missing or empty |
| `project_root is required` | missing or empty |
| `project_root must be absolute` | relative path |
| `max_context_tokens must be positive` | ≤ 0 |
| `failed to append briefing file` | OSError (permissions, disk full, …) |
---
## What the tool does NOT do (Phase 1 limits)
- ❌ Does **not** call `call_subordinate()`. The orchestrator is expected to
do that in a follow-up reasoning step.
- ❌ Does **not** LLM-summarise the older turns. The orchestrator must pass a
pre-computed `summary` argument.
- ❌ Does **not** update the `state_store`. A future phase will add a
`state_store.snapshot()` call before the briefing is written.
- ❌ Does **not** modify the chat loop or any framework core.
- ❌ Does **not** expose a UI persona marker yet. Phase 3 will add the
`🖌️ Designer` style marker to the chat output.
---
## Phase-2 plan (forward-looking)
- `request_full_history()` tool for specialists (stage 2).
- `call_subordinate()` wired into the orchestrator flow with persona marker.
- Loop guard: `max_handover_depth = 3` to prevent bouncing.
- Integration with `state_store.snapshot()` for crash safety.
- Add `frontend_designer` (and any other missing) profile to the allow-list.
- UI persona marker in the webui chat output.
---
## Related files
- Helper: `helpers/handover_protocol.py`
- Helper: `helpers/briefing_file.py`
- Tool: `tools/handover_to_specialist.py`
- Spike design doc: `/usr/workdir/handover-spike.md`
- Memory-protection rules: enforced inside `handover_protocol.py`
(no mid-subagent compaction, no overwrite, briefing ≠ chat history).
+36
View File
@@ -0,0 +1,36 @@
---
name: library-extractor
description: Extract patterns from completed project artifacts into the self-learning patterns library.
tags: ['library', 'extract', 'learning']
---
# Library Extractor
## Purpose
Capture reusable patterns from completed project work and store them in the patterns library for future reuse.
## When to Use
- After a major project milestone
- When a novel design decision is made
- When an error is resolved with a non-obvious solution
- When a best practice is discovered
## When Not to Use
- For trivial implementations (CRUD, boilerplate)
- For project-specific code (not reusable)
- For incomplete work (wait for validation)
## Procedure
1. Identify the pattern: what worked, why it worked, when to reuse it
2. Categorize: architecture_decision, best_practice, error_solution, design_pattern, etc.
3. Capture: title, description, content (with code if relevant), tags, project_id
4. Call the library-extractor API:
```
POST /api/plugins/a0_software_orchestrator/library_extract
{"title": "...", "description": "...", "category": "...", "content": "...", "tags": [...], "project_id": "..."}
```
5. Verify the pattern was stored (check via library-query)
## See Also
- Help: `library/query.md`
- API: `/api/plugins/a0_software_orchestrator/library_extract`
+37
View File
@@ -0,0 +1,37 @@
---
name: library-query
description: Query the patterns library for relevant patterns, best practices, and known errors.
tags: ['library', 'query', 'search']
---
# Library Query
## Purpose
Find relevant patterns from the self-learning library before starting work, to avoid reinventing solutions and to apply known best practices.
## When to Use
- At the start of any new project or task
- When designing architecture for a new feature
- When debugging an error (find prior solutions)
- When planning a phase
## When Not to Use
- For trivial questions (just ask)
- For project-specific state (read the project files)
## Procedure
1. Formulate query keywords: technology, problem type, domain, project type
2. Call the library-query API:
```
GET /api/plugins/a0_software_orchestrator/library_search?q=<keywords>
```
3. Review top results by relevance
4. For each relevant pattern, read the full content via:
```
GET /api/plugins/a0_software_orchestrator/library_get?id=<pattern_id>
```
5. Apply the pattern to the current work, citing the pattern_id
## See Also
- Help: `library/extract.md`
- API: `/api/plugins/a0_software_orchestrator/library_search`
+36
View File
@@ -0,0 +1,36 @@
---
name: context-budgeting
description: Manager context small, raw data to files, token estimation workflow for the orchestrator agent.
tags: ['management', 'context', 'tokens']
---
# Context Budgeting
## Purpose
Keep the main agent's context small by storing raw data in files and using includes/references instead of inline data.
## When to Use
- When a tool returns more than 80 lines of text
- When the user provides large files for processing
- When the conversation history grows large
- When a subordinate returns a long report
## When Not to Use
- For short tool outputs (< 30 lines)
- For data that must be reasoned about inline
## Procedure
1. Receive large output from tool or subordinate
2. Save to a file (e.g., /a0/usr/workdir/<name>.md)
3. Reference the file in the response: `See §include(/path/to/file.md)`
4. Optionally summarize the file in a few lines for context
5. Use raw file only when deep analysis is needed
## Token Estimation Rule
- 1 line of code/markdown ≈ 10-20 tokens
- 80 lines of tool output ≈ 1000-1500 tokens
- 1000 lines of conversation ≈ 15000-20000 tokens
- Compress when output exceeds 1000 tokens
## See Also
- Tool: `context_compactor` (plugin tool for structured compression)
+38
View File
@@ -0,0 +1,38 @@
---
name: error-tracking
description: Known errors lifecycle management and recovery for the orchestrator agent.
tags: ['management', 'errors', 'tracking']
---
# Error Tracking
## Purpose
Track known errors across sessions, document their root cause and solution, and reuse the knowledge for future occurrences.
## When to Use
- When a tool or subordinate returns a persistent error
- When a code block fails compilation or tests
- When the agent encounters an unknown error
- After resolution to log the solution
## When Not to Use
- For transient network blips (retry once, then log)
- For user input errors (request clarification instead)
## Procedure: Error Logging
1. Capture full error output (stack trace, message, context)
2. Search the library for similar past errors (use library-query)
3. If a similar error exists, apply the documented solution
4. If new error, document: title, symptom, cause, fix, tags, project_id
5. Extract to library (use library-extractor) for future reference
## Procedure: Resolution
1. Apply minimal targeted fix
2. Run tests to verify
3. Commit the fix
4. Update error entry with resolution status
## See Also
- Help: `library/extract.md`
- Help: `library/query.md`
- Tool: `error_handler` (if available in plugin)
+40
View File
@@ -0,0 +1,40 @@
---
name: tool-governance
description: Tool registry, capability checks, and fallback handling for the orchestrator agent.
tags: ['management', 'tools', 'registry']
---
# Tool Governance
## Purpose
Maintain a registry of available tools, verify capabilities before use, and define fallback behavior when a tool is unavailable.
## When to Use
- Before invoking any tool for the first time
- When a tool returns an unexpected error
- When the agent needs to discover what tools exist
- During phase transitions
## When Not to Use
- For well-known core tools (terminal, browser, code execution)
- For tools just confirmed working in this session
## Procedure: Tool Discovery
1. Use the `tool_registry` plugin tool to list available tools
2. Read tool documentation from help/<topic>/help.md
3. Note required inputs, expected outputs, error modes
## Procedure: Capability Check
1. Verify the tool exists in registry
2. Verify all required inputs are available
3. Verify the tool is enabled (not toggled off)
4. If any check fails: see Fallback
## Procedure: Fallback
- Tool not found: use `capability_check` to find closest alternative
- Tool disabled: ask user to enable or use alternative
- Tool errors persistently: delegate to test_debug_engineer for diagnosis
## See Also
- Plugin tool: `tool_registry`
- Plugin tool: `capability_check`
+39
View File
@@ -0,0 +1,39 @@
---
name: deployment-basics
description: Deployment documentation, environment setup, runbook, and rollback basics.
tags: ['operations', 'deployment']
---
# Deployment Basics
## Purpose
Standardize deployment operations: environment documentation, runbook creation, rollback procedures.
## When to Use
- Before any production deployment
- When setting up a new environment
- After a release for handoff
- When rollback is needed
## Procedure: Environment Setup
1. Document required variable names from safe sources only (`.env.example`, docs, schemas, compose placeholders, Coolify redacted status). Do not read live `.env`, runtime env dumps, credential stores, shell history, or logs to discover secret values.
2. Document required system dependencies
3. Document required network access (ports, domains)
4. Create env.example file with placeholders
## Procedure: Runbook
1. Pre-deploy: verify env, run tests, backup current state
2. Deploy: step-by-step commands with expected output
3. Post-deploy: health check, optional public reachability test, bounded error-log review
4. Rollback: revert steps, restore backup, verify
## Procedure: Rollback
1. Identify the last known good state
2. Revert code (git checkout <tag>)
3. Restore database (if schema changed)
4. Verify health and public reachability tests; skip authenticated tests unless user-provided test account exists for this task
5. Document rollback reason in worklog
## See Also
- Tool: `deployment_runner` (if available in plugin)
- Help: `operations/runtime.md`
+32
View File
@@ -0,0 +1,32 @@
---
name: git-workflow
description: Git discipline for plugin development - branch, commit after logical blocks, no main push without approval.
tags: ['operations', 'git']
---
# Git Workflow
## Purpose
Enforce git discipline: branch, commit after logical blocks, no push to main without explicit user approval.
## When to Use
After each implementation block or when project state files are updated.
## When Not to Use
When git is not available or the project is not yet a git repository.
## Procedure
1. Check git availability (`which git`)
2. Ensure working on feature branch (`git branch --show-current`)
3. Stage changed files (`git add <files>`)
4. Write descriptive commit message (docs:, feat:, test:, deploy:)
5. Commit changes (`git commit -m "..."`)
6. Do NOT push to main without explicit user approval
7. Update .a0/worklog.md with commit reference
## Quality Gates
Commit after logical blocks, no main push without approval, descriptive messages.
## See Also
- Tool: `git` (core Agent Zero tool)
- Skill: `git-workflow` (global)
+36
View File
@@ -0,0 +1,36 @@
---
name: runtime-verification
description: Start app, bounded error-log review and healthcheck workflow for the runtime_devops_engineer. Browser/UI checks are opt-in and public-only by default.
tags: ['operations', 'runtime', 'verification']
---
# Runtime Verification
## Purpose
Verify the application actually starts, responds to health checks, and behaves correctly before declaring a build successful.
## When to Use
- After implementation completes
- Before declaring a build successful
- After deployment for health/reachability testing
- During debugging of startup issues
## Procedure
1. Discover start command (package.json scripts, Makefile, docker-compose)
2. Start the app in background or as a service
3. Wait for startup completion (configurable timeout)
4. Check health endpoint (GET /health, /api/health, etc.)
5. Capture bounded runtime error output only; never search logs for credentials, cookies, tokens, session data or login material
6. Optional public browser reachability check only after explicit user approval; do not attempt login or authenticated access
7. Stop the app gracefully
8. Return structured handoff
## Quality Gates
- App starts without errors (no ImportError, no 500)
- Health endpoint returns 200
- Bounded error output shows no critical errors
- Public reachability test passes (if applicable); authenticated UI tests are skipped unless the user provides a test account in the current task
## See Also
- Tool: `browser` (optional public reachability only; never for credential discovery or login attempts)
- Help: `operations/deployment.md`
+37
View File
@@ -0,0 +1,37 @@
---
name: test-validation
description: Use existing test/build tooling for validation - no invented commands.
tags: ['testing', 'validation', 'ci']
---
# Test Validation
## Purpose
Run the project's existing test and build tooling to validate a change, without inventing new commands.
## When to Use
- After any implementation block
- Before declaring a feature complete
- Before a release
- When verifying a bug fix
## When Not to Use
- When no test framework exists (create one first, see implementation_engineer)
- For purely documentation changes (no test needed)
## Procedure
1. Discover test framework from package.json, requirements.txt, Makefile, etc.
2. Discover build command from the same files
3. Run tests using the discovered command (e.g., `npm test`, `pytest`, `make test`)
4. Run build using the discovered command (e.g., `npm run build`, `make build`)
5. Capture pass/fail counts and detailed failure output
6. If failures, classify and delegate to test_debug_engineer for root cause
## Quality Gates
- Tests pass (no failures, no skips without justification)
- Build succeeds without warnings (or warnings documented)
- Type check passes (e.g., `tsc --noEmit`, `mypy`)
## See Also
- Tool: `terminal` (for running test commands)
- Subagent: `test_debug_engineer`