9.7 KiB
| id | type | role | representation | state | knowledge_schema |
|---|---|---|---|---|---|
| object/eb0ef2f8-1ed9-aaf1-1afb-2fdbdaa15c74 | arch | module | canonical | current | 1 |
Modul-16: Paperclip (Agent-Orchestrierungsebene)
Status: FREIGEGEBEN (21.08.2026) · Container Modul-16-Paperclip · Image trading-modules-modul16-paperclip:latest
⚠️ Achtung Namenskollision: Es existiert ein Fremdsystem
paperclip-dn8l-paperclip-1(Coolify, Hostinger hvps-paperclip) imcoolify-Netz. Dies ist NICHT unser Modul-16. Unser Modul-16 läuft imtrading-modules-Netz alsModul-16-Paperclip. Fremdsystem nie anfassen.
Zweck
Paperclip ist die übergeordnete Agent-/Orchestrierungsebene des Trading-Systems. Er nimmt Research-, Analytics-, Strategieüberprüfungs-, Backtest-, Optimization- und Monitoring-Aufträge entgegen, wählt eine Agent-Rolle (Strategy/Research/Analytics/Validation/System) und führt sie deterministisch aus. Später (V2) können daraus Hermes-Agent-Aufgaben entstehen.
Kritische Grenze: Paperclip ist NICHT Teil des kritischen Trading-Pfads.
- ✅ Er liest READ-ONLY aus Modul-03–15 und startet klar begrenzte, nicht-kritische Writes (Backtest, Optimization).
- ❌ Er DARF KEINE Broker-Orders senden, Modul-09 nicht zur Orderausführung anweisen, Risk-/Portfolio-Regeln nicht überschreiben, M15-Safety nicht überschreiben, Strategien nicht automatisch produktiv aktivieren, Optimierungsparameter nicht automatisch deployen.
- Trading-Core (M03–15) läuft bei komplettem Ausfall von Modul-16 unverändert weiter.
Architektur / Datenfluss
Client/Auftrag
│ POST /tasks (task_type + payload)
▼
Modul-16-Paperclip (Port 55016, NUR intern/expose)
│
├── app/core/orchestrator.py Rollen-Wahl + deterministische Ausführung
├── app/core/proposal_gate.py Proposal-Gate (NIE Auto-APPROVED/aktiviert)
├── app/storage/storage.py Persistenz agent_task/agent_run/agent_proposal/agent_audit
├── app/clients/clients.py Read-Clients + 2 begrenzte Write-Clients
└── app/api/main.py REST-API (/health, /tasks, /proposals)
│
├── Read-Only (tolerant): Modul-03/04/06 (research), M05+M11 (strategy_review),
│ M11 (analytics), M15 (monitoring, NUR GET)
└── Write (begrenzt): Modul-12 POST /backtest, Modul-13 POST /optimization
API (Docker-intern, Port 55016):
GET /health— Liveness ({"status":"ok","service":"paperclip","version":"0.1.0"})GET /health/ready— Readiness (DB + Schema vorhanden) → 200{"status":"ready"}POST /tasks— Auftrag einreichen (validiert; unbekannte/execute_order→ 422)GET /tasks/GET /tasks/{id}— Aufträge + Status/result_refsPOST /tasks/{id}/run— Aufgabe synchron ausführen (erzeugtagent_run)POST /proposals— Proposal als DRAFT erzeugen (APPROVED via Paperclip → 422)GET /proposals/GET /proposals/{id}
Kein RabbitMQ: synchroner request/response. Port 55016 ist nur intern (expose:), kein öffentliches Mapping.
Agent-Rollen (V1, vorbereitet)
| Rolle | task_type | liest | schreibt |
|---|---|---|---|
analytics |
analytics |
Modul-11 (portfolio/strategy/regime) | — |
research |
research |
Modul-03/04/06 | — |
strategy |
strategy_review |
Modul-05 (Strategien) + Modul-11 | — |
validation |
backtest, optimization, validation |
Modul-12/13 | M12 POST /backtest, M13 POST /optimization |
system |
monitoring |
Modul-15 (NUR GET) | — |
Alle Rollen sind per ENABLED_ROLES registriert; es werden nicht unnötig viele aktiviert.
TASK_TO_ROLE mappt task_type → Rolle.
Proposal-Prinzip (ProposalGate)
Wenn Paperclip eine Änderung empfiehlt, wird sie als Proposal gespeichert, niemals direkt angewendet:
STRATEGY_CHANGE_PROPOSAL mit:
proposal_id, source/agent, strategy, aktuelle Version, vorgeschlagene Änderung (JSON),
Begründung (rationale), Analytics-/Backtest-Referenzen, Confidence, created_at, status
Status: DRAFT / PROPOSED / REVIEWED / APPROVED / REJECTED
create_proposalläuft ausschließlich überProposalGate(nurstatus in {DRAFT, PROPOSED}erlaubt).- Paperclip kann
APPROVEDNIE selbst setzen (validiert inproposal_gate.py; API gibt 422). - Proposal wird mit
auto_activated=falsepersistiert — keine automatische Aktivierung. - Keine automatische Übernahme optimierter Parameter in Produktion.
Sicherheit
- Keine öffentlichen Ports: 55016 nur
expose(Docker-intern), kein Host-Mapping. - Internes Docker-Netzwerk
trading-modules. - Secrets nur ENV/Secret (
PG_PASSWORDaus Composeenvironment); keine Secrets in Logs/API/DB. - Keine Broker-Credentials.
- Kein Docker-Socket-/Root-Recht, kein Shell-Zugriff auf andere Container.
- M15-Ausfall kann Paperclip nicht dazu bringen, Safety zu umgehen (Paperclip hat KEINE M15-Control-Write-Methode).
- Paperclip-Ausfall stoppt Trading nicht (eigene DB-Tabellen, kein Einfluss auf Trading-Core).
Persistenz / Audit (Migration migrations/001_paperclip.sql)
agent_task— Aufträge (id, agent_role, task_type, status, payload, result_refs, error_*).agent_run— Ausführungen (run_id, task_id, agent_role, status, result, idempotent).agent_proposal— Vorschläge (proposal_id, source, strategy, proposed_change, rationale, references, confidence, status, auto_activated).agent_audit— lückenloses Audit-Log (actor, action, detail, task_id, run_id, proposal_id).
Jede Agent-Aktion (task_created, run_started, run_succeeded, run_failed, run_rejected, proposal_*) wird in agent_audit protokolliert.
Read-Clients (tolerant)
Einzelne Quellen-Fehler (404/5xx/Timeout) werden über _safe_get als {"_error": code, "_message": …}
Teil-Ergebnis gekapselt → der Gesamt-Task bleibt SUCCEEDED. Nur wenn ein Service komplett unreachable
(UNREACHABLE/TIMEOUT) ist, liefert er None. Write-Aktionen (Backtest/Optimization) bleiben strikt FAILED bei Fehlern.
Ausnahme — Monitoring (FAIL-CLOSED): Der monitoring-Task ruft M15 nicht über _safe_get,
sondern direkt auf. M15 ist die autoritative Trading-Status-Quelle — ist sie nicht erreichbar, wird der
Monitoring-Task FAILED (kein „ok"-Status bei ausgefallenem M15). Bei M12/M13-Ausfall → betroffener
Task (Backtest/Optimization) FAILED, M16 bleibt healthy, Trading-Core unbeeinflusst.
Tests & E2E-Verifikation (VPS, 21.08.2026)
- Unit-Tests
tests/test_paperclip.py: 10/10 grün (ProposalGate-Safety, Task-Validierung, Worker, Idempotenz, Auto-Aktivierungs-Verbot). - Backtest-Flow: M16 → M12
POST /backtest→ SUCCEEDED,agent_run+run_id/result_refskorrekt (kind:"backtest"). - Optimization-Flow: M16 → M13
POST /optimization→ SUCCEEDED,run_id/result_refskorrekt (kind:"optimization"). - Monitoring-Flow: M16 → M15
/monitoring/status(READ-ONLY) → SUCCEEDED, Ergebnis gespeichert. - Research-Flow: M16 → M03/M04/M06 → SUCCEEDED (M04 404 „Kein Regime" als Teil-Ergebnis gekapselt, kein Crash).
- Strategy-Review-Flow: M16 → M05+M11 → SUCCEEDED.
- Proposal: erstellt als
DRAFT/auto_activated=false;APPROVED→ 422. NICHT auto-aktiviert. - Kein M09-Zugriff:
task_type=execute_order→ 422; keinExecutionClient, keine/order-Endpunkte, keinexecution_base_url. - Kein M15-Override: Paperclip hat nur GET-Methoden auf M15, keine Control-Write.
- Ausfall-Toleranz: M12 down → backtest FAILED, M13 down → optimization FAILED, M15 down → monitoring FAILED (FAIL-CLOSED), M15 up → SUCCEEDED. M16 bleibt in allen Fällen healthy, Trading-Core unbeeinflusst, Erholung → SUCCEEDED.
- Idempotenz: erneuter
runerzeugt neuenagent_run, überschreibt frühere Runs nicht. - Ungültige Aufgabe:
task_type=delete_database→ 422. - Keine Secrets in Logs/API:
docker logsfrei von password/secret/token/api_key. - Health/Ready: beide 200.
Bugs / Fixes (modul-16, dokumentiert)
references-SQL-Keyword → Spalte in Migration + Queries als"references"gequoted.- Migration-Commit: psycopg2 braucht
conn.autocommit = True(Muster wie M15), sonst bleiben Tabellen uncommittet →relation agent_task does not existbei/health/ready. Behoben in_connect. - create_task RETURNING-Mismatch: RETURNING listete 7 Spalten,
_task_rowerwartete 10 →IndexError. Behoben: vollständige Spaltenliste. - Research-Einzelfehler-Crash: Einzelne fehlende Quelle (M04 404) failte den ganzen Research-Task.
Behoben:
_safe_getkapselt Einzelquellen-Fehler, Task bleibt SUCCEEDED mit Teil-Ergebnissen. - Monitoring-FAIL-CLOSED (21.08.2026):
monitoring-Task nutzte_safe_get, was M15-UNREACHABLEzuNonekapselte → Task blieb SUCCEEDED trotz ausgefallenem M15. Fix:_monitoringruft M15 direkt auf, damit ein M15-Ausfall alsClientErrorweiterfaellt und der Task FAILED wird. Verifiziert: M15 down → monitoring FAILED, M15 up → SUCCEEDED.
Compose / Betrieb
- Netzwerk
trading-modules, DB-HostModul-01-PostgreSQL(Modul-01), Port 55016 nur intern (expose),restart: unless-stopped. Kein öffentliches Port-Mapping. - Kein Teil des kritischen Trading-Pfads: kein M09-, kein M15-Control-Zugriff.
Geändert
Geändert von: Rain Ocampo
Datum: 21.08.2026
Grund: Modul-16-Paperclip implementiert + E2E verifiziert (Backtest/Optimization/Monitoring/Research/Strategy-Success, Safety 422, ProposalGate, Ausfall-toleranz, Idempotenz). Monitoring-FAIL-CLOSED-Fix: M15-Ausfall -> monitoring-Task FAILED statt SUCCEEDED. Ausfall-Toleranz-E2E (M12/M13/M15 down -> FAILED, healthy) gruen. Image neu gebaut (Fix persistent). FREIGEGEBEN. Modul-17 NICHT begonnen.