21 KiB
C5 — FORGEJO → TOLARIA SYNC ARCHITECTURE DESIGN
Datum: 2026-08-26 · Autor: Red Queen · Status: DESIGN — REVIEW / HUMAN_GATE (nicht implementiert) Mission: C5 DESIGN RECONCILIATION + FORGEJO DOCUMENTATION · Modus: STRICT READ-ONLY (Design-Doku, kein Code)
Verbindliches Architektur-Design für die automatische Synchronisation: FORGEJO (MASTER) → TOLARIA (DERIVED KNOWLEDGE) → SEARCH (DERIVED RETRIEVAL INDEX) Dieses Dokument ist die Source-of-Truth-Dokumentation des C5-Designs. Noch nichts gebaut.
0. Ausgangslage (verbindlich)
- C3 KNOWLEDGE MODEL & MIGRATION = DONE (84 Objekte,
object/<FULL_UUID>, role/representation-Split). - C4 SEARCH v1 = DONE — produktiver Search-Service: exact / keyword / metadata. Bewusst NICHT Bestandteil: semantic/vector/hybrid embeddings, pgvector, Qwen.
- Grundarchitektur (darf C5 NICHT umkehren):
- Forgejo = MASTER / SOURCE OF TRUTH
- Tolaria = DERIVED KNOWLEDGE LAYER
- Tolaria Search = DERIVED RETRIEVAL INDEX
- Primäre Richtung:
FORGEJO → TOLARIA → SEARCH. Tolaria/Search dürfen nie konkurrierender Source of Truth werden.
1. Current Baseline (reconciled 2026-08-26)
| Komponente | Live-Befund (EVIDENCE) |
|---|---|
| Forgejo (Master/SoT) | nexo312/trading-system-docs, HEAD 4122bdd (Rain: fix(tolaria-search): repair admin rebuild source path), v8.0.3+gitea-1.22.0 |
| Tolaria (Derived) | /app/vault, 84 Objekte, HTTP-API :5173/api/vault/* |
| Search (Derived Retrieval) | C4B, Port 8325, 84 Objekte, exact/keyword/metadata, Health: index_built=true, object_count=84, integrity_ok=true, secret_blocked=0, source_head=35446c03… |
| Vorhandener Sync-Code im Repo | KEINER — nur tolaria/FORGEJO_TOLARIA_SYNC_PRINCIPLE.md (Doku, „NICHT IMPLEMENTIERT") |
| Webhooks | KEINE eingerichtet |
| Automation | a2–a5 = Red-Queen-Orchestrierung (Mission/Heartbeat), kein Knowledge-Sync |
Wiederverwendbare manuelle Basis (C3-Code, NICHT im Repo committet):
Forgejo-Write → Verify → Tolaria-Propagation → Read-Back → DRIFT=0(C3D/C3I-Workflow)- Lokale Evidence-Skripte:
/opt/data/c3d_evidence/propagate.py,drift_check.py,build_drafts.py - Tolaria-Write-Pfad:
POST /api/vault/save {"path","content"}(mit/api/vault-Basis, 400 ohne path) - Search-Rebuild:
POST /api/search/rebuild(BearerTOLARIA_SEARCH_REBUILD_TOKEN) bzw. CLIrebuild.py
2. C4 REBUILD STATUS (korrigiert — Reconciliation)
STALE FINDING KORRIGIERT: Der frühere C5-Entwurf nannte den HTTP-Rebuild als defekt (
server.py:25→../c4a_evidence/…). Dieser Punkt wurde inzwischen durch Rain repariert und produktiv verifiziert.
- HTTP_SEARCH_REBUILD_FIX = DONE — Commit
4122bdd(fix(tolaria-search): repair admin rebuild source path),server.py:25jetztos.path.join(os.path.dirname(__file__), "index_source.json"). - C5D_DEPENDENCY_ON_C4_FIX = RESOLVED — kein zukünftiger C4-Fix mehr als offene Voraussetzung.
- Live-Verifikation (Red Queen):
- HTTP-Rebuild ohne Token → 403 ✅ (live gemessen)
- HTTP-Rebuild mit autorisiertem Token → 200 SUCCESS, indexed=84, blocked=0, integrity_ok=true — Rain-Claim, von Red Queen NICHT selbst live getestet (Token nicht in Env/Config verfügbar). Code-Fix committet + Pfad korrigiert = stützt den Claim, aber die 200-mit-Token-Antwort ist UNVERIFIZIERT durch Red Queen (Verifikationsgrenze).
3. Architektur-Entscheidungen (APPROVED DESIGN DIRECTION)
| Entscheidung | Wert |
|---|---|
| EVENT SOURCE | Forgejo API/Git Polling — kein Webhook in v1 |
| DEFAULT POLLING | 60 Sekunden als Startwert. Konfigurierbar, nicht hart architektonisch festschreiben. |
| CONSISTENCY UNIT | ein Forgejo Commit (atomar) |
| ORDER | Forgejo Commit → Tolaria Propagation → Tolaria Read-Back → DRIFT=0 → Search Full Rebuild → Search Health → last_applied_commit |
| SEARCH UPDATE | Full Rebuild nach relevantem Commit. Kein Incremental Search Update in v1. |
| DEPLOYMENT | eigener C5 Sync Service / Container. NICHT: Search-Container, Tolaria-Container, Agent, Trading-System-Modul. |
4. Agent Boundary (verbindlich)
AGENT → schreibt autorisiert AUSSCHLIESSLICH nach FORGEJO
C5 → propagiert deterministisch nach TOLARIA
C5 → aktualisiert danach SEARCH
NICHT: Agent → Forgejo, Agent → Tolaria, Agent → Search (einzeln).
Dadurch bleibt Forgejo einziger Master und Split-Brain wird vermieden.
5. TOLARIA WRITE SECURITY — OPEN SECURITY GATE
SECURITY DEBT (real, im Design festzuhalten):
POST /api/vault/saveist unauthentifiziert.
- Drift Detection ist KEIN Ersatz für Zugriffskontrolle.
- Vor späterer Hermes-Autonomie muss entschieden werden:
- A) Tolaria Write API authentifizieren
- B) Write API netzseitig so isolieren, dass nur der C5-Service schreiben kann
- C) andere nachweislich gleichwertige Zugriffskontrolle
- Noch NICHT härten. Aber als
PRE_HERMES_SECURITY_GATEkennzeichnen.
6. C5 Human Gates
AUTO zulässig:
- normale Content Changes
- Metadata Changes
- Tags
- current/historical State Change
- Rename/Move bei stabiler ID
- eindeutig valide Source/Canonical-Paare
- Search Full Rebuild
HUMAN GATE / FAIL CLOSED:
- ID Collision
- unexpected Tolaria Drift
- Schema Violation
- unknown object_id
- dangling derived_from
- ambiguous Delete
- unbekannte Legacy Objects
- unklare Source/Canonical-Beziehung
- Security/Auth-Anomalie
7. Delete Policy
- Keine automatischen Hard Deletes in C5 v1.
- Delete/Supersede bleibt besonders kontrolliert.
- Bevorzugt:
state/tombstone/supersededgemäß Governance. - Ambiguität → HUMAN GATE.
8. Change Model
| Änderung | Tolaria-Aktion | Search-Aktion | Validierung | Idempotenz | Failure |
|---|---|---|---|---|---|
| NEW OBJECT | save anlegen |
Full Rebuild | Schema-valid, ID einmalig | save→read-back | FAIL_CLOSED |
| CONTENT CHANGE | save überschreiben (Master-Kopie) |
Full Rebuild | body-integrity vs Master | Re-Write | FAIL_CLOSED |
| METADATA CHANGE | save (FM-Felder) |
Full Rebuild | Enum (type/role/rep/state) | Re-Write | FAIL_CLOSED |
| STATE CHANGE | FM state aktualisieren |
Full Rebuild | current/historical | Re-Write | FAIL_CLOSED |
| RENAME | path+aliases aktualisieren | Full Rebuild | ID stabil | save neu + alt | FAIL_CLOSED |
| MOVE | path ändern, aliases erhalten | Full Rebuild | ID stabil | save neu | FAIL_CLOSED |
| DELETE | → state=archived/Tombstone (kein Hard Delete ohne Gate) |
Full Rebuild | Governance-Nachweis | Tombstone idempotent | Human-Gate |
| SUPERSEDE | state=superseded, supersedes-Relation |
Full Rebuild | Nachfolger existiert | idempotent | FAIL_CLOSED |
| SOURCE/CANONICAL REL CHANGE | derived_from aktualisieren |
Full Rebuild | keine Dangles | geordnet (Source zuerst) | FAIL_CLOSED |
| TAGS CHANGE | FM tags |
Full Rebuild | — | Re-Write | FAIL_CLOSED |
9. Identity Model
- C3-Regel verbindlich:
object/<FULL_UUID>, ID immutable. Rename/Move/Content-Change ändern NIE die ID. - C5 erkennt Objekte primär über
object_id, nicht über path. Frontmatterid:extrahieren, bei jedem Event mit dem Forgejo-Index abgleichen. - Path ist ein Alias/Lookup-Sekundärschlüssel, nie Primärschlüssel. Rename/Move pflegen
aliases/Alt-Pfad-Lookups. - Legacy-Ausnahmen (README ×2, vps.md deferred): separat behandeln,
KEEP_DISTINCT/DEFERRED— C5 darf diese nicht zusammenführen oder neu-vergeben. - Keine ID-Neuvergabe bei Collision → Human-Gate.
10. Source/Canonical Policy
representation=source/canonical/standalone(C3-Split, verbindlich).- Keine dangling
derived_from: nur setzen, wenn die referenzierteobject_idbereits produktiv existiert (Policy B). - Atomare/geordnete Regel bei Paar-Änderung (Root+Canonical): in einer Commit-Einheit synchronisieren — zuerst Source (Root,
derived_fromleer), dann Canonical (derived_from=Root-ID), nach Source-Existenz-Nachweis. C3B-PAIRED-Muster wiederverwenden. - Read-Back + DRIFT=0 pro Paar.
11. Polling & Commit Processing
- Polling: Forgejo-API/Git-Polling, Default 60s, konfigurierbar. Pollt
HEAD/git logseitlast_applied_commit. - Verarbeitung pro Forgejo-Commit (atomare Einheit), nicht pro Datei. Ein Commit mit mehreren Dateien (Root+Canonical, Migration) = eine Transaktion.
- Alle Änderungen eines Commits gegen Tolaria propagieren, bevor Search aktualisiert wird.
- Commit wird erst als
appliedmarkiert, wenn Tolaria-Read-Back für alle betroffenen Objekte + DRIFT=0.
12. Idempotency Model
- Sync-Identity:
(commit_sha, object_id, operation)— stabil und deterministisch. ALREADY_APPLIED: wenncommit_sha <= last_applied_commitoder die Ziel-object_idbereits die identischecontent_hash/metadata_hashträgt → skip (kein Doppel-Write, kein Fehler).- Tolaria-
save+ Read-Back ist naturgemäß idempotent (gleicher Inhalt → gleicher Hash).
13. Ordering Policy
| Szenario | Verhalten |
|---|---|
| B vor A verarbeitet | Commit-Reihenfolge erzwungen; C5 verarbeitet nur last_applied..HEAD in git-log-Ordnung; out-of-order → zurückstellen |
| Webhook doppelt | Idempotenz via commit-SHA: ALREADY_APPLIED → skip |
| Webhook verloren | Unkritisch bei Polling — HEAD-Scan holt alles nach |
| Service offline | Beim Wiederstart: Replay ab last_applied_commit |
| Search vor Tolaria | Verboten — Reihenfolge erzwungen; Search-Update erst nach Tolaria-DRIFT=0 |
Replay/Ordering-Policy: Nur vorwärts, monotone last_applied_commit. Out-of-order Events werden nicht erzwungen, sondern wartend zurückgestellt bis die Vorgänger-Commits angewendet sind.
14. Drift & Conflict Policy
- Vergleichsbasis:
(object_id, content_hash, metadata_hash, source_commit)je Objekt. - DRIFT DETECTED (Tolaria ≠ Forgejo bei einem Feld) → keine blinde Überschreibung. Reconciliation / Alert / kontrollierter Repair.
- EXPECTED DERIVED CHANGE (C5 selbst hat geschrieben, Read-Back = Master) → kein Konflikt.
- UNEXPECTED TOLARIA MUTATION (Tolaria ≠ Master, ohne dass C5 schrieb, z. B. über unauthentifizierten
saveoder UI) → FAIL CLOSED: Evidence erfassen, kein automatisches Überschreiben, Human Review (C3-CONFLICT-Prinzip).
15. Tolaria Propagation Model
- Wiederverwenden:
propagate.py-Muster (C3D) —POST /api/vault/savemit/api/vault-Basis, per Datei Write → Read-Back → Hash-Match, dann DRIFT=0. - Kein Blind-Batch; pro Objekt verifizieren. Frontmatter erhalten (
_organized,knowledge_schema,id,derived_from).
16. Search Rebuild Model
- Full Rebuild nach relevantem Commit (v1). ~84 Objekte, stdlib-only, <1s — Einfachheit schlägt Incremental.
- Kein Incremental Search Update in v1.
- HTTP-Rebuild-Pfad funktioniert (C4-Fix
4122bddcommittet; ohne Token 403, mit Token 200 laut Rain — Red-Queen-Verifikationsgrenze siehe §2).
17. Search Ordering (verbindlich)
Forgejo-Commit bestätigt
→ Tolaria aktualisieren (per Objekt)
→ Tolaria Read-Back → DRIFT=0
→ Search Full Rebuild
→ Search Health (object_count=84, supported_modes, integrity_ok)
→ Sync Event DONE (last_applied_commit fortschreiben)
Prinzip: Search zeigt nie einen Stand, den Tolaria nicht erreicht hat.
18. Failure Matrix
| Fehler | Verhalten | Retry | Rollback | Queue | Human Gate |
|---|---|---|---|---|---|
| Forgejo unavailable | FAIL CLOSED, keine Propagation | Backoff-Retry | — | pending (HEAD unbekannt) | nach Max-Retry |
| Tolaria unavailable | FAIL CLOSED, Search nicht updaten | Backoff-Retry | — | Commit pending | nach Max-Retry |
| Search unavailable | Tolaria evtl. schon propagiert; Search-EVENT pending | Backoff-Retry | — | Search-Step pending | nach Max-Retry |
| Auth failure | FAIL CLOSED | wenige | — | — | Alert |
| Network timeout | FAIL CLOSED | Backoff | — | — | nach Max |
| Malformed Frontmatter | FAIL CLOSED pro Objekt | nein | Objekt nicht anwenden | Rest des Commits? → commit-atomic | Alert |
| Invalid knowledge_schema | FAIL CLOSED | nein | skip Objekt | — | Alert |
| Unknown object_id | FAIL CLOSED | nein | skip | — | Alert |
| ID collision | FAIL CLOSED | nein | skip | — | Human Gate |
| dangling derived_from | FAIL CLOSED | nein | skip bis Source existiert | geordnet | Alert |
| partial commit processing | FAIL CLOSED — Commit nicht als applied markieren | Replay ab unvollständigem | — | — | — |
| Tolaria drift (unexpected) | FAIL CLOSED | nein | kein Überschreiben | — | Human Review |
| Search rebuild failure | FAIL CLOSED — Event nicht DONE | Backoff | Tolaria bleibt korrekt | — | Alert |
| duplicate event | Idempotent (ALREADY_APPLIED) | — | — | — | — |
| out-of-order event | zurückstellen bis Vorgänger | — | — | wartend | — |
| delete ambiguity | FAIL CLOSED | nein | kein Delete | — | Human Gate |
19. Retry Policy
- Begrenzte Retries (z. B. 3–5) mit exponentiellem Backoff (1s→2s→4s…). Kein Endlos-Loop.
- Nach Max-Retry → DEAD/FAILED STATE für das Event: Evidence (Log-Eintrag, Payload, commit_sha), Alert an Operator,
last_errorsetzen. Keine stille Aufgabe. - Ein DEAD-Event blockiert nicht die Queue, wird aber bis Human-Review nicht übersprungen (oder explizit
FAILEDmarkiert mit Human-Review-Pflicht).
20. Recovery / Replay Model
- Persistenter
last_applied_commit(Single Source of Truth für Fortschritt). - Replay ab Commit: Beim Start/Recovery alle Commits
last_applied_commit..HEADerneut verarbeiten (idempotent). - Full reconciliation: auf Anforderung/Drift — alle 84 Objekte Master↔Tolaria↔Search vergleichen, Drift melden, nicht blind neu schreiben.
- Search rebuild: Full Rebuild ist Teil des Normalwegs (§16).
21. Bootstrap Model
Beim ersten Start: Reconciliation zuerst, kein „alles neu schreiben".
- Forgejo-HEAD lesen.
- Tolaria-IST-Stand lesen (84 Objekte).
- Search-IST-Stand lesen.
- Reconciliation Master↔Tolaria: nur identifizierte Abweichungen, mit Drift-Policy (§14), nicht blind propagieren.
- Danach
last_applied_commit = aktueller Forgejo-HEADals Baseline setzen (nur wenn Reconciliation sauber / Abweichungen dokumentiert + behandelt). - Erst dann Normalbetrieb.
22. Security Model
- Minimal-Prinzip: C5 bekommt nur, was nötig ist.
- Forgejo: READ-Token/Polling (Sync-Reader) — kein WRITE (C5 schreibt nie nach Forgejo).
- Tolaria: nur erforderlicher Derived-Write (save) — unvermeidbar, aber isoliert + Drift-watch.
- Search: nur
TOLARIA_SEARCH_REBUILD_TOKEN(Bearer).
- Keine Tokens im Repo, in Logs, in Reports, im Image. Secrets via Env/Secret-Manager, ephemer.
- FINDING (bestehend): Tolaria-
saveist unauthentifiziert → PRE_HERMES_SECURITY_GATE (§5); bis dahin Drift-Watch als Kompensation.
23. Observability & Health
Observability (minimal, keine Content-/Secret-Logs):
last_seen_commit · last_applied_commit · sync_status · objects_changed · tolaria_drift · search_status · retry_count · last_error · last_success_at
Health Contract:
status · forgejo_reachable · tolaria_reachable · search_reachable · last_seen_commit · last_applied_commit · pending_commits · failed_commits · drift_count
24. Resource Budget
- VPS-Bewertung: sehr klein. CPU/RAM: <0.5 CPU, <128MiB (Python + Polling + 84-Obj-Diff). Disk: minimal (kein Vault-Kopie-Volume nötig — nur derived Index + State). Netzwerk: nur Polling-Intervall + Propagate-Requests (niedrig).
- Kein LLM, keine Embeddings, keine Vector-DB (C5 ist reiner Sync, kein Retrieval).
25. Deployment Model
RECOMMENDED_ARCHITECTURE: eigener C5-Sync-Container — isolierte Failure Domain (Ausfall von C5 beeinträchtigt weder Search noch Tolaria), isolierte Secrets, eigener Recovery/Replay, agentenunabhängig, konsistent mit dem C4-Architekturprinzip (eigene Domain je Service).
NICHT: Search-Container, Tolaria-Container, Agent, Trading-System-Modul.
26. Test Plan (C5-Testkorpus)
new object · content edit · metadata edit · rename · move · state change · paired source/canonical · delete · supersede · duplicate event (idempotenz) · lost event/replay · out-of-order · Tolaria down · Search down · drift (unexpected mutation) · invalid schema · secret safety · ID collision · dangling derived_from.
27. Canary Plan
Sicherer C5-Canary: eigens erzeugtes Test-Knowledge-Object (Governance-erlaubt), keine kritischen Trading-Dokumente. Rollbackbar (Forgejo-Revert + Tombstone). Ablauf: Test-Object in Forgejo → C5 propagiert → Tolaria-Read-Back → Search → Health → Rollback → Drift=0. In dieser Mission NICHT ausgeführt (STRICT READ-ONLY).
28. Implementation Phases
| Phase | Inhalt |
|---|---|
| C5A | Contract & State-Machine (Events, Zustände, last_applied_commit, FAIL/DEAD) |
| C5B | Sync-Engine (Polling, Diff, Change-Detection, Idempotenz, Ordering) |
| C5C | Tolaria-Propagation (Wiederverwendung C3-propagate.py-Muster, Drift, Read-Back) |
| C5D | Search-Integration (Full-Rebuild nach Commit, Health) — C4-Fix bereits RESOLVED |
| C5E | Failure/Replay/Recovery + Observability + Health-Contract |
| C5F | Canary (§27) |
| C5G | Acceptance (Exit-Criteria + Fresh Checker + CC-Close) |
29. C5 Exit Criteria
- Forgejo bleibt Master (kein Rückschreib) ✓
- Deterministische Propagation (Forgejo→Tolaria→Search) ✓
- Idempotent (doppelte Events = ALREADY_APPLIED) ✓
- Ordering-safe (Commit-Reihenfolge, out-of-order zurückgestellt) ✓
- Replaybar (last_applied_commit, Replay nach Ausfall) ✓
- Drift-aware (Erkennung, kein blindes Überschreiben) ✓
- Fail-closed bei Konflikten/unexpected drift ✓
- Search erst nach Tolaria (kein vorzeitiger Search-Stand) ✓
- Keine dangling relations (derived_from-Policy) ✓
- Keine ID-Neuvergabe ✓
- Keine Secrets in Logs/Reports/Image ✓
- Recovery getestet (Replay + Full-Reconciliation) ✓
- Canary PASS ✓
30. Hermes Handoff
Was kann Hermes NACH C5 sicher tun, was er VOR C5 nicht sicher tun sollte? Nach C5 kann Hermes autorisiert nach Forgejo schreiben und sich darauf verlassen, dass die Propagation nach Tolaria + Search deterministisch, idempotent und in richtiger Reihenfolge erfolgt — ohne dass Hermes selbst die Vault-API oder Search-Rebuild improvisieren muss. Das beseitigt das heutige Risiko von (a) vergessener/inkonsistenter Propagation, (b) unkoordinierten Direkt-Schreiben nach Tolaria (Split-Brain), (c) manueller Fehleranfälligkeit.
Was fehlt danach noch für echte Hermes-Autonomie?
- Autorisierter Write-Zugang von Hermes nach Forgejo (Gate/Token) — noch nicht eingerichtet.
- Human-Gate-Freigabe für autonome Wissens-Mutationen (C5-Deployment + Hermes-Schreibberechtigung).
- Ein Agent-Write-Policy/Approval-Gate, das festlegt, was Hermes autonom schreiben darf vs. Human-Review.
- Produktives Deployment von C5 (nicht nur Design) + Canary-PASS.
- PRE_HERMES_SECURITY_GATE (§5): Tolaria-Write-Zugriffskontrolle entscheiden, bevor Hermes autonom schreibt.
Hermes-Autonomie NICHT implementiert — nur Handoff analysiert.
31. PRE_HERMES_SECURITY_GATE
Verbindlich vor jeder Hermes-Autonomie: Der unauthentifizierte
POST /api/vault/saveist reale Security Debt. Drift Detection ist KEIN Ersatz für Zugriffskontrolle. Entscheidung nötig: A) Tolaria Write API authentifizieren · B) Write API netzseitig isolieren (nur C5-Service) · C) andere nachweislich gleichwertige Zugriffskontrolle. Noch NICHT härten. Gate bleibt offen bis Christian entscheidet.
32. Open Questions
- C5-Deployment-Container: welcher Executor/Host-Zugang (wie C4)?
- Tolaria-
save-Härtung (Auth/Whitelist) vor oder mit C5? (PRE_HERMES_SECURITY_GATE) - Polling-Intervall (Default 60s) — akzeptabel? (konfigurierbar)
- Soll Hermes einen Write-Zugang nach Forgejo erhalten (Phase 2)?
- HTTP-Rebuild-200-mit-Token: von Red Queen nicht selbst live getestet (Token nicht verfügbar) — Verifikation durch autorisierten Executor empfohlen.
33. Command Center Recommendation (nicht gesetzt)
C4= DONEC5 DESIGN= REVIEW / HUMAN_GATEC5 IMPLEMENTATION= PENDING- NEXT: C5 Human Gate / C5A Contract & State Machine
- C5 NICHT DONE. Keine Implementierung starten.
Ende des C5 Sync Architecture Design. Status: DESIGN — REVIEW / HUMAN_GATE. Kein Code, kein Container, kein Poller, kein Webhook, kein Tolaria-Write.