OP.EXP.5 Gestión de Cambios - Procedimiento Formal ENS
Documentos de referencia
Normativa ENS
- Real Decreto 311/2022, Anexo II, OP.EXP.5
- CCN-STIC 804: Guía de implantación del ENS
- CCN-STIC 821: Normas de seguridad en el ENS
Estándares internacionales
- ISO/IEC 27000
- 27002:2013 - 12.1.2 Gestión de cambios
- 27002:2013 - 14.2.2 Procedimientos de control de cambios
- 27031:2011 - ICT readiness for business continuity
- ISO/IEC 20000-1:2018 - Service management system
- ITIL v4 - Change Management
Dispositivos médicos
- ISO 14971:2019 - Risk management for medical devices
- IEC 62304:2006 - Medical device software lifecycle
- MDR Art. 120 - Notificación de cambios sustanciales
- FDA 21 CFR 814.39 - Suplementos PMA para cambios
Otras referencias
- NIST SP 800-53 rev4: CM-4, CM-5, SI-2, SI-7
- SANS CIS Critical Security Controls v6.1
Propósito
Establecer un procedimiento formal y estructurado para la gestión de todos los cambios en los sistemas de información de Legit Health, garantizando:
- Cumplimiento con categoría MEDIA del ENS como PROVEEDOR de servicios sanitarios
- Control de cambios en dispositivo médico Clase IIa
- Trazabilidad completa y documentación adecuada
- Minimización de riesgos e impacto en la disponibilidad
- Validación clínica cuando sea requerida
Alcance
Este procedimiento aplica a todos los cambios en:
- Infraestructura tecnológica y cloud (AWS)
- Software del dispositivo médico y algoritmos de IA
- Configuraciones de seguridad ENS
- Arquitectura de red y comunicaciones
- Procesos y procedimientos del SGS
- Integraciones con sistemas externos
- Datos y modelos de aprendizaje automático
Guía de implantación ENS
El procedimiento para cambiar componentes del sistema requiere:
- Aprobación del responsable según matriz de autorización
- Documentación completa del cambio (RFC)
- Pruebas de seguridad en entorno no productivo
- Retención de versión previa (mínimo 30 días)
- Copias de seguridad de componentes (actual y anterior)
- Actualización del inventario de activos
- Actualización de procedimientos operativos
- Actualización del plan de continuidad
Clasificación de cambios
Matriz de clasificación ENS y dispositivo médico
Como sistema de categoría MEDIA y PROVEEDOR (no prestador directo), aplicamos controles proporcionales sin sobre-ingeniería. Los tiempos de respuesta y niveles de aprobación reflejan nuestro rol de apoyo al servicio sanitario.
Clasificacion_Cambios:
EMERGENCIA:
descripcion: "Cambios críticos para resolver incidentes activos"
impacto_ens: "Restauración inmediata de seguridad/disponibilidad"
impacto_clinico: "Riesgo para seguridad del paciente"
tiempo_respuesta: "< 4 horas"
aprobacion_minima:
- "CISO o delegado 24/7"
- "CMO (si afecta diagnóstico)"
CAB_requerido: false
documentacion: "Posterior en 24h"
validacion_clinica: "Post-implementación si aplica"
ejemplos:
- "Vulnerabilidad crítica explotada (CVSS >9)"
- "Fallo diagnóstico con riesgo paciente"
- "Brecha de datos de salud activa"
- "Caída total del servicio"
MAYOR:
descripcion: "Cambios con impacto significativo"
impacto_ens: "Modificación de controles de seguridad"
impacto_clinico: "Afecta funcionalidad diagnóstica"
tiempo_respuesta: "48-72 horas"
aprobacion_requerida:
- "CAB completo"
- "CISO"
- "CMO (Chief Medical Officer)"
- "QA/RA Manager"
CAB_requerido: true
documentacion: "Completa previa con análisis impacto"
validacion_clinica: "Requerida pre-implementación"
notificacion_regulatoria: "Si modifica intended use"
ejemplos:
- "Actualización algoritmo IA diagnóstico"
- "Cambio arquitectura seguridad"
- "Nueva integración clínica (HL7/FHIR)"
- "Migración infraestructura crítica"
- "Cambio umbrales decisión clínica"
NORMAL:
descripcion: "Cambios planificados impacto moderado"
impacto_ens: "Sin afectación a categorización"
impacto_clinico: "Sin impacto directo diagnóstico"
tiempo_respuesta: "5-10 días"
aprobacion_requerida:
- "CAB estándar"
- "Product Owner"
- "Responsable ENS"
CAB_requerido: true
documentacion: "Estándar con RFC"
validacion_clinica: "Testing regresión"
ejemplos:
- "Actualizaciones software no crítico"
- "Mejoras UX/UI"
- "Optimizaciones rendimiento"
- "Nuevas features secundarias"
MENOR:
descripcion: "Cambios bajo impacto"
impacto_ens: "Mínimo o nulo"
impacto_clinico: "Ninguno"
tiempo_respuesta: "Según sprint"
aprobacion_requerida:
- "Team Lead"
- "Notificación CAB"
CAB_requerido: false
documentacion: "Simplificada"
ejemplos:
- "Correcciones documentación"
- "Ajustes cosméticos"
- "Scripts mantenimiento"
- "Actualizaciones dependencias menores"
ESTANDAR:
descripcion: "Cambios pre-aprobados"
impacto_ens: "Controlado y conocido"
impacto_clinico: "Ninguno"
tiempo_respuesta: "Automático/programado"
aprobacion_requerida:
- "Pre-aprobado anualmente"
CAB_requerido: false
documentacion: "Registro automático"
ejemplos:
- "Renovación certificados SSL"
- "Rotación logs"
- "Backups programados"
- "Limpieza datos temporales"
Criterios de evaluación de impacto
# change_impact_evaluator.py
class ChangeImpactEvaluator:
def evaluate(self, change_request):
"""Evalúa impacto según ENS y MDR"""
impact_score = {
"ens_security": self.evaluate_ens_impact(change_request),
"clinical_safety": self.evaluate_clinical_impact(change_request),
"data_protection": self.evaluate_gdpr_impact(change_request),
"availability": self.evaluate_availability_impact(change_request),
"regulatory": self.evaluate_regulatory_impact(change_request)
}
# Clasificación automática basada en scores
if any(score >= 4 for score in impact_score.values()):
return "MAYOR"
elif any(score >= 3 for score in impact_score.values()):
return "NORMAL"
elif all(score <= 1 for score in impact_score.values()):
return "MENOR"
else:
return "NORMAL"
def evaluate_clinical_impact(self, cr):
"""Evalúa impacto en funcionalidad clínica"""
if cr.affects_diagnostic_algorithm:
return 5 # Crítico
elif cr.affects_clinical_data:
return 4 # Alto
elif cr.affects_clinical_workflow:
return 3 # Medio
else:
return 1 # Bajo
Change Advisory Board (CAB)
Composición del CAB
CAB_Composition:
Miembros_Permanentes:
- rol: "CTO"
responsabilidad: "Aprobación técnica"
voto: true
- rol: "CISO/Responsable Seguridad"
responsabilidad: "Validación seguridad ENS"
voto: true
- rol: "CMO/Responsable Clínico"
responsabilidad: "Validación clínica"
voto: true
- rol: "QA Manager"
responsabilidad: "Aseguramiento calidad MDR"
voto: true
- rol: "Responsable ENS"
responsabilidad: "Cumplimiento ENS"
voto: true
Miembros_Consultivos:
- rol: "DPO"
cuando: "Cambios con datos personales"
- rol: "Regulatory Affairs"
cuando: "Cambios con impacto regulatorio"
- rol: "Clinical Safety Officer"
cuando: "Cambios algoritmos IA"
Reuniones:
ordinarias: "Jueves 10:00 CET"
extraordinarias: "Según necesidad"
emergencia: "En 2 horas máximo"
quorum_minimo: "3 miembros con voto"
Proceso de decisión
Proceso de gestión de cambios
Solicitud de cambio (RFC)
// rfc_template.ts
interface RequestForChange {
// Identificación
id: string; // RFC-YYYY-MM-NNNN
solicitante: string;
fecha_solicitud: Date;
urgencia: "BAJA" | "MEDIA" | "ALTA" | "CRITICA";
// Clasificación ENS
tipo_cambio: "EMERGENCIA" | "MAYOR" | "NORMAL" | "MENOR" | "ESTANDAR";
categoria_ens: "INFRAESTRUCTURA" | "SOFTWARE" | "CONFIGURACION" | "PROCESO";
// Descripción
titulo: string;
descripcion_detallada: string;
justificacion_negocio: string;
justificacion_clinica?: string; // Si afecta dispositivo médico
// Análisis de impacto
componentes_afectados: string[];
servicios_impactados: string[];
usuarios_afectados: number;
tiempo_indisponibilidad: number; // minutos
// Riesgos ENS
analisis_riesgos: {
probabilidad: 1 | 2 | 3 | 4 | 5;
impacto: 1 | 2 | 3 | 4 | 5;
rpn: number; // Probabilidad × Impacto
medidas_mitigacion: string[];
};
// Plan de implementación
fecha_propuesta: Date;
duracion_estimada: number; // horas
plan_implementacion: Step[];
plan_validacion: ValidationPlan;
plan_rollback: RollbackPlan;
// Validación clínica (si aplica)
validacion_clinica_requerida: boolean;
tipo_validacion?: "REGRESSION" | "CLINICAL_STUDY" | "EXPERT_REVIEW";
protocolo_validacion?: string;
// Trazabilidad
incidentes_relacionados?: string[]; // INC-XXXX
riesgos_relacionados?: string[]; // Del R-TF-013-002
prs_requirements?: string[]; // Códigos PRS afectados
// Aprobaciones
aprobaciones_requeridas: Approver[];
estado_aprobacion: "PENDIENTE" | "APROBADO" | "RECHAZADO" | "DIFERIDO";
}
Evaluación y aprobación
# change_approval_workflow.py
class ChangeApprovalWorkflow:
def process_rfc(self, rfc):
"""Procesa RFC según procedimiento ENS"""
# 1. Validación inicial
validation = self.validate_rfc(rfc)
if not validation.is_valid:
return self.reject_rfc(rfc, validation.errors)
# 2. Clasificación automática
rfc.classification = self.classify_change(rfc)
# 3. Análisis de impacto ENS
impact_analysis = self.analyze_ens_impact(rfc)
# 4. Verificación cumplimiento
compliance_check = self.check_compliance(rfc)
# 5. Determinar aprobadores
approvers = self.determine_approvers(rfc)
# 6. Si requiere CAB
if rfc.classification in ["MAYOR", "NORMAL"]:
cab_decision = self.schedule_cab_review(rfc)
# 7. Validación técnica
technical_validation = self.technical_review(rfc)
# 8. Validación clínica si aplica
if rfc.clinical_validation_required:
clinical_validation = self.clinical_review(rfc)
# 9. Decisión final
return self.make_decision(rfc, all_validations)
Implementación de cambios
Procedimiento de implementación
# change_implementation.py
class ChangeImplementation:
def implement(self, approved_rfc):
"""Implementa cambio aprobado según ENS"""
implementation_log = {
"rfc_id": approved_rfc.id,
"start_time": datetime.utcnow(),
"environment": "PRODUCTION",
"steps": []
}
try:
# 1. Verificaciones pre-implementación
self.pre_implementation_checks(approved_rfc)
# 2. Crear punto de restauración
restore_point = self.create_restore_point()
# 3. Notificar usuarios afectados
self.notify_affected_users(approved_rfc)
# 4. Activar ventana de mantenimiento
self.activate_maintenance_window(approved_rfc)
# 5. Ejecutar pasos de implementación
for step in approved_rfc.implementation_steps:
result = self.execute_step(step)
implementation_log["steps"].append(result)
# Verificar salud del sistema
if not self.verify_system_health():
raise ImplementationError("System health check failed")
# 6. Validación post-implementación
validation = self.post_implementation_validation(approved_rfc)
# 7. Validación clínica si aplica
if approved_rfc.clinical_validation_required:
clinical_validation = self.validate_clinical_functionality()
# 8. Actualizar documentación
self.update_documentation(approved_rfc)
# 9. Actualizar inventario ENS
self.update_ens_inventory(approved_rfc)
# 10. Cerrar ventana de mantenimiento
self.close_maintenance_window()
implementation_log["status"] = "SUCCESS"
except Exception as e:
# Activar rollback
self.execute_rollback(restore_point, approved_rfc)
implementation_log["status"] = "FAILED"
implementation_log["rollback_executed"] = True
implementation_log["error"] = str(e)
# Notificar fallo
self.notify_implementation_failure(approved_rfc, e)
# Crear incidente si es crítico
if approved_rfc.classification == "EMERGENCIA":
self.create_incident(approved_rfc, e)
raise
finally:
# Documentar resultado
self.document_implementation(implementation_log)
return implementation_log
Validación y verificación
Validation_Requirements:
Funcional:
- "Pruebas de regresión completas"
- "Verificación casos de uso críticos"
- "Validación integraciones"
Seguridad_ENS:
- "Scan vulnerabilidades"
- "Verificación configuraciones seguridad"
- "Test de penetración (cambios MAYOR)"
- "Validación controles ENS afectados"
Rendimiento:
- "Pruebas de carga"
- "Verificación tiempos respuesta"
- "Monitorización recursos"
Clinica_MDR:
- "Validación algoritmos diagnóstico"
- "Verificación umbrales decisión"
- "Test dataset validación"
- "Revisión por CMO"
Documentacion:
- "Actualización manual usuario"
- "Actualización procedimientos"
- "Registro en DHF (Design History File)"
- "Actualización risk management file"
Gestión de rollback
Plan de rollback
# rollback_manager.py
class RollbackManager:
def create_rollback_plan(self, rfc):
"""Crea plan rollback específico ENS"""
rollback_plan = {
"rfc_id": rfc.id,
"trigger_conditions": [
"Fallo crítico en producción",
"Pérdida integridad datos",
"Brecha seguridad detectada",
"Fallo validación clínica",
"Degradación rendimiento >50%"
],
"max_rollback_time": self.calculate_rollback_time(rfc),
"steps": self.generate_rollback_steps(rfc),
"validation": self.define_rollback_validation(rfc),
"data_recovery": self.plan_data_recovery(rfc)
}
return rollback_plan
def execute_rollback(self, rollback_plan, reason):
"""Ejecuta rollback según procedimiento ENS"""
# Notificar inicio rollback
self.notify_rollback_start(rollback_plan, reason)
# Ejecutar pasos rollback
for step in rollback_plan.steps:
self.execute_rollback_step(step)
# Validar integridad sistema
self.validate_system_integrity()
# Documentar rollback
self.document_rollback(rollback_plan, reason)
# Crear informe post-mortem
self.create_post_mortem_report(rollback_plan)
Control de versiones
Esquema de versionado
Version_Control_Scheme:
Formato: "MAJOR.MINOR.PATCH.BUILD"
Incremento_Version:
MAJOR:
- "Cambios breaking en API"
- "Nueva funcionalidad clínica mayor"
- "Cambio arquitectura fundamental"
MINOR:
- "Nueva funcionalidad compatible"
- "Mejoras significativas"
- "Nuevas integraciones"
PATCH:
- "Corrección bugs"
- "Parches seguridad"
- "Mejoras menores"
BUILD:
- "Número automático CI/CD"
Git_Tags:
formato: "v{MAJOR}.{MINOR}.{PATCH}"
anotaciones:
- "Release notes"
- "Estado validación clínica"
- "Aprobación regulatoria"
- "Checksum artefactos"
Trazabilidad de cambios
-- change_tracking_schema.sql
CREATE TABLE change_log (
rfc_id VARCHAR(20) PRIMARY KEY,
change_date TIMESTAMP NOT NULL,
change_type ENUM('EMERGENCIA','MAYOR','NORMAL','MENOR','ESTANDAR'),
version_before VARCHAR(20),
version_after VARCHAR(20),
components_affected JSON,
clinical_impact BOOLEAN,
ens_controls_affected JSON,
approvers JSON,
implementation_time INTEGER,
rollback_executed BOOLEAN,
success BOOLEAN,
post_mortem_required BOOLEAN,
regulatory_notification BOOLEAN,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Índices para reporting
CREATE INDEX idx_change_date ON change_log(change_date);
CREATE INDEX idx_change_type ON change_log(change_type);
CREATE INDEX idx_clinical_impact ON change_log(clinical_impact);
CREATE INDEX idx_success ON change_log(success);
Métricas e indicadores KPI
KPIs de gestión de cambios
Indicador | Fórmula | Objetivo MEDIA | Frecuencia |
---|---|---|---|
Tasa éxito cambios | (Cambios exitosos / Total cambios) × 100 | > 95% | Mensual |
Tasa éxito primera vez | (Éxito sin rollback / Total) × 100 | > 90% | Mensual |
Tasa rollback | (Rollbacks / Total cambios) × 100 | < 5% | Mensual |
Tiempo medio implementación | Σ(Tiempo implementación) / N | < 4 horas | Mensual |
Cambios de emergencia | (Emergencias / Total) × 100 | < 10% | Mensual |
Cumplimiento CAB | (Con CAB requerido / Total que requieren) × 100 | 100% | Mensual |
Documentación completa | (RFC completos / Total RFC) × 100 | 100% | Mensual |
Cambios no autorizados | Número absoluto | 0 | Mensual |
Incidentes por cambios | (Incidentes causados / Total cambios) × 100 | < 2% | Trimestral |
Validación clínica exitosa | (Validaciones OK / Total requeridas) × 100 | 100% | Trimestral |
Dashboard de monitorización
# change_metrics_dashboard.py
class ChangeMetricsDashboard:
def generate_monthly_report(self, month, year):
"""Genera informe mensual gestión cambios ENS"""
report = {
"period": f"{year}-{month:02d}",
"total_changes": self.count_total_changes(month, year),
"by_type": {
"emergency": self.count_by_type("EMERGENCIA"),
"major": self.count_by_type("MAYOR"),
"normal": self.count_by_type("NORMAL"),
"minor": self.count_by_type("MENOR"),
"standard": self.count_by_type("ESTANDAR")
},
"success_metrics": {
"success_rate": self.calculate_success_rate(),
"first_time_success": self.calculate_first_time_success(),
"rollback_rate": self.calculate_rollback_rate(),
"unauthorized_changes": self.count_unauthorized()
},
"compliance_metrics": {
"cab_compliance": self.calculate_cab_compliance(),
"documentation_completeness": self.check_documentation(),
"ens_compliance": self.verify_ens_compliance()
},
"clinical_metrics": {
"clinical_validations": self.count_clinical_validations(),
"validation_success_rate": self.clinical_success_rate()
},
"trends": self.calculate_trends(month, year),
"recommendations": self.generate_recommendations()
}
return report
Integración con otros controles ENS
Matriz de integración
Control ENS | Integración con OP.EXP.5 |
---|---|
OP.EXP.1 | Actualización automática inventario post-cambio |
OP.EXP.2 | Verificación configuración seguridad |
OP.EXP.3 | Mantenimiento según ventanas aprobadas |
OP.EXP.4 | Coordinación ventanas mantenimiento |
OP.EXP.7 | Gestión incidentes que requieren cambios |
OP.EXP.8 | Registro detallado de cambios |
OP.CONT | Actualización plan continuidad |
MP.SI | Verificación integridad post-cambio |
ORG.2 | Aprobación según roles y responsabilidades |
Procedimientos específicos dispositivo médico
Cambios que requieren notificación regulatoria
Regulatory_Notification_Required:
MDR_Article_120:
- "Cambio en intended use"
- "Modificación indicaciones clínicas"
- "Cambio en población objetivo"
- "Nuevo riesgo identificado"
FDA_510k_Supplement:
- "Cambio algoritmo diagnóstico principal"
- "Nueva funcionalidad clínica"
- "Modificación arquitectura sistema"
Vigilancia_Post_Mercado:
- "Corrección seguridad crítica"
- "Actualización por incidente reportado"
- "Mejora basada en datos clínicos"
Validación clínica obligatoria
# clinical_validation_requirements.py
class ClinicalValidationRequirements:
def requires_clinical_validation(self, rfc):
"""Determina si cambio requiere validación clínica"""
validation_triggers = [
"algorithm_modification",
"threshold_change",
"ai_model_update",
"clinical_decision_support_change",
"diagnostic_criteria_modification",
"new_clinical_feature"
]
for component in rfc.affected_components:
if any(trigger in component for trigger in validation_triggers):
return True
return False
def determine_validation_type(self, rfc):
"""Determina tipo de validación requerida"""
if rfc.affects_core_diagnostic:
return "FULL_CLINICAL_STUDY"
elif rfc.affects_ai_model:
return "VALIDATION_DATASET_TEST"
elif rfc.affects_clinical_workflow:
return "USABILITY_STUDY"
else:
return "REGRESSION_TESTING"
Plantillas y formularios
Enlaces a plantillas
- [RFC-TEMPLATE]: Plantilla solicitud de cambio
- [CAB-MINUTES]: Plantilla acta CAB
- [ROLLBACK-PLAN]: Plantilla plan rollback
- [VALIDATION-REPORT]: Plantilla informe validación
- [POST-MORTEM]: Plantilla análisis post-mortem
Referencias
Documentación interna
- GP-005: Control de cambios QMS
- GP-110: Ciberseguridad ENS
- R-TF-013-002: Registro gestión riesgos
- R-024-013: Registro cambios implementados
Guías externas
- CCN-STIC 804: Implementación ENS
- ITIL v4 Change Management
- ISO/IEC 20000-1:2018
Control del documento
- Versión: 2.0.0
- Fecha: 2024-11-15
- Autor: Responsable ENS
- Revisado por: CISO, CMO, QA Manager
- Aprobado por: Comité de Seguridad
- Próxima revisión: 2025-11-15
Signature meaning
The signatures for the approval process of this document can be found in the verified commits at the repository for the QMS. As a reference, the team members who are expected to participate in this document and their roles in the approval process, as defined in Annex I Responsibility Matrix
of the GP-001
, are:
- Author: Team members involved
- Reviewer: JD-003, JD-004
- Approver: JD-001