@@ -56,10 +56,48 @@ names, creation timestamps, and labels. Crate-level details live in
5656
5757## Persistence
5858
59- The gateway stores protobuf payloads with indexed object metadata. SQLite is the
60- default local store; Postgres is supported for deployments that need an external
61- database. Persisted state includes sandboxes, providers, SSH sessions, policy
62- revisions, settings, inference configuration, and deployment records.
59+ The gateway persistence layer is a protobuf object store. Domain services store
60+ typed protobuf messages as opaque binary payloads, while the database keeps a
61+ small set of indexed metadata columns for lookup, listing, versioning, and
62+ workflow state. The implementation lives in the
63+ [ gateway persistence module] ( ../crates/openshell-server/src/persistence/mod.rs ) ;
64+ backend-specific SQL lives in the SQLite and Postgres migration directories
65+ under ` crates/openshell-server/migrations/ ` .
66+
67+ The storage schema is intentionally narrow:
68+
69+ | Column | Purpose |
70+ | ---| ---|
71+ | ` id ` | Stable gateway-generated object ID and primary key. |
72+ | ` object_type ` | Logical resource kind, such as ` sandbox ` , ` provider ` , ` ssh_session ` , ` inference_route ` , ` sandbox_policy ` , or ` draft_policy_chunk ` . |
73+ | ` name ` | Human-readable name, unique within an object type when present. |
74+ | ` scope ` | Optional owner or namespace for scoped/versioned records, such as a sandbox ID for policy revisions. |
75+ | ` version ` | Optional monotonically increasing version for scoped records. |
76+ | ` status ` | Optional workflow state for records such as policy revisions or draft policy chunks. |
77+ | ` dedup_key ` and ` hit_count ` | Optional policy-advisor fields for coalescing repeated observations. |
78+ | ` payload ` | Prost-encoded protobuf payload for the full domain object. |
79+ | ` created_at_ms ` and ` updated_at_ms ` | Gateway timestamps used for ordering and list output. |
80+ | ` labels ` | JSON object carrying Kubernetes-style object labels for filtering and organization. |
81+
82+ Common resources use generic helpers that derive ` object_type ` , ` id ` , ` name ` ,
83+ and labels from protobuf metadata traits before encoding the full message into
84+ ` payload ` . Policy revisions and draft policy chunks use the same table but also
85+ populate ` scope ` , ` version ` , ` status ` , ` dedup_key ` , and ` hit_count ` so the
86+ gateway can efficiently fetch the latest policy, track load status, and manage
87+ advisor drafts without creating resource-specific tables.
88+
89+ SQLite is the default local store; Postgres is supported for deployments that
90+ need an external database or multi-replica coordination. Both backends expose
91+ the same ` Store ` API and the same logical schema. Backend differences stay
92+ inside the adapters: for example, SQLite stores labels as JSON text and payloads
93+ as ` BLOB ` , while Postgres stores labels as ` JSONB ` and payloads as ` BYTEA ` .
94+ Domain code should depend on the object-store contract, not SQL dialect details.
95+ This keeps the gateway data model portable across storage backends and leaves
96+ room for future stores that can provide the same object, label, version, and
97+ scope semantics.
98+
99+ Persisted state includes sandboxes, providers, SSH sessions, policy revisions,
100+ settings, inference configuration, and deployment records.
63101
64102Policy and runtime settings are delivered together through the effective sandbox
65103config path. A gateway-global policy can override sandbox-scoped policy. The
0 commit comments