Copia de seguridad, exportación e importación
Todo lo que Control Center puede copiar, entregar o adoptar, y la forma exacta de cada artefacto. Para hacer una copia de seguridad de verdad, consulta Hacer copia de seguridad y restaurar; para entender por qué la persistencia está dividida de esta forma, consulta Espacios de trabajo y aislamiento.
Artefactos
Sección titulada «Artefactos»Hay tres artefactos de copia de la base de datos, con ámbitos y políticas de eliminación distintos.
| Artefacto | Escrito por | Forma | Cubre |
|---|---|---|---|
| Instantánea de la instalación | server.backupNow |
Un directorio con marca de tiempo | Todas las bases de datos de la instalación |
| Copia de seguridad de un espacio de trabajo | Pipeline Workspace backup |
Directorio con marca de tiempo con un archivo .db |
La base de datos de un espacio de trabajo |
| Exportación de un espacio de trabajo | workspace.export |
Un único archivo .db |
La base de datos de un espacio de trabajo |
Todos se escriben con VACUUM INTO de SQLite, que es seguro frente a una base de datos
WAL activa: toma una transacción de lectura, produce una copia desfragmentada y
transaccionalmente coherente, y nunca exige detener el servidor.
Estructura de la instantánea
Sección titulada «Estructura de la instantánea»<dataDir>/backups/2026-07-28T09-12-33-000Z/ manifest.json global.db <workspaceId>/workspace.db one directory per workspaceLa estructura replica exactamente el directorio de datos activo, que es lo que hace que
restaurar una instalación sea copiar de vuelta en lugar de traducir. El nombre del
directorio es la marca de tiempo UTC con : y . sustituidos por -, de modo que es
seguro para el sistema de archivos en Windows y se ordena cronológicamente como una
cadena simple.
Las copias de seguridad programadas de espacios de trabajo viven aparte, en
<dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db.
No incluyen un manifiesto ni global.db y no son instantáneas de la instalación.
El paso de retención del pipeline semanal elimina únicamente las copias de seguridad de
su propio espacio de trabajo más antiguas que la antigüedad configurada (30 días de forma
predeterminada); las instantáneas de la instalación creadas a mano nunca se rotan con ese
paso. server.listBackups solo lista instantáneas de la instalación, incluidas las
incompletas.
manifest.json
Sección titulada «manifest.json»| Campo | Tipo | Significado |
|---|---|---|
version |
int | Versión del formato del manifiesto. Actualmente 1 |
created_at |
ISO-8601 UTC | Cuándo se tomó la instantánea |
global.file |
string | Siempre global.db |
global.schema_version |
int | Versión del esquema de GlobalDatabase en el momento de la captura |
global.bytes |
int | Tamaño del global.db escrito |
workspace_schema_version |
int | Versión del esquema de WorkspaceDatabase compartida por todos los archivos de espacio de trabajo |
workspaces[] |
array | Una entrada por espacio de trabajo capturado |
workspaces[].workspace_id |
string | El espacio de trabajo al que pertenece este archivo |
workspaces[].file |
string | Ruta relativa a la raíz de la instantánea, <workspaceId>/workspace.db |
workspaces[].bytes |
int | Tamaño de ese archivo |
skipped_workspaces[] |
array of string | Espacios de trabajo que la copia de seguridad no pudo capturar |
Un espacio de trabajo se omite cuando está registrado pero nunca se ha escrito en él (así
que todavía no existe ningún archivo), o cuando su VACUUM INTO falló. En cualquier caso,
la instantánea se completa igualmente y el manifiesto indica qué falta.
Completitud
Sección titulada «Completitud»server.listBackups informa de un indicador complete por instantánea. Es falso cuando
el manifiesto falta o no se puede analizar, cuando falta global.db o cuando el
manifiesto nombra un archivo de espacio de trabajo que no está en el disco.
Una instantánea incompleta se lista igualmente, porque una instantánea que un operador no
puede ver es una instantánea que cree tener. Cuando el manifiesto no se puede leer, el
listado recurre a la propia estructura e informa de los archivos
<workspaceId>/workspace.db que encuentre; esos siguen siendo adoptables individualmente
mediante workspace.import aunque la instantánea en su conjunto no pueda restaurar una
instalación.
Qué no contiene una copia de seguridad
Sección titulada «Qué no contiene una copia de seguridad»Ambos artefactos son solo bases de datos. El directorio de un espacio de trabajo contiene más que su base de datos, y nada del resto viaja:
| Ruta | ¿En una instantánea? | ¿En una exportación de espacio de trabajo? |
|---|---|---|
global.db |
Sí | No |
<workspaceId>/workspace.db |
Sí | Sí (el archivo es este) |
<workspaceId>/blobs/ |
No | No |
<workspaceId>/skills/ |
No | No |
<workspaceId>/agents/ |
No | No |
<workspaceId>/chat_credentials/ |
No | No |
<workspaceId>/spaces/<spaceId>/ |
No | No |
<workspaceId>/pr_clones/ |
No | No |
secrets.json |
No | No |
models/ |
No | No |
meetings/<meetingId>/ |
No | No |
rigs/ |
No | No |
Parte de eso es prescindible: spaces/ contiene worktrees con copy-on-write que se
reaprovisionan desde los repos, pr_clones/ es una caché, models/ se vuelve a
descargar y rigs/ es estado de la máquina. Parte no lo es: blobs/ contiene imágenes
pegadas a las que apuntan filas de la base de datos, skills/ y agents/ contienen los
archivos con los que se ejecuta un agente, y secrets.json contiene todas las claves de
emparejamiento, credenciales de proveedores y ajustes de SSO de la instalación. Consulta
Hacer copia de seguridad y restaurar
para cubrir el resto.
Operaciones
Sección titulada «Operaciones»Las RPC de copia de seguridad de la instalación y la exportación e importación de espacios
de trabajo son solo para fullClient: un teléfono emparejado no puede activarlas. Todas
están ausentes por completo —no se rechazan, faltan estructuralmente— en un servidor sin
el puerto de copia de seguridad conectado, como el servidor de demostración.
| Operación | Tipo | Ámbito | Rol mínimo | Argumentos | Devuelve |
|---|---|---|---|---|---|
server.backupNow |
mutación | Instalación | propietario de la instalación | ninguno | {ok, path} |
server.listBackups |
lectura | Instalación | propietario de la instalación | ninguno | {backups: [...]} |
server.deleteBackup |
mutación | Instalación | propietario de la instalación | name |
{ok} |
workspace.export |
lectura | Espacio de trabajo | admin |
ninguno | {ok, path} |
workspace.import |
mutación | Espacio de trabajo | owner |
source_path |
{ok, workspace_id} |
workspace.delete |
mutación | Instalación* | owner |
id |
fila del registro marcada como eliminada |
workspace.deleteno tiene ámbito porque la fila que marca vive en el registro global; su manejador comprueba la pertenencia de quien llama al espacio de trabajo nombrado y exigeowner.
La path de cada respuesta es una ruta del host del servidor.
Respuesta de server.listBackups
Sección titulada «Respuesta de server.listBackups»De la más reciente a la más antigua, ordenadas por nombre de directorio (que es la marca de tiempo, así que el orden se mantiene incluso para una instantánea cuyo manifiesto no se pudo leer).
{ "backups": [ { "path": "/…/backups/2026-07-28T09-12-33-000Z", "name": "2026-07-28T09-12-33-000Z", "created_at": "2026-07-28T09:12:33.000Z", "bytes": 481203712, "complete": true, "workspaces": [ { "workspace_id": "w_9f2c…", "path": "/…/backups/2026-07-28T09-12-33-000Z/w_9f2c…/workspace.db", "bytes": 190840832 } ], "skipped_workspace_ids": [] } ]}created_at se omite cuando el manifiesto no se pudo leer. bytes en el nivel superior es
el tamaño real en disco de todo el directorio, no la suma del propio manifiesto: la
pregunta que se hace un operador que poda instantáneas es cuánto ocupa el directorio, no
cuánto pretendía escribir la copia de seguridad.
Cada workspaces[].path es exactamente lo que workspace.import toma como
source_path. Es deliberado: «restaurar este espacio de trabajo desde esta instantánea»
es la operación de importación, así que ambas no pueden divergir hacia tratamientos
distintos del mismo archivo.
Validación de workspace.import
Sección titulada «Validación de workspace.import»Antes de sustituir nada, el archivo candidato se abre en solo lectura con una conexión
SQLite en bruto de corta vida y se lee su fila workspace_meta.
| Condición | Resultado |
|---|---|
No es una base de datos SQLite legible, o no tiene workspace_meta |
Se rechaza. No se toca nada |
| El id de espacio de trabajo registrado ≠ el de destino | Se permite y se registra. Así es como se duplica un espacio de trabajo o se restaura con un id nuevo |
| El id de instalación registrado ≠ esta instalación | Se permite y se registra. Sus dispositivos emparejados e ids de usuario pertenecen a esa instalación y no se resolverán aquí |
| Id de espacio de trabajo no válido, o el archivo no existe | Se rechaza |
Cuando se acepta, la base de datos del espacio de trabajo de destino se cierra y se
descarta del gestor antes de copiar el archivo encima (una conexión de drift abierta
retiene el archivo y su -wal), y luego se vuelve a abrir para que beforeOpen reinstale
los disparadores de FTS y de sincronización, y los índices FTS se reconstruyen: las tablas
de contenido de un archivo importado están pobladas, pero su índice puede estar obsoleto.
Rutas de transferencia
Sección titulada «Rutas de transferencia»Todas las operaciones anteriores hablan en rutas del lado del servidor, lo cual es una
respuesta completa solo cuando el servidor es tu propia máquina. Estas tres transportan
los bytes, en el mismo carril firmado con PSK que usan el proxy de medios y el almacén de
imágenes. Quien llama firma una cadena de destino con la clave precompartida de su
dispositivo y pasa la firma como s.
| Ruta | Método | Consulta | Destino firmado | Requiere |
|---|---|---|---|---|
/backup/workspace |
GET | w, d, s |
backup-workspace:<workspaceId> |
admin del espacio de trabajo |
/backup/snapshot |
GET | n, d, s |
backup-snapshot:<name> |
propietario de la instalación |
/backup/restore |
POST | w, d, s |
backup-restore:<workspaceId> |
propietario del espacio de trabajo |
w es un id de espacio de trabajo, n un nombre de directorio de instantánea, d el id
del dispositivo que llama y s la firma. n se resuelve contra el listado de copias de
seguridad en lugar de concatenarse a la raíz de las copias de seguridad, así que la ruta
no puede apuntarse a un directorio que el listado no habría mostrado.
| Estado | Causa |
|---|---|
400 |
Falta un parámetro de consulta obligatorio, o el cuerpo de una subida está vacío |
403 |
Dispositivo desconocido o revocado, firma incorrecta, o quien llama carece del rol |
404 |
No hay puerto de copia de seguridad en este host, o la instantánea o el archivo de espacio de trabajo indicados no existen |
405 |
Se llama a /backup/restore con algo distinto de POST |
413 |
El cuerpo de la subida supera los 8 GiB, por la longitud de contenido declarada o por los bytes leídos realmente |
500 |
La exportación o el archivado falló en el lado del servidor |
Ambas descargas responden con Cache-Control: no-store y Accept-Ranges: none. Cada
solicitud acuña una copia nueva y la elimina una vez transmitida, así que una
respuesta cacheada o reanudada uniría bytes de dos exportaciones distintas en un único
archivo que parece válido y no lo es.
/backup/snapshot devuelve <name>.zip, con las entradas relativas a la raíz de la
instantánea, de modo que descomprimirlo reproduce manifest.json + global.db +
<workspaceId>/workspace.db. Las entradas se escriben en orden de clasificación, así que
dos archivos comprimidos de la misma instantánea son idénticos.
/backup/restore transmite el cuerpo directamente a un archivo de preparación en lugar de
almacenarlo en búfer, lo acota antes y durante la lectura, y elimina el archivo preparado
en todas las salidas posibles, incluida una denegación.
Rutas y límites
Sección titulada «Rutas y límites»| Cosa | Valor |
|---|---|
| Instantáneas | <dataDir>/backups/<timestamp>/ |
| Copias de seguridad programadas de espacios de trabajo | <dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db |
| Exportaciones de espacios de trabajo | <dataDir>/backups/exports/<workspaceId>-<timestamp>.db |
| Preparación de transferencias | <dataDir>/backups/transfer/ — un banco de trabajo, barrido por la ruta que escribe en él |
| Nombre del archivo de la instantánea | <snapshot directory name>.zip |
| Techo de subida | 8 GiB por POST /backup/restore |
| Retención | Instantáneas de la instalación: eliminación manual. Copias de seguridad de espacios de trabajo: pipeline semanal, 30 días de forma predeterminada |
Los directorios exports/, transfer/ y workspace-backups/ no son instantáneas de la
instalación y se excluyen de server.listBackups. Solo el último directorio tiene
retención programada; eliminar una instantánea de la instalación exige la acción explícita
del propietario de la instalación.
Consulta también
Sección titulada «Consulta también»- Hacer copia de seguridad y restaurar — las recetas a las que pertenecen estas operaciones
- Espacios de trabajo y aislamiento — por qué un espacio de trabajo es un archivo
- CLI de
cc_server— el directorio de datos en el que se encuentran estas rutas - Mapa de rutas — dónde vive la interfaz
- Arquitectura — la separación cliente/servidor que siguen las rutas