Speichereigentum
Wem bei Codex und bei Claude welche Datenbank und welcher Ordner gehört, warum HB Code die Dateien eines Agenten nie selbst öffnet, welche Tabellen eine Session mit ihrem Agenten verknüpfen, was das Löschen einer Session entfernt und wie die atomare Identitätsreservierung hinter der Outbox arbeitet.
Gegen den Quellcode geprüft am 5. Oktober 2026
Auf dieser Seite
Trennen Sie die Speicher nach Inhaber
Jeder Agent speichert seine Unterhaltungen selbst. HB Code speichert die Verknüpfung von einer Session zur Unterhaltung des Agenten, die Outbox und den Live-Zustand. Eine Unterhaltung liest HB Code nur über die Schnittstelle des Agenten: das Protokoll des Codex-App-Servers oder das Claude Agent SDK im Agent-Host.
| Frage | Codex | Claude |
|---|---|---|
| Wo liegt das Transkript? | Im Profil-Home codex/ | Im Claude-Hauptordner unter projects. Der Hauptordner ist CLAUDE_ |
| Welche Identität verknüpft die Session? | codex_ | claude_ |
| Wer liest den Verlauf? | Der Codex-App-Server-Kindprozess des Profils, bei thread/ | Ein Agent-Host-Prozess, der für eine Anfrage startet. Er ruft get |
| storage | indexed | native |
| Wo liegt die Befehlsausgabe? | Der Desktop hängt den Live-Stream an eine Datei in codex-command-outputs an und katalogisiert sie in codex_ | Nur im Transkript. HB Code speichert kein Byte der Ausgabe. Jeder Lesevorgang eines Bash-Ergebnisses sendet die Host-Anfrage tool |
| Was speichert HB Code selbst? | codex_ | claude_ |
- HB-Code-Datenappdata.db · codex-command-outputs/ · pasted-images/
Die Desktop-Laufzeit öffnet diese selbst: SQLx für die Datenbank, einfache Dateizugriffe für Codex-Befehlsausgabe und Chat-Anhänge.
- Codex-Homecodex/profiles/<uuid>/home/
HB Code legt den Ordner an, startet Codex mit ihm als CODEX_HOME und löscht den ganzen Profilordner, wenn Sie das Profil entfernen, außer eine Session verknüpft noch einen Rollout darin. HB Code öffnet nie eine Datei darin. Der Verlauf kommt über thread/items/list zurück.
- Startprüfung--allowed-storage-root = CODEX_HOME = sqlite_home
Der gebündelte app-server startet nur, wenn alle drei auf denselben Ordner zeigen, sodass Codex seine Datenbanken nirgendwo sonst ablegen kann.
- Claude-Kontoordnerclaude/accounts/<uuid>/
Ein Ordner für jedes Konto, das Sie hinzufügen. Er behält .claude.json, die zugehörige Sperrdatei, .credentials.json, backups und statsig. HB Code verknüpft jeden anderen Eintrag der obersten Ebene des Hauptordners hinein und ersetzt nie einen Eintrag, den der Ordner schon hat.
- Claude-Hauptordner~/.claude · CLAUDE_CONFIG_DIR
Er gehört Claude Code. Alle Konten speichern ihre Transkripte über die Verknüpfung projects hier. Der Agent-Host liest sie mit dem Claude Agent SDK, und jeder Verlaufslesevorgang startet den Host mit diesem Ordner, egal welches Konto aktiv ist.
Die Abbildung zeigt nur den Desktop-Computer. Zwei Speicher liegen außerhalb des Desktops: die Serverdatenbank und das Telefon. Die letzten zwei Zeilen der folgenden Tabelle nennen, was jeder enthält. Keiner enthält ein Transkript.
| Speicher | Inhaber und Inhalt | Zugriffsregel |
|---|---|---|
| HB Code appdata. | Produktmetadaten des Desktops, Session-Verknüpfungen für beide Agenten, Outbox-Operationen, Remote-Idempotenz, Live-Overlay-Zustand und Messwerte der Tariflimits. | HB-Code-Rust-Repositories verwenden SQLx und SQLite. |
| App-eigenes Codex-Profilverzeichnis | Der Codex-Kindprozess besitzt seine privaten Datenbanken, Auth/ | Verwenden Sie das App-Server-Protokoll. HB Code darf das private SQLite-Schema des Kindprozesses nicht abfragen. |
| Eine ausdrücklich gewählte Codex-Unterhaltungsquelle | Der exakte verknüpfte Transkriptpfad und die Thread-Identität definieren die Quelle. | Greifen Sie über pfadbezogene App-Server-Methoden auf die ausgewählte Quelle zu. Suchen Sie in anderen Verzeichnissen nicht nach einem Ersatz. |
| Claude-Hauptordner (~/ | Claude Code gehören die gespeicherten Transkripte, die Einstellungen und die Anmeldung. | Die Desktop-Laufzeit parst nie ein Transkript. Der Agent-Host liest Transkripte über das Claude Agent SDK. |
| Claude-Kontoordner (claude/ | Die Anmeldung eines hinzugefügten Kontos: .claude. | HB Code legt den Ordner und die Verknüpfungen an und entfernt den Ordner zusammen mit dem Konto. Das Entfernen löscht die Verknüpfungen und folgt ihnen nie. |
| Server Postgre | Konto- und Dienstdaten, die von Server-Repositories und Datenbankrollen gesteuert werden. | Trennen Sie Migrations-, System-Laufzeit- und Mandanten-Laufzeit-Prinzipale. |
| Telefonzustand | Ansichtszustand, lokale Kopien ungesendeter Nachrichten sowie Vorschau- und Ausgabe-Caches. | Betrachten Sie den Desktop als Autorität für Projekte, Ausführung, Outbox und Dateien. |
Jeder Lesevorgang eines Claude-Transkripts läuft mit dem Hauptordner, egal welches Konto aktiv ist. Ein gespeichertes Transkript braucht keine Anmeldung, und jedes Konto speichert in denselben Ordner projects. HB Code legt diesen Ordner im Hauptordner an, bevor es ein Konto verknüpft. Schlägt die Verknüpfung projects fehl, schlägt die Einrichtung des Kontos mit einem Fehler fehl. Eine fehlgeschlagene Verknüpfung für einen anderen Eintrag schreibt nur eine Warnung ins Protokoll.
Der Agent-Host öffnet drei Arten von Claude-Dateien direkt, weil das SDK sie nicht liefert: die Datei meta.json neben einem Subagenten-Transkript, den Run-Datensatz eines Workflows und das Feld effort im ersten gespeicherten Assistenten-Turn eines Subagenten. Er liest sie und schreibt sie nie.
Das Asset-Protokoll der WebView ist auf Medienvorschauen unter dem App-Cache beschränkt, sodass keine private Laufzeitdatei von der Seite erreichbar ist.
Speicheridentität und Ausführungsidentität unterscheiden sich
Die Spalte sessions.chat_agent enthält codex oder claude. Sie wird beim Anlegen der Session gesetzt, und eine Session-Aktualisierung behält sie bei. Sie entscheidet, welche Identitätstabellen eine Session nutzt.
- sessions.chat_agentcodex · claude
Wird beim Anlegen der Session gesetzt und von einer späteren Aktualisierung nicht geändert. Sie entscheidet, welche Seite eine Session hat. Der Standardwert der Spalte ist codex.
- codex_session_linksapp_session_id → profile_id, codex_thread_id, rollout_path, status
Ein partieller eindeutiger Index erlaubt eine Verknüpfung mit dem Status available je Profil und Thread. Der Status ist available, profile_required oder unavailable. Der Fremdschlüssel profile_id verhindert das Löschen einer Profilzeile, die eine Verknüpfung noch nennt.
- claude_sessionsapp_session_id → native_session_id (eindeutig)
Einer App-Session gehört eine Claude-Unterhaltung. Eine zweite Session, die dieselbe Unterhaltung fortsetzen will, scheitert mit „This Claude conversation is already open in another session.“
- claude_operations(app_session_id, operation_id) → native_message_id, run_id, display_text, attachments
Wird vor dem Senden geschrieben. Eine Wiederholung derselben Operation behält die erste UUID und die erste Run-ID. Eine Wiederholung mit anderem Text oder anderen Anhängen scheitert mit einem Konflikt.
Ein App-eigenes Codex-Profil hat eine stabile, opake UUID in kanonischer Kleinschreibung. Eine E-Mail-Adresse und ein Dateisystempfad sind keine Profilidentität. Die Tabelle codex_profiles enthält eine Zeile je Profil mit dem Status signed_out, authenticated oder unavailable und den Kontospalten, die der App-Server gemeldet hat.
Indexed und Exact sind Entwurfsnamen für die zwei Leserouten von Codex. Im Code entscheidet ein Prädikat: Eine Verknüpfung, deren Rollout-Pfad außerhalb des Laufzeit-Homes liegt, ist eine externe exakte Quelle. Beide Routen rufen thread/items/list auf dem Codex-App-Server auf. Ein exakter Lesevorgang fügt path und historySources hinzu. Das übertragene storageFormat einer Codex-Session bleibt auf beiden Routen indexed. Eine Operation löst ihre Route einmal auf und behält sie.
Eine Claude-Session hat keine Profilverknüpfung, weil jedes Claude-Konto dieselben Transkripte liest. HB Code speichert nicht, ob ein Transkript existiert. Der Host antwortet mit missing, wenn Claude die Unterhaltung noch nicht gespeichert hat, und der Desktop zeigt dann eine leere Timeline. Die UUID in claude_operations ist die UUID der Benutzernachricht, die der Desktop sendet. Über sie findet der Desktop diese Nachricht im Transkript. Die Zeile enthält auch den Nachrichtentext und die Anhänge.
Der exakte Quellzugriff hat bewusste Grenzen
- historySources[{ rolloutId, path }]
Vom Desktop aus den absoluten Pfaden der anderen verknüpften Rollouts der Session gebaut, die er aufzeichnet, sobald Codex ein Kind meldet. Nur hier sucht der app-server nach einem Vorfahren.
- history_basethread_id · end_byte_offset
Session-Metadaten am Anfang der Datei des Kinds: der Vorfahren-Rollout und das Byte, an dem der geerbte Teil endet. Der app-server folgt bis zu 256 Vorfahren und lehnt einen Zyklus ab oder einen Vorfahren, der kürzer als dieser Offset ist.
- reloadRequiredFehler data.code
Der Cursor trägt einen Digest aller Bytes, die er abdeckt. Anhängen lässt ihn gültig. Ändern sich diese Bytes, scheitert die nächste Seite, und der Desktop zeigt einen gewöhnlichen Ladefehler. Nur sourceUnavailable bietet an, die Quelldatei neu zu wählen.
| Bedingung | Vertrag |
|---|---|
| Erforderliche Ancestor-Quelle ist nicht vorhanden | Der app-server lässt den Lesezugriff mit missing |
| Quelle wird ersetzt oder gekürzt | Der app-server bindet jeden Cursor an einen Digest der gelesenen Bytes. Anhängen lässt Cursor gültig. Kürzen oder Umschreiben lässt die nächste Seite mit reload |
| Die aktuelle Methode nimmt nur eine Thread-ID entgegen | Bieten Sie diese Mutation für eine exakte externe Quelle nicht an, wenn sie den ausgewählten Pfad nicht adressieren kann. Dies gilt für die Operationen aktuelles Ziel, Rollback und persistierte Thread-Settings. |
| Ein anderes mitgeliefertes Sidecar besitzt den Writer | Geben Sie die Thread-Ownership frei, bevor eine andere Runtime sie wiederaufnimmt. |
Vor einem Versand oder Anhängen gibt der Desktop den Thread von jedem anderen Profilserver frei, den er betreibt. Das koordiniert die mitgelieferten Sidecars dieses Prozesses. Es hindert keinen fremden externen Codex-Prozess daran, dieselbe Quelle zu schreiben. Stoppen Sie einen externen Schreiber, bevor Sie diese Unterhaltung in HB Code fortsetzen.
Die Outbox verwendet einen atomaren Identitätsanspruch
workspace_chat_outbox
session_id → entries_json, updated_at
workspace_chat_outbox_operation_identity
(session_id, operation_id) → request_fingerprint
remote_rpc_idempotency
scope_key → request_fingerprint, state, response_json, lease, expiry
chat_operation_ledger
(app_session_id, operation_id) → status, result_json
chat_session_messages
operation_id → recipient, sender, sender_call_id, sender_run_id, sender_thread_id, chain_id, hop, delivery
chat_live_timeline_overlays
(app_session_id, timeline_target_id) → revision, snapshot_json
chat_live_timeline_overlay_revisions
singleton → one global revision sequence
chat_pending_terminal_overlay_cleanups
(app_session_id, run_id)
agent_usage_samples
agent, account_key, window_kind → used_percent, resets_at, sampled_atFünf Tabellen tragen das Präfix chat_ und dienen Codex- und Claude-Sessions gleichermaßen. Vier davon hatten bis zu einer Umbenennungsmigration das Präfix codex_. chat_session_messages ist neuer. Tabellen, die nur Codex nutzt, behalten das Präfix codex_, zum Beispiel codex_session_links und codex_command_outputs.
| Tabelle | Inhalt | Regel |
|---|---|---|
| chat_ | Der Status und das gespeicherte Ergebnis einer Chat-Operation. | Schlüssel: App-Session-ID und Operations-ID. Das Löschen einer Session entfernt die Zeilen der Basis-Session, ihres Alias :: |
| chat_ | Der Datensatz einer Nachricht, die ein Agent in einer Session an eine andere Session gesendet hat. | Schlüssel: Operations-ID. Das Paar aus Absender-Session und Absender-Aufruf-ID ist eindeutig, und hop ist mindestens 1. delivery ist sent, needs-approval oder declined. |
| chat_ | Das gespeicherte Live-Overlay einer Timeline als JSON. | Schlüssel: App-Session-ID und Timeline-Ziel-ID. Bei Claude ist das Ziel die App-Session-ID für die Unterhaltung und die Subagenten-ID für einen Subagenten. |
| chat_ | Eine Zeile mit einem Revisionszähler für alle Overlays. | Der Zähler wächst nur, bis 2^53 − 1. Ein neues Ziel kann die Revision eines gelöschten Ziels nicht wiederverwenden. |
| chat_ | Die beendeten Runs, deren Live-Zeilen noch nicht vollständig durch gespeicherten Verlauf ersetzt sind. | Schlüssel: App-Session-ID und Run-ID. Die Zeile wird geschrieben, bevor der Desktop den aktiven Run vergisst, und bleibt, bis jede Timeline dieses Runs abgeglichen ist. |
save_workspace_chat_outbox_with_operation_identity öffnet eine Transaktion. Ihr INSERT … ON CONFLICT aktualisiert die Identitätszeile nur, wenn der vorhandene Fingerabdruck dem übermittelten gleicht. Betrifft diese Anweisung nicht genau eine Zeile, wird die Transaktion zurückgerollt. Danach schreibt sie das JSON der Outbox-Einträge per Upsert. Für eine Nachricht aus einer anderen Session fügt sie außerdem die Zeile in chat_session_messages ein, und eine Zeile mit derselben Operations-ID bleibt unverändert. Dann folgt der Commit. Eine Session-Nachricht wird nie ohne ihren Datensatz eingereiht und nie ohne ihren Warteschlangeneintrag aufgezeichnet. Die Identitätszeile hat die Basis-Session als Schlüssel, während das Outbox-JSON unter der Alias-Session gespeichert wird. So lässt sich dieselbe Operation von jedem Alias im Geltungsbereich finden.
Die Tabelle remote_rpc_idempotency ist das zweite Register. Sie behält das Ergebnis jeder gelisteten Remote-Mutation 48 Stunden lang über Desktop-Neustarts hinweg, sodass ein Telefon, das nach der Rückkehr des Desktops erneut versucht, weiterhin die gespeicherte Antwort erhält.
agent_usage_samples enthält Messwerte der Tariflimits für beide Agenten. Der Kontoschlüssel ist die ID des aktiven Codex-Profils oder die Claude-Konto-ID, also default oder eine UUID. Ein Messwert wird übersprungen, wenn der neueste Messwert desselben Fensters jünger als 10 Minuten ist, dieselbe Rücksetzzeit hat und um weniger als 0,5 Prozent abweicht. Messwerte, die älter als 35 Tage sind, werden gelöscht.
Was das Löschen einer Session entfernt
delete_session_with_scoped_references entfernt die HB-Code-Zeilen einer Session in einer SQLite-Transaktion. Das Löschen sendet keine Anfrage an Codex und keine an Claude. Das Transkript des Agenten bleibt dort, wo der Agent es gespeichert hat.
| Daten | Wirkung des Löschens |
|---|---|
| Zeilen der Session in codex_ | In der Transaktion gelöscht. Ihre Zeilen für ausstehende Anhängevorgänge verschwinden mit. Die Ausgabedateien werden nach dem Commit entfernt. |
| chat_ | Die Zeilen der Basis-Session, ihres Alias :: |
| codex_ | Zeilen mit dieser Basis-Session werden gelöscht. |
| workspace_ | Zeilen derselben drei Geltungsbereiche werden gelöscht. |
| project_ | active_ |
| sessions | Die Zeile wird zuletzt gelöscht. |
| claude_ | Durch ON DELETE CASCADE von der Zeile in sessions gelöscht. Ein Datensatz einer Session-Nachricht verschwindet, wenn ihr Absender oder ihr Empfänger gelöscht wird. |
| Arbeitsspeicher des laufenden Desktops | Nach dem Commit leert der Desktop die zwischengespeicherten Outbox-Einträge, die Einträge der Videoanalyse und das Operations-Ledger der Session im Arbeitsspeicher. |
| Codex-Thread und Rollout-Dateien | Nie angefasst. Sie bleiben im Profil-Home oder unter dem angehängten Pfad. |
| Claude-Transkript | Nie angefasst. Es bleibt im Claude-Hauptordner, und eine neue Session kann es fortsetzen. |
Der Zugriff auf Projektdateien bildet eine eigene Grenze
Entfernte Dateizugriffe laufen mit dem Dateisystemzugriff des Desktop-Benutzers. resolve_desktop_file_read_path expandiert eine Home-Abkürzung, hängt einen relativen Pfad an das kanonische Projektverzeichnis und kanonisiert das Ergebnis. Die Funktion erzwingt keine Projekteinschließung, und die Entwurfsnotiz sagt das mit Absicht. allowExternalFile und allowExternalMedia entscheiden nur, welcher Auflöser zuerst versucht wird, sodass ein authentifizierter Companion so oder so Pfade außerhalb des gewählten Projekts öffnen kann. ensure_path_within_project, das Elternkomponenten zurückweist und die kanonische Wurzel prüft, existiert für desktop-lokale Operationen.
App-verwaltete Chat-Anhänge liegen in pasted-images unter dem App-Datenverzeichnis, und ein externer Medienlesezugriff für einen Anhang muss als Bild, Video, Audio oder Dokument klassifiziert sein. Das Telefon verwendet nie sein eigenes Home-Verzeichnis.