Zum Artikel springen
PlanToCodeDocsApp herunterladen

HandbuchArchitektur

Speichereigentum

Wem welche Datenbank gehört, warum PlanToCode nie selbst eine Codex-Datei öffnet, wie eine Transkriptquelle identifiziert wird, und der atomare Identitätsanspruch hinter der Outbox.

Gegen den Quellcode geprüft am 17. September 2026

Auf dieser Seite

Trennen Sie die Speicher nach Inhaber

Die Dateien von Codex liegen im Ordner von PlanToCode, doch nur Codex öffnet sie
Die Dateien von Codex liegen im Ordner von PlanToCode, doch nur Codex öffnet sieDer App-Datenordner von PlanToCode enthält seine eigene Datenbank und Dateien und eine Ebene tiefer einen Home-Ordner für jedes Codex-Profil. Die Desktop-Laufzeit öffnet ihre eigenen Dateien direkt, legt Profilordner an und löscht sie und erreicht alles in einem Home nur über JSON-RPC zum Codex-Kindprozess. Ein angehängter Rollout kann unter jedem Pfad liegen, und Codex öffnet ihn nur, wenn eine Anfrage ihn nennt. Außerhalb des Computers hält der Server Konten und Abrechnung, und das Relay leitet Desktop-Daten an Telefone weiter, ohne sie zu speichern.
Ihr Computer
PlanToCode DesktopRust-Laufzeit
Codex app-serverein Kindprozess pro Profilpaar
JSON-RPC über stdio
com.plantocode · App-Daten
appdata.dbSession-Links, Outbox, Live-Overlay
Befehlsausgaben und Anhängecodex-command-outputs/ · pasted-images/
codex/profiles/<uuid>/ · von PlanToCode angelegt und gelöscht
home/ · nur von Codex geöffnet
sessions/ · archived_sessions/ · .jsonl · .jsonl.zstprivate SQLite · auth.json
angehängter Rolloutbeliebiger Pfad · Codex öffnet ihn, wenn eine Anfrage ihn nennt
~/.codexein separates Codex-Home, nie durchsucht
Regionaler ServerKonten und Abrechnung in PostgreSQL und Redis
Relay · nicht gespeichert
Telefonungesendete Nachrichten, Caches, Ansichtszustand
  • PlanToCode-Datencodex-command-outputs/ · pasted-images/ · appdata.db

    Die Desktop-Laufzeit öffnet sie selbst: SQLx für die Datenbank, einfache Lese- und Schreibzugriffe für Befehlsausgaben und Chat-Anhänge.

  • Codex-Homecodex/profiles/<uuid>/home/

    PlanToCode 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. PlanToCode ö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.

  • Außerhalb dieses ComputersPostgreSQL · Redis

    Der Server hält Konten, Geräte, Guthaben und Nutzung in PostgreSQL und Anmelde-Übergaben, Rate-Limits und vorgemerkte Abbuchungen in Redis. Was das Relay weiterleitet, wird nicht gespeichert.

SpeicherInhaber und InhaltZugriffsregel
PlanToCode appdata.dbDesktop-Produktmetadaten, Sitzungsverknüpfungen, Outbox-Operationen, Remote-Idempotenz und Live-Overlay-Zustand.PlanToCode Rust-Repositories verwenden SQLx und SQLite.
App-eigenes Codex-ProfilverzeichnisDer Codex-Child-Prozess besitzt seine privaten Datenbanken, Auth/Konfiguration und den normalen zugehörigen Sitzungsspeicher.Verwenden Sie das App-Server-Protokoll. PlanToCode darf das private SQLite-Schema des Child-Prozesses nicht abfragen.
Eine explizit ausgewählte KonversationsquelleDer 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.
Server PostgreSQLKonto- und Dienstdaten, die von Server-Repositories und Datenbankrollen gesteuert werden.Trennen Sie Migrations-, System-Laufzeit- und Mandanten-Laufzeit-Prinzipale.
TelefonzustandAnsichtszustand, lokale Kopien ungesendeter Nachrichten sowie Vorschau- und Ausgabe-Caches.Betrachten Sie den Desktop als Autorität für Projekte, Ausführung, Outbox und Dateien.

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

Ein app-eigenes Codex-Profil hat eine stabile opake UUID, die kanonischer Kleinbuchstabentext sein muss; eine E-Mail-Adresse und ein Dateisystempfad sind keine Profilidentität. codex_session_links schlüsselt den Link nach App-Session und trägt profile_id, codex_thread_id, einen optionalen rollout_path und einen Status available, profile_required oder unavailable, mit einem partiellen eindeutigen Index, der genau einen available-Link pro Thread und Profil erlaubt. Indexed und Exact sind Entwurfsnamen; im Code entscheidet ein Prädikat: Ein Link, dessen Rollout-Pfad außerhalb des Laufzeit-Homes liegt, ist eine externe exakte Quelle, Lesevorgänge übergeben path und historySources nur, wenn ein Rollout-Pfad vorliegt, und das storageFormat auf der Leitung bleibt in beiden Fällen indexed. Beide Routen rufen thread/items/list auf dem Codex app-server auf, und ein exakter Lesezugriff fügt path und historySources hinzu. Eine Operation legt ihre Route einmal fest und behält sie.

Der exakte Quellzugriff hat bewusste Grenzen

Ein exakter Lesezugriff setzt den Verlauf aus Bytebereichen der Dateien zusammen, die er bekommt
Ein exakter Lesezugriff setzt den Verlauf aus Bytebereichen der Dateien zusammen, die er bekommtFür eine exakte Quelle sendet der Desktop den Rollout-Pfad und die anderen Rollouts der Session als historySources. Der Codex app-server spielt die Bytes des Eltern-Rollouts bis zu dem Offset ab, den das Kind vermerkt hat, dann die eigenen Bytes des Kinds, und bindet den Cursor an einen Digest genau dieser Bytes. Anhängen an das Kind lässt den Cursor gültig, und das Umschreiben gelesener Bytes erzwingt ein Neuladen. Ein Eltern-Rollout, der nicht aufgeführt ist, lässt den Lesezugriff scheitern, auch wenn seine Datei im selben Ordner liegt. Die Größen sind Beispiele.
Codex app-serverthread/items/list · threadId · path · historySources · cursor
Eltern-Rollout in historySources aufgeführt
parent.jsonl
geerbtes Präfix
nicht gelesen
history_base.end_byte_offset
child.jsonl · path
eigene Bytes
umgeschrieben oder gekürzt: reloadRequired
später angehängt: gültig
ein Replay
Eltern-Präfix
Kind
der Digest des Cursors deckt diese Bytes ab
Eltern-Rollout nicht aufgeführt
child.jsonl · path
history_base
parent.jsonlim Ordner, in historySources fehlt es
missingHistorySource: Der Lesezugriff scheitert. Kein Ordner und kein Codex-Home wird durchsucht.
  • 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.

BedingungVertrag
Erforderliche Ancestor-Quelle ist nicht vorhandenDer app-server lässt den Lesezugriff mit missingHistorySource scheitern, auch wenn die Datei neben dem Kind liegt. Der Desktop zeigt einen allgemeinen Ladefehler. Nur sourceUnavailable wird zu CODEX_SOURCE_ERROR, das anbietet, die Quelldatei neu zu wählen.
Quelle wird ersetzt oder gekürztDer 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 reloadRequired scheitern, angezeigt als allgemeiner Ladefehler. „Timeline source changed; reload the timeline“ ist der Fehler des Desktops, wenn sich die verknüpfte Quelle selbst geändert hat.
Die aktuelle Methode nimmt nur eine Thread-ID entgegenBieten 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 WriterGeben 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, also stoppen Sie einen externen Schreiber, bevor Sie diese Unterhaltung in PlanToCode fortsetzen.

Die Outbox verwendet einen atomaren Identitätsanspruch

Wichtige Beziehungen in der Produktdatenbank – schematisch, kein Migrations-SQL
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

codex_live_timeline_overlays
  timeline target → persisted overlay snapshot

codex_live_timeline_overlay_revisions
  singleton → one global revision sequence

codex_chat_operation_ledger
  (app_session_id, operation_id) → status, result_json

save_workspace_chat_outbox_with_operation_identity öffnet eine Transaktion. Sein INSERT … ON CONFLICT aktualisiert die Identitätszeile nur, wenn der vorhandene Fingerabdruck dem eingereichten entspricht. Betrifft diese Anweisung nicht genau eine Zeile, wird die Transaktion zurückgerollt. Dann wird das Outbox-JSON per Upsert geschrieben und bestätigt. Die Identitätszeile ist nach der Basis-Session geschlüsselt, während das Outbox-JSON unter der Alias-Session gespeichert wird, sodass dieselbe Operation von jedem Alias im Geltungsbereich gefunden werden kann.

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.

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; es 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.