Architecture

AI Platform ecosystem architecture — physical layout, domain structure, network topology, data pipeline, and machine cluster
Published

August 24, 2026

This page provides a high-level overview of the AI Platform ecosystem architecture: physical disk layout, domain hierarchy, network traffic flow, PDAI document processing, and the four-machine cluster.


Physical Layout (~/ai-mac-studio/ Umbrella)

All ai-* directories are real directories under ~/ai-mac-studio/ — no Dropbox, no Conda, no PROJECT_BASE. Finder and every CLI tool walk each tree exactly once.

flowchart LR
  subgraph umbrella ["~/ai-mac-studio/"]
    platform["platform/\n(Hub, Proxy, Registry)"]
    agents["agents/\n(Tool Packages)"]
    pdai["pdai/\n(PDAI Pipeline, consolidated)"]
    apps["apps/\n(Hybrid Native+Python)"]
    scholarly["scholarly/\n(Research Projects)"]
    publication["publication/\n(arXiv, Lektorat)"]
    privat["privat/\n(PrivatKanzlei)"]
    development["development/\n(Experiments)"]
    syncthing["syncthing/\n(Sync Manager)"]
  end

  subgraph pdai1 ["External /Volumes/PDAI-1"]
    pdaiColl["pdai-collections/\n(~37 Sammlungen, Bulk-Daten)"]
    editions["editions/\n(Viewer-Registrierungen)"]
  end

  pdai -. "data_path()" .-> pdai1
  scholarly -. "data_path()" .-> pdai1
NoteClient machines

~/ai-mac-studio is the tree on mac-studio, the central machine for PDAI data, the DuckLake, the MCP servers and Famulus development. Client machines (e.g. openscience) hold a Syncthing mirror of it at ~/ai-openscience and mount PDAI-1 via SMB; studio-only steps are queued in ~/syncthink/queue/.

Key properties:

  • No Dropbox — fileproviderd traversiert keine ai-*-Pfade
  • No conda / PROJECT_BASE — virtuelle Envs per Paket via uv
  • No symlinks in der Umbrella — alle Pfade sind echte Verzeichnisse
  • Bulk-Daten (~150+ GB) auf PDAI-1; Zugriff über env.data_path("name")
  • Python ≥ 3.14/3.15, hatchling, keine requirements.txt

Domain Hierarchy

graph TD
    home["~/ai-mac-studio/"]

    home --> platform["platform/\nGeneral Manager\n(Hub :5050, Proxy :5001)"]
    home --> pdai["pdai/\nPDAI Document Pipeline\n(konsolidiert Aug 2026)"]
    home --> agents["agents/\n29 Tool-Pakete\n(7 Kategorien)"]
    home --> apps["apps/\nHybride Apps\n(ai-korrespondenz, ai-applevoicerecorder)"]
    home --> scholarly["scholarly/\nForschungsprojekte\n(ai-karman-manager, ...)"]
    home --> publication["publication/\narXiv, Lektorat"]
    home --> development["development/\nExperimente\n(moss-transcribe, causal-architect)"]

    pdai --> pipeline["pipeline/\nai-scholar, ai-classifypdf\nschema-audit, ai-ocr-dev"]
    pdai --> index["index/\nai-lemma-index :5890\nai-oxford-dictionary"]
    pdai --> pdaiAgents["agents/\nai-query :5113"]
    pdai --> viewer["viewer/\nai-viewer :5100–5720"]
    pdai --> format["format/\nlettre-pdai, ai-repository"]
    pdai --> enrich["enrich/\nai-translation, ai-biblatex"]

    agents --> infra["infrastructure/ (8)\nai-core, ai-cluster\nai-machine-registry"]
    agents --> comm["communication/ (6)\nai-korrespondenz, ai-mail\nai-reporter"]
    agents --> media["media/ (3)\nai-audio, ai-video, ai-foto"]
    agents --> apple["apple/ (2)\nai-apple, ai-apple-documents"]
    agents --> dataml["data-ml/ (4)\nai-chroma, ai-stanza\nai-index, ai-exo"]
    agents --> mgmt["management/ (6)\nai-agenda, ai-voicememo\nai-task"]

Network Topology

Alle Internet-Anfragen kommen durch einen einzigen ngrok-Tunnel auf mac-studio, geroutet vom Proxy auf Port 5001 über config/routes.yaml.

graph LR
    internet["Internet"]
    ionos["IONOS\n*.lettre.ai\nFrameset-Weiterleitung"]
    ngrok["https://lettre.ngrok.dev\nngrok-Tunnel"]
    proxy["mac-studio :5001\nProxy\nroutes.yaml"]

    internet --> ionos --> ngrok --> proxy

    proxy --> hub["  :5050  Hub"]
    proxy --> viewer["  :5100  AI Viewer"]
    proxy --> aiquery["  :5113  AI Query API"]
    proxy --> famnb["  :5118  Famulus Notebook"]
    proxy --> glider["  :5890  Glider"]
    proxy --> editions["  :5111  Editions"]
    proxy --> diaries["  :5112  Diaries"]
    proxy --> korrespondenz["  :5300  Korrespondenz"]
    proxy --> inqua["  :8080  INQUA (Host-Header)"]
    proxy --> more["  ... 14 weitere Routen"]

Externe Domänen (*.lettre.ai) sind in IONOS als HTML-Frameset-Weiterleitungen zu https://lettre.ngrok.dev/{path} konfiguriert.
Tailscale-Zugriff: https://mac-studio.tail147011.ts.net/ → Proxy :5001.


PDAI Document Pipeline

PDAI (Primary Document AI) ist das gelehrte Dokument-Verarbeitungssystem. Es konvertiert gescannte PDFs in strukturiertes XML für Annotation und Analyse.

Konsolidierter Code-Pfad: ~/ai-mac-studio/pdai/
Dokument-Daten: /Volumes/PDAI-1/pdai-collections/ (~37 Sammlungen)

graph TD
    pdfs["Quell-PDFs\n(Bibliotheken, Archive)"]
    classify["ai-classifypdf\n pdai/pipeline/ai-classifypdf\nErnte + Klassifizierung"]
    pdai1["/Volumes/PDAI-1/pdai-collections/\n~37 thematische Sammlungen"]
    scholar["ai-scholar process\n pdai/pipeline/ai-scholar\n--model qwen3.5:cloud / kimi-k2.7-code:cloud\n(+structure.xml für Argumentstruktur)"]
    pages["pages/page_NNN/page_NNN.xml\nStrukturiertes PDAI 2.0 XML\n+ structure.xml"]
    index["ai-lemma-index\n pdai/index/ai-lemma-index\nDuckDB + Parquet-Postings"]
    query["ai-query :5113\n pdai/agents/ai-query\nQuery-Resolution-Agent"]
    viewer["ai-viewer :5100–5720\n pdai/viewer/ai-viewer\nWeb-Dokumentbetrachter"]

    pdfs --> classify --> pdai1 --> scholar --> pages
    pages --> index --> query --> viewer

Wichtige Pfade (aktuell):

Komponente Pfad
Pipeline-Code pdai/pipeline/ai-scholar/, pdai/pipeline/ai-classifypdf/
Lemma-Index pdai/index/ai-lemma-index/
Query-Agent pdai/agents/ai-query/ (v0.5.0)
Viewer pdai/viewer/ai-viewer/
Schemata (DTDs) pdai/pipeline/ai-scholar/src/ai_scholar/schemas/
Instruktions-Templates pdai/pipeline/ai-scholar/src/ai_scholar/instructions/ + platform/registry/instructions/
Produktions-Sammlungen /Volumes/PDAI-1/pdai-collections/
Editions-Registrierungen /Volumes/PDAI-1/editions/<name>/registry.json

OCR-Modellauswahl:

Dokumenttyp Standardmodell Fallback
Gedruckte Gelehrten-PDFs qwen3.5:cloud gemini-3.8-flash
Handschriftliche Korrespondenz kimi-k2.7-code:cloud gemini-3.8-flash

Reference layer (famulus reference)

Between the PDAI collections and their consumers sits the reference layer. Each collection is exported into one DuckLake; one MCP server serves items, citations and traces by fr: address. Overview: The Famulus universe; concept: Famulus reference; storage: DuckLake.

graph LR
    coll["/Volumes/PDAI-1/pdai-collections/&lt;coll&gt;/"] -->|"famulus-reference build"| fdb["&lt;coll&gt;_famulus.duckdb"]
    fdb -->|"export (mac-studio)"| lake["DuckLake _lake/famulus.ducklake"]
    lake -->|"read replica, READ_ONLY"| mcp["famulus-reference MCP :5135"]
    lake -->|"FAMULUS_LAKE=1"| proof["famulus-proof"]
    mcp --> orch["ai-platform-mcp, Partituren"]
    proof --> nb["famulus-notebook :5118"]
Component Path Port
famulus-reference (build, export, MCP, harvest) pdai/famulus-reference/ 5135
DuckLake catalog /Volumes/PDAI-1/pdai-collections/_lake/famulus.ducklake —
famulus-proof lake mode, fr: resolver development/famulus-proof/src/famulus_proof/lake.py —
intake skill pdai/skills/pipeline/pdai-collection-intake/ —

The lake has a single writer (mac-studio). Client machines read the lake over SMB or through the MCP server.

Laufende PDAI-Dienste

Supervisor: com.ai-platform.editions → startet alle Viewer + Glider + Landing
Query-Agent: com.ai-platform.ai-query

Dienst Port Pfad Route
Enestroem Viewer 5100 pdai/viewer/ai-viewer /viewer
Euler Opera Omnia 5103 pdai/viewer/ai-viewer /euler-opera
Kepler GW 5104 pdai/viewer/ai-viewer /kepler-gw
Copernicus 5105 pdai/viewer/ai-viewer /copernicus
Waefler 5106 pdai/viewer/ai-viewer /waefler
Euler OO IVA 5107 pdai/viewer/ai-viewer /euler-oo-iv
Pirckheimer 5108 pdai/viewer/ai-viewer /pirckheimer
Kirch 5109 pdai/viewer/ai-viewer /kirch
Editions Landing 5111 pdai/viewer/ai-viewer /editions
Astronomical Diaries 5112 pdai/viewer/ai-viewer /diaries
ai-query (API, Widget) 5113 pdai/agents/ai-query /ai-query
Famulus Notebook 5118 development/famulus-notebook /famulus-notebook
Famulus Reference MCP 5135 pdai/famulus-reference /famulus-reference (planned)
Glider Suche 5890 pdai/index/ai-lemma-index /glider
Ancient Sundials 5720 pdai/viewer/ai-viewer /sundials
Karman-Manager 5725 scholarly/projects/ai-karman-manager /karman

Machine Cluster

graph TD
    macstudio["mac-studio\n(Primary Hub)\nTailscale 100.102.189.23\nAlle Dienste hier"]
    macmini["mac-mini\n100.121.127.59\nBatch-Worker"]
    macm4["mac-m4\nnicht im Tailnet\nDev-Maschine, Batch-Worker"]
    macerster["mac-erster\n100.87.180.115\n(= openscience, legacy)"]

    macstudio <-->|"Tailscale VPN"| macmini
    macstudio <-->|"Tailscale VPN"| macm4
    macstudio <-->|"Tailscale VPN"| macerster
Maschine Rolle Tailscale IP Besonderheiten
mac-studio Primary Hub 100.102.189.23 M1 Ultra 128 GB; alle Dienste, NFS-Server
mac-mini Batch-Worker 100.121.127.59 OCR-Batch-Jobs, NFS-Client
mac-m4 Dev + Batch nicht im Tailnet (Stand 23.09.2026) Entwicklung, OCR-Experimente
mac-erster Legacy 100.87.180.115 = openscience; read-only

NFS: mac-studio exportiert /Volumes/PDAI-1 via NFS an mac-mini.
Tailscale-URL: https://mac-studio.tail147011.ts.net/ → Proxy :5001.


Konfigurationsdateien

graph LR
    routesyaml["config/routes.yaml\n(URL zu Port)"]
    datamounts["config/data-mounts.yaml\n(PDAI-1 Mount-Namen)"]
    machinesjson["machines/*.json\n(Maschinen-Konfiguration)"]
    envpy["shared/env.py\n(Laufzeit-Pfad-Auflösung)"]
    catalog["catalog.duckdb\n(Indexiertes Registry)"]

    machinesjson --> envpy
    datamounts --> envpy
    routesyaml --> proxy["Proxy :5001"]
    envpy --> allpackages["Alle ai-* Pakete"]
    catalog --> hub["Hub :5050"]
Warningservice-commands.yaml — zurückgezogen

config/service-commands.yaml ist nicht mehr autoritativ. Editionen werden von platform/scripts/editions_supervisor.py (launchd: com.ai-platform.editions) verwaltet. Die Datei wird nur noch als historische Referenz behalten.

Autoritative Start-Quelle: launchd-Plists in ~/Library/LaunchAgents/com.ai-platform.*.plist


Pfad-Auflösung

Alle Pakete verwenden platform_env — niemals hartcodierte absolute Pfade:

import importlib.util, sys
from pathlib import Path

def load_env():
    env_path = Path.home() / "ai-mac-studio/platform/shared/env.py"
    spec = importlib.util.spec_from_file_location("_platform_env", env_path)
    mod = importlib.util.module_from_spec(spec)
    sys.modules["_platform_env"] = mod
    spec.loader.exec_module(mod)
    return mod.detect()

env = load_env()

env.HOME                      # ~/ai-mac-studio
env.PLATFORM_DIR              # ~/ai-mac-studio/platform
env.package_dir("ai-scholar") # ~/ai-mac-studio/pdai/pipeline/ai-scholar
env.data_path("pdai_collections") # /Volumes/PDAI-1/pdai-collections

Letzte Aktualisierung: 2026-08-24