Architektur — Ground Truth System

Diese Datei beschreibt, wie das System gebaut ist. Für den Plan der Umsetzung siehe ../PLAN.md. Für gelockte Entscheidungen siehe ../DECISIONS.md.


1. Ziel

Ein zentrales, menschen- und agenten-lesbares Gedächtnis pro Unternehmen, mit verteilten persönlichen Gedächtnissen pro Mensch oder Agent — und bewusster, selektiver Synchronisation zwischen beiden Ebenen.


2. Topologie (N:N)

                    ┌─────────────────────────────────────┐
                    │  Business Brain  "kuble"            │
                    │  ground.kuble.com  (46.225.238.83)  │
                    │                                     │
                    │  • Next.js Web UI + API             │
                    │  • SQLite Metadata                  │
                    │  • Git-Repo (brains/)               │
                    │  • MCP Server                       │
                    │  • Docker + Traefik                 │
                    └─────────────────────────────────────┘
                             ▲                ▲
                             │ HTTPS+API-Key  │
            ┌────────────────┘                └────────────────┐
            │                                                  │
 ┌──────────────────────┐                          ┌──────────────────────┐
 │ Personal Brain       │                          │ Personal Brain       │
 │ gustavo              │                          │ maniak (Agent)       │
 │ Mac Mini             │                          │ Hermes VPS           │
 │                      │                          │                      │
 │ • Next.js + SQLite   │                          │ • Next.js + SQLite   │
 │ • Git-Repo (brains/, │                          │ • Git-Repo           │
 │   soul/private/,     │                          │ • Key-only API login │
 │   soul/business/*)   │                          │                      │
 └──────────────────────┘                          └──────────────────────┘

Kardinalität: N Personals pro Business, ein Personal mit M Businesses. Jede Verbindung ist eine separate, widerrufbare N:N-Relation.


3. Kernkonzepte

Brain

Eine Sammlung von Markdown-Files mit YAML-Frontmatter, versioniert in git, organisiert in Layern. Jedes File ist ein einzelnes Brain-Dokument (oder kurz: "ein Brain").

Layer

  • Slow — stabil, ändert sich selten. Werte, Kultur, Kernwissen, Identität.
  • Rapid — dynamisch, ändert sich ständig. Kunden, Projekte, laufende Arbeit.

Domain

  • Business — dem Unternehmen gehörend. Zentral gehostet.
  • Personal — einer Person oder einem Agent gehörend. Bei ihr/ihm gehostet.

Soul (nur Personal)

  • Private Soul (soul/private/) — persönlich, niemals synced.
  • Business Soul (soul/business/<slug>/) — pro verbundenem Business. Read-only auf Personal-Seite, one-way gepullt vom Business. Für Agents: "Wie verhält sich Maniak, wenn er im Auftrag von Kuble agiert?"

Instance

Eine laufende Einheit des Systems. Entweder vom Typ business oder personal. Hat genau eine Identity (z.B. kuble, gustavo, maniak).

Connection

Eine N:N-Beziehung zwischen einer Business- und einer Personal-Instanz, authentifiziert über API-Key, widerrufbar. Siehe CONNECTIONS.md.


4. Daten-Ebenen

Ebene Wo Format Primär für
Brain-Daten brains/** + soul/** Markdown + Frontmatter Wissensinhalte — die eigentliche Substanz
History .git/ git Change-Tracking + Rollback
Instanz-Metadata .gts/meta.sqlite SQLite Sessions, Admin-Accounts, Connections, API-Keys, Audit-Log, Mirror-Exclusions, OAuth-State, Chat-History
Instanz-Config .gts/config.yaml YAML Instance-Type, Identity, URLs, Feature-Flags

Brain-Daten sind Source of Truth (D1). Metadata ist Service-Zustand — nicht teilbar zwischen Instanzen. Config ist Deployment-Setup.


5. ID-Schema

Jedes Brain hat eine global eindeutige id:

<instance-slug>.<type-short>.<slug>[.<subslug>]

Beispiele:

  • kuble.slow.werte — Werte des Business-Brains kuble
  • kuble.projekt.nori-v3 — Business-Projekt
  • kuble.kunde.beispielgmbh — Business-Kunde
  • gustavo.projekt.nori-v3 — Personals eigene Sicht
  • gustavo.private.tagebuch.2026-q2 — private Notiz
  • gustavo.business.kuble.werte — business-soul aus Kuble gepullt
  • maniak.private.learnings.sync-patterns — Agent-Learning

Der Pfad im Filesystem spiegelt die ID (Linter validiert Konsistenz).


6. Selective Sync

Wer entscheidet was:

  • Business definiert, welche Projekte + Kunden existieren, welche Felder (H2-Sektionen) syncable sind.
  • Personal entscheidet, welche dieser Projekte/Kunden er syncen will und welche Felder davon.

Mechanik:

  1. Personal ruft gts sync <business-slug> (oder Cron).
  2. Personal-Seite sendet Wunsch-Liste: [{brain_id, fields}].
  3. Business validiert: API-Key gültig, Brain existiert, Felder syncable.
  4. Business liefert Content der genehmigten Felder.
  5. Personal merged in lokale Brains (neue Commits, Sync-Trigger in Message).
  6. Personal sendet eigene geänderte Felder zurück (wenn bidirectional).
  7. Business validiert, schreibt, commitet.

Konflikt-Strategie: Wenn beide Seiten denselben Feld-Inhalt seit dem letzten Sync geändert haben, schlägt Sync fehl. User bekommt eine Konflikt-Datei, entscheidet manuell, syncen erneut. Nie automatisches Overwrite.


7. Change Tracking & Rollback

  • Jede CLI/MCP/API-Schreibaktion = 1 atomarer Commit.
  • Commit-Message-Format:
    • brain(<domain>/<layer>/<slug>): <action> — normale Schreibvorgänge.
    • sync(<src>→<dst>): fields=[...] — Sync-Operationen.
    • admin(<action>): <detail> — Admin-Operationen (wenn sie git-Änderungen verursachen; Login/Invite gehen in SQLite audit_log).
  • gts history <brain-id> — lesbarer Wrapper um git log -- <path>.
  • gts revert <commit> — erstellt einen Revert-Commit, History bleibt erhalten.
  • gts snapshot create "<name>" — benannter git-Tag als Savepoint.

8. Sicherheit

Vektor Mechanismus
Transport Business↔Personal HTTPS nur; Let's Encrypt via Traefik auf Business-Server
Auth Business-Admin Email/Passwort + Invite-Flow für weitere Admins (D24)
Rollen admin | member | viewer auf admins.role; last-admin-Guard im UI
Auth Personal-User Username/Passwort oder Google OAuth (Auth.js)
Auth Business↔Personal API-Keys, issued von Admin, revocable (D25)
Admin-Brain Access can_read_admin pro Connection + allowed_users / allowed_connections pro Brain; Remote-Writes auf admin hart blockiert
At-Rest Business-Brain Disk-Encryption auf Server-Host (OS-Verantwortung)
At-Rest Personal-Brain Disk-Encryption auf dem jeweiligen Gerät (User-Verantwortung)
Audit SQLite audit_log (alle Auth/Admin-Ops + MCP-Writes) + git-History (Brain-Ops)
Rate-Limit Auf Auth- und Invite-Endpoints (Phase 4)
Secrets Niemals in Brain-Markdown; .env auf jedem Host; Rotation dokumentiert

Rollen-Modell:

  • admin — Full-Access, darf admin-Kategorie lesen/schreiben, Rollen verwalten, Connections togglen. Mindestens ein Admin pro Instanz (UI-Guard).
  • member — Lesen/schreiben in allen Kategorien außer admin; admin nur lesbar wenn User-Email in allowed_users des Brains steht.
  • viewer — Read-only, sonst gleiche admin-Regeln wie member.

Kein File-Level-Encryption (kein git-crypt) im MVP — D17 supersedet D9.


9. MCP-Integration

Jede Instanz startet einen MCP-Server lokal (packages/mcp/dist/server.js, bin gts-mcp). Agents verbinden sich typischerweise:

  • Mit ihrer eigenen Personal-Instanz (per stdio direkt oder via SSH-bridge)
  • Mit dem Business-Brain über eine Connection + forced-command SSH-Key mit Env-Vars

MCP-Env-Vars für Access-Control (alle optional):

Env Default Effekt
GTS_MCP_ACTOR_EMAIL / GTS_MCP_ACTOR_NAME Instance-Owner Git-Commit-Author für MCP-Writes
GTS_MCP_CALLER_SLUG unset (= trusted-local) Remote-Instanz-Slug. Wenn gesetzt → Access-Checks aktiv.
GTS_MCP_CAN_READ_ADMIN 0 1 erlaubt lesen von admin-Brains (zusätzlich muss Slug in allowed_connections sein)
GTS_MCP_READONLY_CATEGORIES (leer) Komma-separierte Kategorien wo brain_write/brain_capture abgelehnt wird. Typisch: slow

Writes auf admin-Kategorie sind für Remote-Caller (GTS_MCP_CALLER_SLUG != unset) immer hart blockiert, unabhängig von Flags.

Audit-Logging: MCP-Writes schreiben einen Row in audit_log mit source: "mcp", actor: "<email> via <slug>", event: mcp-brain-{create,update,capture}, target: <brain-id>, detail: {commit, wasNoOp}. Sichtbar auf /history in der Audit-Events-Spalte.

Tool-Liste siehe ../PLAN.md §10.


9b. Zwei-Ebenen-Modell für Rohtexte (Source + destilliertes Brain)

Ein langer Text (Meeting-Transkript, Email, Dokument) wird nie direkt in ein projekt/kunde/knowledge-Brain reingeschrieben. Stattdessen zwei Writes:

  1. Source anlegen (category: source) — Body = voller Originaltext 1:1. Pflichtfelder type (meeting/email/transcript/document/chat/call) und date.
  2. Ziel-Brain updaten — neuer Body-Abschnitt mit 3–5 destillierten Bullet Points + sources[]-Array im Frontmatter um die neue Source-ID erweitern.

Dieses Muster ist in Hermes-SOUL und im MCP-Server instructions-Text verankert, damit Agents es konsistent anwenden. Der destillierte Brain bleibt leserlich; die Source ist jederzeit für Volltext-Suche und Originalzitate verfügbar.


10. Nori als Projekt (Migration)

Nori-Plattform-Daten wandern langfristig vom Standalone-Stack in das GTS:

  • Nori-Kunden → kuble.kunde.<slug> Brains
  • Nori-Projekte → kuble.projekt.<slug> Brains
  • Nori-Agent-Konfigs (SOUL.md, MEMORY.md pro Customer) → Personal-Brain-Instanz pro Agent, verbunden mit dem Kuble-Business

Ziel: ein Business ("Kuble"), viele Personal-Agents (einer pro Nori-Customer), die aus dem Business selective ihre Projekt-Brains pullen.

Zeitlich: Phase 7, nach stabilem MVP.


11. Was NICHT zur Architektur gehört

  • Kein Analytics-Cluster. Das System ist Write-Side. Für BI-Dashboards mit aggregierten Daten: separates BI-Tool, das gelegentlich aus git exportiert.
  • Kein Real-Time-Collab. Sync ist pull-basiert. Wenn zwei User gleichzeitig schreiben, zählt git-Merge-Logik.
  • Kein Multi-Org-Admin. Jedes Business ist eine eigene Instanz. Multi-Business-Verwaltung auf Business-Seite ist aus dem MVP ausgeschlossen (aus Personal-Sicht funktioniert Multi-Business via multiple Connections).