ADR-052: Operación — Prometheus en el manifiesto de producción, señal preservation y nombres neutros del almacén de objetos¶
Estado: Aceptado Fecha: 2026-10-22 Autores: Giampiero (mantenedor principal); bloque D-6 del lote D (deuda de C-8) Relacionados: ADR-041 (métricas; enmendado aquí: familia y señal), ADR-027 (RustFS; enmendado aquí: nombres), ADR-023 (WORM), ADR-043 (valoración), ADR-042 (reempaquetado)
Contexto¶
- Las reglas de alerta vivían solo en prosa (
deployment.md): nada comprobaba que nombraran familias que existen. Una alerta sobre una métrica inexistente no dispara nunca, y nadie lo nota. - Prometheus no estaba en el manifiesto. La red de producción es una sola (
orpycamcp-net, nointernal); meter allí a Prometheus le daría alcance a Postgres, Redis, Keycloak y al almacén sin necesitarlo. - Agotados que ninguna métrica veía: el reintento del sellado XAdES (
reconcile_agotadodel índice y de las actas de transferencia y de eliminación), la fixity PREMIS del acta (fixity_premis_agotado), el reempaquetado del AIP (reempaque_agotado, D-5) y la aplicación de la valoración (expediente_valoracion_hold.agotada, D-4). El operador no tenía cómo enterarse de que algo esperaba a un humano. - El nombre del motor anterior sobrevivía en las variables (
MINIO_*), en el servicio del compose y en la disposición del respaldo, justificado por «13 ficheros». Peor:extra="ignore"y los valores por omisión hacían que una variable vieja se ignorara en silencio: el almacén caía a su valor por omisión y la réplica secundaria del AIP, a local, sin aviso.
Decisión¶
1. Prometheus en infra/docker-compose.prod.yml, en una red propia internal¶
Red metricas-net (internal: true: sin gateway, ni entrada ni salida fuera de ella). En ella viven solo
Prometheus y los seis servicios con /metrics (auth, archive, workflow, notification, signature, knowledge),
que siguen además en orpycamcp-net. Alternativas descartadas: meterlo en orpycamcp-net (alcance a toda la pila) y
dejarlo fuera del manifiesto (estado anterior). Las cabeceras de proxy de ADR-041 son defensa en profundidad y no
sustituyen a la red.
- Imagen
prom/prometheuspor tag y digest (resuelto condocker buildx imagetools inspect). Sinportsniexpose; sin--web.enable-admin-apini--web.enable-lifecycle; configuración montada:ro; sistema de ficheros de solo lectura; retención de 30 días en el volumenprometheus-data. - Alertmanager no entra: el canal de aviso (correo, SMS, guardia) es decisión de la entidad. Las reglas se
evalúan y se consultan con
promtool(verdeployment.md). - Fuente única de las reglas:
infra/prometheus/alertas.yml(yprometheus.ymlcon los objetivos).deployment.mddeja de copiarlas y enlaza el fichero. - Guardianes:
shared/tests/test_prometheus_manifiesto.py(red, puertos, flags, censo de objetivos derivado del árbol, cadaexprsolo nombra familias del registro) y ampliación detest_manifiesto_prod_seguro.py.
2. Familia orpycamcp_preservation_exhausted_artifacts y señal preservation (enmienda ADR-041)¶
Se renombra orpycamcp_worm_exhausted_artifacts → orpycamcp_preservation_exhausted_artifacts y la señal
worm → preservation, porque sellado y fixity no son WORM. Sin compatibilidad (los datos son de prueba y
Prometheus no estaba desplegado). Fases (phase): reconcile, renewal, packaging (WORM), sealing,
fixity, repackaging y valuation; artefactos: los siete anteriores más expediente_valoracion.
Son 19 combinaciones (artefacto, fase); el 0 se emite cuando se midió, y «no verificado» sigue sin emitir series
de valor (ADR-041).
El censo (shared/tests/test_metricas_preservacion_censo.py) recalcula la lista desde las migraciones: toda columna
booleana *_agotad[oa] debe estar en el mapa columna→fase y tener su combinación, con límite de palabra para no
confundir reconcile_agotado (sellado) con worm_reconcile_agotado (WORM).
Declarado: fixity_premis_agotado no tiene reintento manual; la métrica avisa y la acción hoy es de base de
datos. Insumo para la épica siguiente (endpoint + tool). Las métricas son de operación, no de la entidad: el MCP
no debe exponerlas.
3. Nombres neutros del almacén de objetos, de una vez y sin alias (enmienda ADR-027)¶
| Antes | Después |
|---|---|
MINIO_ENDPOINT, _ACCESS_KEY, _SECRET_KEY, _USE_SSL, MINIO_SECONDARY_* |
OBJECTSTORE_… |
MINIO_ROOT_USER, MINIO_ROOT_PASSWORD (.env de infra) |
OBJECTSTORE_ROOT_USER, OBJECTSTORE_ROOT_PASSWORD |
MINIO_REGION, MINIO_SECURE (pruebas S3 y respaldo) |
OBJECTSTORE_REGION, OBJECTSTORE_USE_SSL |
servicio minio, contenedor orpycamcp-minio[-prod], DNS minio:9000 |
objectstore, orpycamcp-objectstore[-prod], objectstore:9000 |
respaldo: minio/, minio-versiones/, minio-retencion.tsv, minio-versiones.tsv, minio.tar.gpg, minio_objetos= |
objectstore/, objectstore-versiones/, objectstore-retencion.tsv, objectstore-versiones.tsv, objectstore.tar.gpg, objectstore_objetos= |
- Sin alias. Pero tampoco silencio: storage-service no arranca si el entorno o su
.envtraen cualquier variable del prefijo retirado (_variables_retiradas(); solo lee nombres, nunca valores), ybackup.sh/restore.shcortan con un mensaje que indica elsed.restore.shse niega ante un respaldo con la disposición anterior: reinterpretar nombres en una restauración es donde un error pasa por éxito. - Se conservan, porque describen con verdad lo que son: el volumen
minio-data(fondo del motor anterior, retenido por decisión de la entidad), los buckets (no llevan el nombre del motor; y renombrar un bucket con objetos COMPLIANCE no es posible), el módulominio_client.pyy la bibliotecaminiopy_async. - Guardián
shared/tests/test_sin_nombres_del_motor_anterior.py: niMINIO_(regex(?<![A-Z])MINIO_, que excluyeDOMINIO_), niminio:9000, nihttp://minioen código, pruebas, compose, CI e infraestructura, salvo los tres módulos que nombran el prefijo para rechazarlo.
Consecuencias¶
- Incompatible para quien despliegue: renombrar variables del
.env(sed -i 's/^MINIO_/OBJECTSTORE_/' <fichero>), recrear conup -d --build --remove-orphans(el contenedor viejo queda huérfano; el volumenobjectstore-datase reutiliza), y la familia/señal de métricas cambia de nombre (reglas y paneles propios deben actualizarse). - Los respaldos hechos antes de este cambio no se restauran con
restore.shsin renombrarlos a mano en una copia. - Pendiente (fuera de alcance, orden del usuario): rol propio del job de
audit_chain_runs.