Las reglas aparecen en la sección 7 de docs/architecture/23-ops.md y en la sección 4.1 de docs/architecture/07-data.md. Este es el procedimiento.
La garantía que lo hace seguro
La versión R se ejecuta correctamente con el esquema R y con el esquema R menos uno. Cada cambio de esquema se divide en ampliación, transición y contracción:
- Ampliación: añade la nueva columna, tabla o índice. El código antiguo lo ignora.
- Transición, durante al menos una versión: el código nuevo escribe en ambos formatos y lee el nuevo; un trabajo reanudable completa los registros antiguos.
- Contracción: elimina el formato antiguo en una versión posterior, en un despliegue independiente.
Así, en todo momento de una actualización gradual, los procesos antiguos y nuevos pueden compartir una base de datos. No hay migraciones inversas: una migración que eliminó una columna hace una hora no puede recuperar las filas escritas durante esa hora.
El trabajo de CI schema-compat comprueba la garantía en cada versión ejecutando las pruebas de la versión anterior con el esquema nuevo.
Antes de empezar
- Lee las notas de la versión. Si una versión requiere una ventana de mantenimiento, se indicará junto con la duración estimada; como máximo habrá una por versión.
- Ejecuta el simulacro de restauración o confirma que se completó correctamente con esta versión (backup-restore.md). Si el simulacro falla, no se puede continuar con la actualización.
- Crea una copia base:
docker compose -f docker/compose.yaml --profile backup run --rm backup.
Docker Compose, un host
export QUIRE_RELEASE=2026.10.0 # or set it in docker/.env
docker compose -f docker/compose.yaml pull # or build
docker compose -f docker/compose.yaml run --rm migrate
docker compose -f docker/compose.yaml up -d --no-deps web content collab
docker compose -f docker/compose.yaml up -d --no-deps worker schedulerEl orden es deliberado:
- Primero, migrar, mientras la versión anterior sigue atendiendo solicitudes. Las migraciones de ampliación son invisibles para ella.
- Después, la capa web. Al recibir SIGTERM, cada proceso web cambia
/readyzadraining, termina las solicitudes en curso en un máximo de 30 segundos, cierra los flujos con una indicación para volver a conectarse y sale.stop_grace_periodes de 40 segundos, así Compose nunca interrumpe un apagado correcto. - Por último, los workers, para que la versión más reciente del consumidor no se adelante al formato de evento que se produce. Los workers dejan de obtener trabajos de inmediato y disponen de 120 segundos; si un trabajo no termina, otro worker lo vuelve a obtener. Es seguro porque todos los trabajos son idempotentes. El scheduler cede el liderazgo en su siguiente turno.
En un solo host, Compose reemplaza cada contenedor por turnos, así que hay una breve interrupción por servicio. Para eliminar por completo las interrupciones, ejecuta la capa web como dos contenedores detrás de tu propio proxy (con un archivo de configuración alternativa que añada un segundo servicio web sin puerto publicado) y vuelve a crearlos de uno en uno, esperando a que cada uno indique que está saludable antes de continuar.
Varios hosts o un orquestador
Sigue el mismo orden: ejecuta una sola tarea de migración y luego actualiza gradualmente la capa web, con un recurso adicional disponible y ninguno no disponible, y después los workers. Configura las comprobaciones de preparación en /readyz y las de disponibilidad en /healthz.
Con bases de datos de tenants dedicadas, el paso migrate realiza ambas tareas: primero migra la base de datos de control y después cada base de datos indicada en ops.tenant_database, de una en una y con su propio bloqueo. Un fallo en una base de datos de tenant no detiene las demás. Cuando termina con todas, compara los registros de migración y devuelve un código distinto de cero, salvo que todas hayan aplicado exactamente las mismas migraciones que la base de datos de control; además, indica cuáles van retrasadas o adelantadas. El mismo comando instala las tablas de la cola en cada base de datos, porque el worker consume en ella los trabajos de los tenants fijados a esa base.
bun apps/worker/src/migrate.ts # what the Compose step runs
bun run db:migrate:all # the same, from a checkoutLa migración normal y la configuración inicial también instalan los documentos legales canónicos en inglés del operador de Quire en ops.platform_policy_version. El instalador es idempotente: solo se sustituyen los textos en inglés que falten y exactamente los textos provisionales creados por la migración. Las semillas se archivan y se inserta una nueva versión publicada; las referencias históricas de aceptación y los textos se conservan. Cualquier versión auténtica redactada por el operador, incluido un borrador, se conserva y debe gestionarse desde la consola de Políticas de la plataforma. Los documentos, versiones y consentimiento de las políticas de inquilinos nunca cambian con esta transición. Esto es publicación de texto del operador, no certificación legal ni cumplimiento automático de sus promesas.
Se accede a cada base de datos dedicada por el nombre con el que está registrada. Una base de datos registrada como env:QUIRE_DB_NORTHWIND_URL necesita:
| Variable | Se usa para |
|---|---|
QUIRE_DB_NORTHWIND_URL |
Rol de la aplicación, para la capa web y el worker |
QUIRE_DB_NORTHWIND_URL_MIGRATOR |
Rol de migración, para este comando y para las transferencias |
QUIRE_DB_NORTHWIND_URL_SUPERUSER |
Opcional: vuelve a aplicar la inicialización (roles, esquemas y funciones auxiliares) antes de migrar |
Si una base de datos registrada no tiene conexión _MIGRATOR, se informa como fallo y nunca se omite. La capa web puede actualizarse cuando termina la base de datos de control. Si la base de datos de un tenant lleva una hora de retraso, se genera una advertencia; tras un día, una alerta de prioridad alta.
pgvector
A partir de la migración 0264, el corpus de fundamentación usa un índice pgvector HNSW si el servidor tiene la extensión; el servicio postgres de Compose se compila con ella (docker/postgres.Dockerfile). En el primer migrate después de cambiar las imágenes, la inicialización de superusuario crea la extensión y, a continuación, la migración 0264 añade una columna vectorial generada y crea el índice. La columna reescribe una vez app.ai_chunk con un bloqueo exclusivo, por lo que las solicitudes de fundamentación esperan; nada más toca esa tabla.
En un servidor sin pgvector, la migración 0264 muestra un aviso y no cambia nada, y la recuperación sigue siendo exacta. Si pgvector es anterior a la versión 0.8, se crean la columna y el índice, pero la recuperación sigue siendo exacta hasta que se actualiza la extensión (alter extension vector update), porque los recorridos HNSW filtrados requieren los recorridos iterativos de la versión 0.8. Para activarla más adelante en un servidor que no la tenga, instala la extensión, vuelve a ejecutar la inicialización (o create extension vector como superusuario) y luego, como quire_migrator, ejecuta:
set maintenance_work_mem = '1GB'; -- the HNSW build is much faster in memory
select ops.ai_chunk_enable_vector_index();Es idempotente y devuelve enabled o unavailable. Ejecútala también en cada base de datos de tenant dedicada.
Revertir
Siempre se puede revertir el código: establece QUIRE_RELEASE en la etiqueta anterior y vuelve a ejecutar up -d. Funciona porque, dentro de una versión, el esquema es compatible en ambos sentidos.
No se admite revertir el esquema. Esto es lo que no se puede deshacer y cómo recuperarse:
| No reversible | Recuperación |
|---|---|
| Una migración de contracción que eliminó una columna | Restauración a un momento anterior a la eliminación en una base nueva; después, extraer y combinar los datos |
| Un cambio de datos en el sitio | Lo mismo y, después, conciliar las escrituras posteriores |
| Webhooks y eventos enviados | Eventos compensatorios, nunca eliminaciones |
| Correo enviado | Una persona redacta el mensaje de seguimiento |
| Cadena hash de auditoría | No se reescribe nunca; se añade una entrada de corrección |
Por eso una migración de contracción se despliega sola: así, la restauración tiene un límite claro.
Comprobar la actualización
docker compose -f docker/compose.yaml ps # every service healthy
curl -fsS http://localhost:8080/readyz # ready, and what is configured
docker compose -f docker/compose.yaml logs migrate # the migrations applied