metis-desk/docs/architecture/preflight-activacion-catalogo-global-sistemas-operativos.md
David c863cc6d96 feat: add unpublished share component and publication operation summary
- Introduced `UnpublishedShare` component for displaying empty state with actions for assigning and viewing history.
- Added `PublicationOperationSummary` component to summarize publication context and actions based on the current state.
- Implemented `CompanyNetworkShareDetail` to manage and display network share details for companies.
- Created `NetworkShareResourceTitle` for collapsible display of resource names with accessibility features.
- Developed `ResourceDetailActions` for managing resource actions like edit, activate/deactivate, and delete.
- Added `ResourceRevisionHistory` to display the history of resource revisions with detailed information.
- Implemented a comprehensive audit script for network share detail UI, including accessibility checks and error handling.
2026-10-26 18:45:30 +01:00

62 KiB
Raw Blame History

Preflight de activación — Catálogo global de sistemas operativos

Fecha: 26 de octubre de 2026, Europe/Madrid. Inspección iniciada el día 25. Ámbito: repositorio local, diagnósticos y corrección con MariaDB desechable en el apartado 17. No se ha conectado a producción, leído .env, ejecutado migraciones productivas, modificado datos reales, cambiado gates ni desplegado.

Dictamen vigente: apartado 17, corrección local sobre a72d6a2ec8985e1d51f74db68a1b3aabb3693030: B-01 RESUELTO, B-02 RESUELTO EN ENTORNO REPRESENTATIVO; snapshot global NO PREPARADO. Los apartados 1–16 conservan los diagnósticos históricos anteriores a esta corrección. El apartado 17 añade las pruebas con persistencia exclusivamente desechable y distingue los cambios concurrentes.

1. Resumen y dictamen

NO PREPARADO para desplegar el artefacto de producción evaluado. Se conserva la correspondencia de fuentes con el GO técnico, pero el preflight descubre dos bloqueos de ejecución/configuración que ese GO no había ensayado:

  1. B-01, demostrado: apps/server/dist/index.js no supera node --check: SyntaxError: Identifier 'createRequire' has already been declared. El banner de apps/server/tsup.config.ts declara createRequire; el bundle vuelve a importarlo al incluir sharp 0.35.5. Dos builds forzados terminan con éxito y generan los mismos bytes, pero el servidor compilado es sintácticamente inválido. No puede desplegarse ese bundle aunque tsup devuelva cero.
  2. B-02, demostrado para la topología TLS → HTTP: el entrypoint escucha HTTP en loopback; en producción la sesión exige cookie Secure, pero createApp no configura trust proxy y express-session no configura proxy. En un diagnóstico local con X-Forwarded-Proto: https, request.secure=false y no se emite cookie de sesión. No se ha comprobado la topología real del destino; no se presupone que exista una solución externa no versionada.

El GO previo sigue siendo evidencia de los escenarios de fuentes/HTTP/MariaDB/UI ensayados, no certifica el arranque de este artefacto de producción ni el entorno desconocido. B-01 impide el despliegue con independencia de que el origen del defecto esté fuera del catálogo SO. No se corrigen estos bloqueos aquí: la misión prohíbe cambios funcionales salvo diagnósticos no invasivos.

Se deja preparado el expediente y el runbook para una autorización futura. No procede solicitar autorización de activación mientras B-01 y la solución aplicable a B-02 sigan abiertos. Después harán falta verificaciones del destino.

2. Fuentes y método

Consultados: cierre técnico y resolución del GO, auditoría, decisión SO, implementación, documentación R2.0–R2.6 —en particular despliegue, persistencia R2.1b, software, perfiles, coexistencia—, estado D08.2, composición modular, puesta en marcha y acceso.

Se aplicó rdx-solid, incluida su referencia backend: contrato del artefacto, composición, seguridad y diferencias verificables. No se aplicaron criterios nuevos de diseño UI ni se instalaron dependencias. Las fuentes documentales históricas se contrastaron con los gates y endpoints actuales; sus flags propuestos no sustituyen los ya implementados.

Estados: VERIFICADO = evidencia directa con el alcance indicado; PENDIENTE DE VERIFICACIÓN = falta evidencia del destino; NO CUMPLE = fallo observado; NO APLICA = capacidad ajena o deliberadamente inexistente.

3. Snapshot y reproducción exacta — hito A

Requisito Estado Evidencia
Base Git VERIFICADO main, d2bf856c973419277f0b30f6437242cd82f7d720
HEAD representa por sí solo el GO NO CUMPLE El GO incluye cambios sin commit, incluidos ficheros nuevos
Identificación del estado completo del GO VERIFICADO Coinciden los hashes de 1884 fuentes y 40 archivos de trabajo con sus manifiestos
Reconstrucción VERIFICADO Base Git más overlay de esos 40 archivos restaurados en /tmp; se verifican todas las huellas y el lockfile; directorio retirado
Cambios posteriores funcionales en el snapshot registrado VERIFICADO: ninguno Comparación de hashes, no solo git diff HEAD
Node / PNPM VERIFICADO 24.20.0 / 11.25.0; engines >=24 <25, packageManager=pnpm@11.25.0
Lockfile VERIFICADO pnpm-lock.yaml sin diferencias frente a HEAD; SHA-256 bcd468ab1f127fffeb7f37ef3bdb5f2c5e85d40c192f3bc4a7cae5b2209b7c17
Dependencias del candidato VERIFICADO en manifests/lock Express 4.22.1, Sequelize 6.37.8, MariaDB driver 3.5.4, sharp 0.35.5, React 19.2.5, Vite 8.3.0
Instalación limpia de dependencias para el destino PENDIENTE DE VERIFICACIÓN No se ejecuta install ni se cambia node_modules; los builds usan la instalación local existente
Builds VERIFICADO como compilación Dos ejecuciones pnpm exec turbo run build --force, sin caché; 12 artefactos idénticos byte a byte
Correspondencia del frontend con MCP VERIFICADO apps/web/dist coincide byte a byte con web-build conservado de authenticated-6u28upls
Ejecución sintáctica del servidor compilado NO CUMPLE B-01, node --check devuelve 1

Evidencias en preflight: traceability.json, go-source-overlay.tar, build-first.json, build-second.json y nondeployable-build.tar. El último conserva exclusivamente los archivos dist diagnosticados: no es un paquete desplegable, no incorpora dependencias runtime ni una configuración aprobada del destino. Los sourcemaps requieren política de publicación; no deben exponerse sin decisión del operador.

Para reproducir las fuentes: checkout separado de la base indicada, aplicar go-source-overlay.tar en su raíz y comprobar los hashes de source-snapshot.json y workingSources del manifiesto del GO. El overlay tiene solo rutas relativas y fuentes aprobadas, sin secretos. El ensayo de reconstrucción restaura los archivos requeridos desde los objetos Git y aplica el overlay; no equivale a un build en un checkout limpio con dependencias recién instaladas.

Además del snapshot hay evidencias regeneradas .artifacts/ y un .pyc del trabajo concurrente, sin efecto funcional. Este preflight añade el informe, SQL no ejecutado y evidencia local. No modifica las 1884 fuentes/40 archivos del GO. No se sobrescribe trabajo concurrente.

4. Inventario del entorno de destino

No se ha identificado un destino de producción mediante manifests operativos autorizados. compose.yaml y la guía de puesta en marcha describen desarrollo WSL y una BD local; no prueban infraestructura desplegada.

Componente Confirmado en repositorio Estado del destino
Backend ESM Node 24, apps/server/dist/index.js, dependencias runtime externas; HTTP 127.0.0.1:PORT PENDIENTE DE VERIFICACIÓN de host/supervisor/instancias; B-01 NO CUMPLE
Frontend Estáticos apps/web/dist; API compilada no los sirve PENDIENTE DE VERIFICACIÓN de hosting, caché y fallback SPA
MariaDB Compose declara mariadb:11.8, volumen persistente y puerto de loopback; tests usaron 11.8.9 PENDIENTE DE VERIFICACIÓN de motor/patch/esquema/capacidad; no consultar compose efectivo
Reverse proxy/TLS No se localizó manifest de proxy, TLS o despliegue productivo PENDIENTE DE VERIFICACIÓN; B-02 para terminación TLS y HTTP al backend
Sesiones express-session, SequelizeSessionStore; cookie metis.sid, HttpOnly, SameSite Strict, 8 horas, Secure en producción PENDIENTE DE VERIFICACIÓN de acceso real, rotación de secreto y comportamiento entre instancias
Autenticación/administración Identity y guard requireGlobalResourceManager; administrador inicial, sin RBAC ficticio de compañía PENDIENTE DE VERIFICACIÓN de responsables y cuentas autorizadas; no extraer datos personales
Auxiliares Procesamiento de imágenes con sharp, persistencia de sesión, limpieza de recursos al apagar PENDIENTE DE VERIFICACIÓN de binarios/arquitectura/permisos runtime
Despliegue/backup/restore Procedimientos R2 conceptuales; la guía declara despliegue, HTTPS y backups pendientes PENDIENTE DE VERIFICACIÓN de procedimiento, ventana, recuperación y prueba de restauración

pnpm --filter @metis/server start carga .env; no se ejecutó. pnpm db:up prepara entorno y arranca BD; tampoco se ejecutó. Arrancar el backend no es una inspección de solo lectura: compone módulos, ejecuta migraciones existentes y seed. No usarlo como prueba inocua contra el destino.

5. Configuración real y gates

Fuente: apps/server/src/config/database.ts, config/env-schema.ts, identity-runtime.ts, modules/resources/src/api/module.ts y resource-global-gates.ts. Todos los valores efectivos del destino son PENDIENTE DE VERIFICACIÓN; no se deducen de defaults ni de pruebas aisladas.

Gate Default en código Propósito y dependencias Propuesta / riesgo
RESOURCE_GLOBAL_OS_CATALOG_ENABLED false Alta/edición/reactivación SO administrativas; scoped, integridad y autorización Etapa 0 false; etapa 1 true. Abre publicación, no solo borradores
RESOURCE_GLOBAL_OS_SOFTWARE_ENABLED false Selección y nueva asociación SO, requiere OS_CATALOG False hasta operación autorizada; true abre ambas capacidades juntas
RESOURCE_GLOBAL_CATALOG_ENABLED false Administración application; requisito de gates application Conservar valor previamente aprobado; no es dependencia de SO
RESOURCE_GLOBAL_SOFTWARE_ENABLED false Nueva asociación application, requiere CATALOG Conservar autorización independiente
RESOURCE_GLOBAL_SOFTWARE_CANDIDATES_ENABLED false Candidatos application, requiere CATALOG No concede asociación por sí solo; no controla candidatos SO
RESOURCE_GLOBAL_PROFILE_ENABLED false Application en perfiles, requiere CATALOG Conservar autorización; jamás abre SO en perfil
administration interno true Capacidad adicional sometida al guard de Identity NO APLICA como variable de entorno; no sustituye permisos

Otros parámetros reales: DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD, SESSION_SECRET (mínimo 32 caracteres), APP_ORIGIN, NODE_ENV y PORT (default 3001, rango 1–65535). Registrar únicamente presencia, validación y coherencia; no valores secretos ni cadena de conexión. APP_ORIGIN debe corresponder al origen externo permitido; NODE_ENV=production exige Secure, sujeto a B-02. API_PROXY_TARGET pertenece al proxy de desarrollo Vite y no configura un proxy de producción.

No hay variable de disponibilidad que sustituya el estado real de Resources ni flag que aplique scope. El arranque inspecciona legacy/scoped/parcial; con catálogo global habilitado exige scoped completo y CHECK/FK activos a nivel sesión/global. No inventar variables TRUST_PROXY, versiones contractuales o gates por compañía: no están implementadas en este snapshot.

6. Precondiciones MariaDB — hito C

Requisito Esperado por código/migración Estado real del destino
Motor y versión MariaDB; referencia ensayada 11.8.9; InnoDB y driver Sequelize v6 PENDIENTE DE VERIFICACIÓN
resources.scope VARCHAR(7), ascii/ascii_bin, NOT NULL, DEFAULT company PENDIENTE DE VERIFICACIÓN
resources.companyId CHAR(36), utf8mb4_bin, nullable exclusivamente con scope global coherente PENDIENTE DE VERIFICACIÓN
CHECK resource_scope_owner y resource_global_no_integration, cláusulas exactas del inspector; sesión/global activos PENDIENTE DE VERIFICACIÓN
FKs e índices PK/owners/plantillas/especificaciones/revisiones; FKs operativas preservadas y activas PENDIENTE DE VERIFICACIÓN
Especificaciones y EAV resource_characteristics, resource_specification_fields, resource_specification_field_choices, secciones, revisiones y especificaciones históricas relacionadas PENDIENTE DE VERIFICACIÓN
Instalaciones software_installations, FKs a compañía/activo/producto/licencia, currentKey único; propietario no nullable PENDIENTE DE VERIFICACIÓN
Historial software_installation_revisions, FK a instalación, único (configurationId, position); Resource único (resourceId, position) PENDIENTE DE VERIFICACIÓN
Scope aplicado R2.1b explícita: scope, ownerCheck, integrationCheck, nullableOwner; no confiar en un fichero como prueba de aplicación PENDIENTE DE VERIFICACIÓN
Datos preexistentes Cero owners/referencias inválidas; particulares incompletos permitidos; inactivos utilizados conservados PENDIENTE DE VERIFICACIÓN
Integridad aislada previa 29/29 + 50/50 y cero revisiones huérfanas en el GO VERIFICADO como antecedente aislado, no como esquema del destino

El inspector resource-scope-schema.ts compara tipos, nulabilidad, default, charset y texto normalizado de los CHECK. Legacy sin scope puede leerse con gates cerrados; no habilitar globales. Un esquema parcial debe detener el servicio y reanudarse mediante el procedimiento R2.1b autorizado. No ejecutar el CLI como diagnóstico: exige --apply --writes-paused y realiza DDL. Ninguna migración se ejecutó en este preflight.

Se preparó diagnostico-mariadb.sql, solo SELECT y no ejecutado. Fase 1 consulta versión/metadatos; el operador debe confirmar tablas y scoped antes de la fase 2. Fase 2 devuelve recuentos de plantilla/bindings, identidad incompleta, SO global/particular, instalaciones/revisiones por scope/estado, inactivos usados y referencias inválidas. Las instalaciones por compañía se expresan como histograma de volúmenes, sin UUID/nombres. No extraer valores comerciales, inventarios o datos personales al informe.

Ejecutar únicamente tras autorización específica de lectura, con credencial de mínimo privilegio, límites de tiempo/carga y procedimiento aprobado del operador. No se incluye una contraseña en comandos ni se presume un nombre de base destino. Las consultas se contrastaron estáticamente con el DDL guardado del GO, no con MariaDB real en esta intervención. Recuentos de identidad son diagnósticos orientativos: no sustituyen toda la policy semántica ni la revisión de duplicados.

7. Plantilla SO y posibles instalaciones legacy

La stock template:os conserva UUID y campos existentes. El seed comprueba ausencia de field:os_edition_state para decidir la evolución; añade bindings opcionales de os_family, os_product_version y os_edition_state y conserva los originales/personalizaciones. provider y software_edition ya existían. Estados: known, not_applicable, unknown; publicación requiere identidad válida. No rellenar particulares antiguos con valores ficticios.

El marcador de campo existente no demuestra por sí solo que todos los bindings del destino sean correctos: una edición manual o evolución incompleta necesita diagnóstico, no borrado del marcador. El arranque siembra catálogo aun con gates SO cerrados; estos gates no son un interruptor del seed o de todas las migraciones. Evolución doble y conservación fueron probadas en aislamiento, no sobre el destino. Copias de plantillas SO no adquieren elegibilidad global. No hay DDL específico nuevo de SO ni autorización para D08.2.

8. Contratos y lectores — hito D

Cabecera real: x-metis-resources-contract, valores soportados explícitos 2 y 3. No existe flag de entorno para negociar la versión. El navegador actual solicita contrato 3 en los consumidores mixtos.

Contexto Cliente sin versión v2 v3
Respuesta compatible exclusivamente particular Compatibilidad local ensayada Compatible Compatible
Contexto que exige referencias application global 409 de actualización cuando corresponde Compatible por propósito Compatible por propósito
Colección/referencia de software que requiere SO global 409 RESOURCE_CLIENT_UPGRADE_REQUIRED, sin recortar filas Igual 409 DTO SO válido
SO global como ApplicationConfiguration Rechazado por propósito Rechazado Rechazado
Versión explícita no soportada, como 4 NO APLICA NO APLICA HTTP 400 para petición con esa versión

SO público: kind=os, scope=global, companyId=null, identidad y enlace SO; application conserva su DTO/tipo, listado y enlaces. Los particulares conservan pertenencia. Capabilities v2 conserva cuatro claves anteriores; v3 incorpora capacidad SO. Autorización/CSRF/compañía se verifican en servidor, no por esa cabecera.

Los clientes realmente desplegados son PENDIENTE DE VERIFICACIÓN: inventariar navegadores con JS cacheado, API consumers, tareas y todas las instancias backend. Actualización coordinada y recarga/control de caché antes de nuevas asociaciones SO. No mezclar backend incapaz de leer SO global con referencias ya persistidas.

Cerrar gates de nuevas dependencias conserva lectura de catálogo, UUID, instalaciones/historial y navegación a inactivos; permite notas/retirada legítima según estado y contrato. El gate cerrado no abre edición administrativa del producto. Desactivación administrativa de seguridad y replay idempotente tienen sus reglas propias; no se afirma que todos los POST queden bloqueados. Esta garantía procede de las pruebas previas; debe verificarse también en el destino autorizado.

9. Secuencia progresiva propuesta

Bloqueada por B-01/B-02 y verificaciones del destino. No se ejecuta. Todos los cambios de configuración requieren autorización explícita futura.

Etapa Configuración SO Operación propuesta y previos Smoke / avance Abortar y reversión
0 preparación OS_CATALOG=false, OS_SOFTWARE=false Corregir/validar artefacto y TLS/sesiones; fijar release, dependencias, backup/restore, scope; desplegar lectores v3 y frontend coordinados solo tras autorización Salud, login persistente, lectura local/global existente, tipos/UUID/historial; cero inconsistencias No abrir flags; detener rollout si falla arranque, sesión o integridad; mantener lectores compatibles
1 administración OS_CATALOG=true, OS_SOFTWARE=false Administrador autorizado puede crear/editar/revisar/publicar productos aprobados; revisar evolución y elegibilidad antes Alta/revisión autorizadas; lectura ordinaria; nuevos candidatos/asociaciones SO aún cerrados Cerrar OS_CATALOG; conservar productos/historial; desactivar producto incorrecto con permisos
2 selección y 3 operación OS_CATALOG=true, OS_SOFTWARE=true Habilitación conjunta de candidatos y asociación; mismos checks que etapa 1 más clientes v3 y activo/compañía autorizados Canario autorizado: selección, instalación, versión, activo/puesto, historia y negativos de licencia/perfil Cerrar OS_SOFTWARE y después OS_CATALOG; comprobar lectura/retirada; no borrar filas

No hay separación técnica entre selección SO y asociación SO. No usar SOFTWARE_CANDIDATES de aplicaciones para fingirla. Tampoco hay gate por compañía: un canario limitado a una compañía es un procedimiento operativo, no aislamiento por flag. Acordar quién puede escribir durante esa ventana y cómo se limita el alcance; si no puede limitarse, no anunciar un piloto restringido.

Orden obligatorio: persistencia preparada → backend con lectores v3 → frontend/consumidores compatibles → administración → nuevas asociaciones → verificación. La evolución se ejecuta durante el arranque y puede escribir con flags cerrados, por lo que ese arranque requiere ventana/autorización, no solo permiso de lectura. Mantener los otros cuatro gates según su autorización propia; no modificarlos como efecto secundario de SO.

10. Smoke tests operativos preparados

No ejecutados sobre destino. Usar sesión real sin copiar cookies/tokens a logs, y registrar código HTTP/requestId/resultados, sin contenido sensible. GET puede tocar la sesión; «lectura» significa sin cambio de negocio, no promesa de cero escrituras técnicas en el servidor.

Tipo Comprobación y ruta real Resultado esperado
Lectura Login y persistencia con cuenta autorizada a través del origen HTTPS Cookie Secure/HttpOnly y sesión mantenida; B-02 resuelto
Lectura GET /api/resource-global-operating-systems y /api/resource-global-applications 200 autenticado, tipos separados, sin datos administrativos expuestos
Lectura GET /api/resource-global-operating-systems/:id UUID/SO activo o inactivo legible, destino correcto
Lectura GET /api/resource-application-candidates/:companyId/capabilities, contrato 3 Capabilities acordes con etapa; no equivale a permiso administrativo
Lectura GET /api/resource-application-candidates/:companyId?purpose=software-installation, contrato 3 Solo candidatos activos/elegibles; SO global aparece únicamente en etapa operativa
Lectura, aunque use POST POST /api/resource-application-references/:companyId/resolve, cuerpo { "purpose": "software-installation", "ids": ["UUID aprobado"] }, contrato 3 Referencia SO resuelta por propósito; petición de resolución sin mutación de negocio
Lectura GET /api/software-installations/:companyId, contrato 3; ficha activo/puesto e historial desde UI Instalaciones/versiones/estado/historia existentes completos; rutas global/particular correctas
Lectura Repetir contexto con SO global usando v2/sin cabecera 409 explícito; no respuesta truncada
Escritura, autorización separada Instalar producto aprobado en activo de pruebas ya existente y autorizado, desde diálogo normal Instalación propia; versión en activo/puesto; historial correcto
Escritura negativa, autorización separada Intentar SO en perfil de aplicaciones Rechazo, sin configuración persistida
Escritura negativa, autorización separada Intentar licencia de otra compañía en instalación Rechazo, asociación previa intacta; permiso de prueba no supone acceso libre a esa compañía
Escritura, autorización separada Cambio de versión y retirada válida de instalación usada/inactiva Misma identidad de producto; nuevas revisiones; lectura preservada

No crear activos ficticios ni productos de prueba en producción durante el preflight. Las pruebas negativas también requieren permiso y verificación de ausencia de efectos. Si no hay un activo y datos autorizados, el operador debe proponer canario en staging; no inventarlos en la base real.

11. Runbook de rollback y recuperación — hito F

Regla común: detener nuevas dependencias cerrando OS_SOFTWARE=false, luego nuevas altas/ediciones/reactivaciones con OS_CATALOG=false, mantener lectores Resources 3 y los cuatro gates application según autorización independiente. Aplicar configuración a todas las instancias y reiniciar mediante su supervisor aprobado. Configuración operativa/supervisor no están verificados. No ejecutar este plan ahora.

Incidencia Detección / respuesta propuesta Límite y recuperación
Catálogo SO Errores de alta/revisión/listado correlacionados; cerrar ambos flags Conservar lectura e historial; reparar causa y validar antes de reabrir
Selector Candidatos/tipos/etiquetas incorrectos; cerrar OS_SOFTWARE No hay gate SO solo de selección; comparar capacidades y referencias reales
Frontend incompatible Enlaces/estado o JS antiguo; suspender nuevas asociaciones y distribuir frontend compatible Mantener backend v3; no servir UI que oculte instalaciones existentes
Contrato Resources 409 de actualización o payload incompatible; detener consumidores antiguos y coordinar versión No borrar referencias ni rebajar backend; reabrir tras probar clientes v3
Evolución de plantilla Error de arranque/plantilla/bindings; detener rollout y escritores Cerrar flags no evita seed al arrancar; no prometer recuperación solo reiniciando. Investigar y autorizar reparación/restore integral consistente
Asociación Rechazos/filas inconsistentes; cerrar OS_SOFTWARE y verificar constraints/referencias No editar SQL a mano ni reasignar licencia; corregir mediante operación autorizada con historial
Producto comercial incorrecto Desactivar producto para impedir nuevas asociaciones; conservar UUID y uso previo Identidad publicada fija; otro producto necesita otro UUID. No convertir/reasignar instalaciones ni fusionar particulares
Producto inactivo usado Leer referencia/historia y needsReview; decidir continuidad/retirada Inactivo no significa ausente; retirada legítima sigue permitida. Reactivación solo tras revisión/autorización
B-01/B-02 No publicar el bundle fallido ni abrir flags; resolver en intervención específica Repetir parse/arranque aislado del compilado y login HTTPS end-to-end antes de replantear preparación

Conservar Resource, SoftwareInstallation, UUID, licencias, especificaciones e historial. Prohibidos borrado como rollback, fusión de particulares, D08.2 automático o backend incapaz de leer SO global ya referenciados. Un restore de BD requiere autorización, backup/restauración ensayados, corte consistente y análisis de cambios posteriores; no se propone downgrade destructivo del esquema.

Después de una incidencia: metadatos y diagnósticos agregados de la fase C; cero referencias inválidas/huérfanas; comparar con línea base del operador; leer casos existentes activos/inactivos/históricos; probar retirada si hay autorización; verificar sesiones/contratos en todas las instancias. Reabrir solo tras causa corregida, evidencias actuales y nueva autorización.

Probado previamente en aislado: cierre de seis flags conserva lectura/historia/retirada y bloquea nuevas altas; carreras/rollback transaccional ensayados. No probado operativamente: supervisor, proxy, restauración del destino ni ninguno de los ocho escenarios como simulacro productivo completo. Este runbook es verificable, no un rollback productivo ya ensayado.

12. Deuda global y aceptación

Hallazgo / propietario funcional Estado comprobado y efecto Clasificación
Bundle inválido B-01 / mantenedor de build servidor Dos compilaciones y node --check fallido; colisión banner/sharp Bloqueante real, no ejecutable
Sesión Secure B-02 / backend y operación/proxy HTTP local sin cookie bajo HTTPS reenviado; destino desconocido Bloqueante para topología TLS→HTTP sin solución validada
Calendar vendor / mantenedor de dependencia pnpm typecheck vuelve a fallar en calendar.tsx:165 por locale opcional; vendor intacto No causa B-01; deuda de tipos. Bloquea pipeline si exige verde; no aceptar exención implícita
Dos assertions Companies / mantenedor de Companies Antecedente del GO: ayuda compañía/persona, 305/307; fuentes sin diferencias No comprometieron catálogo/contratos en escenarios previos; no se reejecuta suite extensa sin cambios. Aceptación CI pendiente
Lint / propietarios de fuentes indicadas en log Nueva ejecución: 15 errores, 1 warning, 5 infos Deuda fuera del cambio; clasificar/aceptar explícitamente para release, nunca tratar como CI verde
Formato/imports / mantenedores y autores de evidencias Nueva ejecución: 173 errores, 1 warning, 5 infos Incluye copias JSON de evidencias SQL del desbloqueo, posteriores al check previo de 170; no son código runtime. No reformatear evidencia sellada sin actualizar huellas
Chunk web >500 kB / frontend Advertencia en ambos builds, sin fallo de compilación Riesgo de rendimiento, no prueba de fallo funcional; presupuesto del destino pendiente
Runtime/artefacto completo / operación Dependencias nativas/externalizadas, hosting y lanzamiento no ensayados como release PENDIENTE DE VERIFICACIÓN; necesario después de B-01

Se distinguen fallos antiguos de diagnósticos nuevos. La antigüedad no excusa un artefacto que no arranca: B-01 es bloqueante aunque no se determine aquí cuándo apareció. No se modifican bundler, sharp, vendor, tests de Companies ni áreas ajenas para conseguir verde.

13. Evidencias y comprobaciones de esta intervención

Conservadas bajo evidencias de preflight, con manifiesto: hashes de fuentes/overlay/artefactos, logs de build, parse, sesión proxy y calidad general. El diagnóstico de sesión usa el createApp real y express-session instalado, secreto aleatorio efímero y store en memoria para ese experimento local, sin BD ni cuentas reales. No certifica el store SQL ni login completo: aísla el mecanismo de emisión de cookie.

Comandos ejecutados: pwd, git status --short, git rev-parse HEAD, git branch --show-current, versiones Node/PNPM, comparación de hashes, reconstrucción en directorio temporal, pnpm build, dos pnpm exec turbo run build --force, node --check apps/server/dist/index.js, diagnóstico local proxy, pnpm typecheck, pnpm lint, pnpm check y detalle Biome. Los builds devuelven 0; el parse devuelve 1; tipos/lint/check devuelven error. No se ejecutan el servidor compilado ni scripts start contra base configurada.

Reproducción no invasiva desde la raíz, sin cargar .env ni abrir BD:

pnpm exec turbo run build --force
node --check apps/server/dist/index.js
node --import tsx .artifacts/resources-global-operating-systems-preflight/proxy-session-diagnostic.mjs

El segundo comando debe reproducir B-01 y devolver 1 en este snapshot. El tercero abre y cierra un HTTP efímero de loopback; el resultado esperado del defecto es trustProxy=false, secure=false, sessionCookieIssued=false, databaseUsed=false. El diagnóstico conservado se formateó y volvió a ejecutar con salida cero; esa salida cero significa diagnóstico completado, no sesión productiva correcta.

No se repiten MariaDB, unitarias extensas ni Playwright: cero diferencias funcionales frente al GO; se verifican sus hashes/manifiestos y se reutilizan como antecedentes. Los 29/29 + 50/50 y las 35 comprobaciones/69 capturas pertenecen al desbloqueo anterior. Los dos builds nuevos se justifican por la identificación/reproducibilidad de artefactos, y el parse/cookie por riesgos de ejecución productiva no cubiertos antes.

14. Riesgos residuales y condiciones de autorización

Además de B-01/B-02: desconocimiento del destino, despliegue mixto de lectores, clientes antiguos, gates globales sin canario por compañía, evolución que escribe al arrancar, backup/restore no ensayado del destino, dependencia de policies/locks para identidad EAV, particulares equivalentes persistentes y falta de medición de rendimiento productivo. No hay unicidad SQL comercial multicampo ni D08.2 implementado.

Hito Estado final
A trazabilidad del candidato VERIFICADO con base + overlay + hashes; fijar release aún es tarea de integración
B entorno operativo PENDIENTE DE VERIFICACIÓN; no se dispone de manifest de destino autorizado
C persistencia Requisitos VERIFICADOS en código; aplicación/datos destino PENDIENTE DE VERIFICACIÓN
D contratos/orden VERIFICADO en snapshot y antecedentes; clientes destino PENDIENTE DE VERIFICACIÓN
E etapas VERIFICADO como propuesta ajustada a gates; selección/asociación SO inseparables
F rollback VERIFICADO como runbook preparado; simulacro del destino PENDIENTE DE VERIFICACIÓN
Artefacto servidor NO CUMPLE, B-01
Sesión de producción TLS→HTTP NO CUMPLE en diagnóstico, B-02; topología destino pendiente
Adopción/D08.2 o globalidad de licencias NO APLICA, fuera de alcance

Responsables requeridos: mantenedor del build para B-01; backend y operación para TLS/sesiones; integración para commit/release inmutable y dependencias; DBA/operación para autorización de lecturas, esquema, backup/restauración y ventana; producto/propietario autorizado para productos, canario y gates; mantenedores de CI para deuda/excepciones expresas.

Condiciones antes de autorizar: artefacto compilado válido y arranque aislado comprobado; sesiones Secure a través de la topología aprobada; identidad de release congelada; destino identificado; inventario de clientes; metadata/datos verificados con autorización; backup/restauración aprobados; smoke y responsables acordados; tratamiento explícito de CI no verde. No cambiar flags como sustituto de cumplir estas condiciones.

Dictamen final: NO PREPARADO, referido al snapshot reproducido y al artefacto productivo generado localmente. El entorno real sigue pendiente. El informe prepara las decisiones y acciones necesarias; no solicita, concede ni ejecuta autorización de despliegue o activación.

15. Reevaluación del candidato confirmado en Git

Fecha: 26 de octubre de 2026. Solicitud reiterada de preflight; no autoriza corregir funcionalidad, migrar, desplegar ni activar. Se utilizó rdx-solid para limitar las comprobaciones a diferencias reales y a los bloqueos productivos ya detectados.

15.1. Identificación y diferencias respecto al GO

Requisito Estado actual Evidencia
Candidato actual VERIFICADO main, 6992a4ac745acf6b474a0f22d1a859b861119452; git status --short vacío antes de intervenir
Trazabilidad del código candidato VERIFICADO Ahora está confirmado en Git; reproducible mediante checkout del commit y dependencias fijadas. No necesita el overlay anterior para identificar sus fuentes
Igualdad completa con el GO NO CUMPLE De 1884 fuentes registradas: 1875 iguales y 9 modificadas; hay 6 fuentes adicionales en los mismos ámbitos
Archivos de trabajo del GO VERIFICADO con diferencia documental De los 40 registrados, 39 coinciden; cambió docs/componentes-de-interfaz.md
Node/PNPM y dependencias VERIFICADO en instalación/manifests 24.20.0 / 11.25.0; lockfile conserva SHA-256 bcd468ab1f127fffeb7f37ef3bdb5f2c5e85d40c192f3bc4a7cae5b2209b7c17
Instalación limpia de dependencias del destino PENDIENTE DE VERIFICACIÓN No se ejecuta install ni se cambia configuración privada

Los commits 07082001 y 6992a4ac incorporan el trabajo previamente sin commit y cambios adicionales. Se compararon contenidos con los manifiestos del GO; no se atribuye todo git diff d2bf856c..HEAD a una diferencia funcional posterior, porque también contiene aquel trabajo ya validado.

Durante la reevaluación aparecieron cambios concurrentes sin commit en modules/assets/src/web/index.ts, infrastructure-page.tsx, use-company-detail-controller.ts, el nuevo helper infrastructure-items.ts y pruebas infrastructure.test.tsx / companies-page.test.tsx. Se preservaron. El candidato de esta tabla es el commit, no el árbol concurrente final: sus diferencias se verificaron leyendo los objetos de git archive HEAD. Los hashes del trabajo concurrente se registran aparte como no validados en la fecha de captura; las ejecuciones de esta intervención no certifican esas modificaciones posteriores. Una release que las incorpore necesita nueva identificación y análisis de impacto.

Diferencia Clasificación Impacto y validación
Columnas adicionales de características/recursos y sus pruebas Frontend Cambia el contenido configurable del inventario; Resources reejecutado
Preferencias por compañía/plantilla, precedencia de URL y persistencia de orden Frontend Afecta navegación y contexto de listados; pruebas nuevas incluidas en Resources
CursorEntityTable y prueba de visibilidad Frontend compartido Puede afectar también listados globales; reejecutada la suite específica de columnas/tablas. Validación visual actual pendiente
Traducciones es/en de Resources Frontend/textos Fuentes distintas del GO; no certificar con capturas anteriores
Guía de listados y componentes Documentación Revisada como patrón vigente; no cambia esquema/contrato
Script de test en modules/resources/package.json Configuración de validación Añade nuevas pruebas; no cambia dependencias runtime ni lockfile
DTO HTTP, lógica backend, persistencia, seguridad, gates y configuración de build Sin diferencia funcional identificada respecto al GO Las diferencias de common son locales es/en; los nuevos archivos server son las fixtures/tests del cierre ya registrados en el GO

Las nueve fuentes modificadas y seis nuevas, con hashes, están enumeradas en traceability.json. No hay bloqueo de identificación del candidato. No se traslada el GO íntegro al frontend cambiado: corresponde validar visualmente los nuevos listados/componente compartido antes de una futura aprobación de release.

15.2. Artefactos y bloqueos reproducidos

Se ejecutó pnpm exec turbo run build --force: servidor y web compilan, dos tareas correctas. Se calcularon hashes de los 12 archivos dist. El dist del servidor coincide byte a byte con el del preflight anterior; el dist web es distinto. Por tanto, la correspondencia del frontend antiguo con MCP descrita en el apartado 3 no se aplica al candidato actual.

  • B-01 sigue NO CUMPLE: nuevo node --check apps/server/dist/index.js devuelve 1, Identifier 'createRequire' has already been declared. tsup.config.ts conserva el banner y el bundle incluye el segundo import procedente de sharp. La compilación correcta no acredita ejecución; no se arrancó ese servidor ni se abrió BD.
  • B-02 sigue NO CUMPLE para TLS→HTTP: el diagnóstico conservado se ejecutó con el createApp actual. Resultado nuevo: trustProxy=false, http=200, secure=false, sessionCookieIssued=false, databaseUsed=false. Salida cero del diagnóstico significa que terminó el experimento, no que la sesión de producción funcione.

No se ha configurado confianza en proxy, relajado Secure, cambiado NODE_ENV, editado el bundle ni modificado sharp para eludir los bloqueos. La solución de TLS/proxy debe ser aprobada y acotada al proxy real, sin confiar indiscriminadamente en cabeceras reenviadas.

15.3. Validaciones dirigidas nuevas y deuda actual

Comando / ámbito Resultado nuevo
pnpm --filter @metis/resources test, con loopback permitido 124/124, incluido caché, contratos y pruebas nuevas de columnas/preferencias
node --import tsx --test --test-isolation=none src/entity-column-visibility.test.tsx, desde rdx-ui con TSX_TSCONFIG_PATH del paquete 9/9
Typecheck directo Resources, Web y rdx-ui Los tres correctos
Biome y ESLint sobre las 15 fuentes modificadas/nuevas Ambos correctos
Build forzado Dos tareas correctas; advertencia de tamaño de chunk web
Parse del servidor compilado Fallo bloqueante B-01, salida 1
Diagnóstico de sesión local Experimento completado; demuestra B-02
pnpm typecheck raíz Falla en calendario vendor por locale opcional, salida 2
pnpm lint raíz 15 errores, 1 warning, 5 infos; salida 1
pnpm check raíz 173 errores, 1 warning, 5 infos; salida 1

No se han corregido incidencias ajenas. Los propietarios y clasificación de deuda del apartado 12 siguen aplicándose: el parse inválido es bloqueante, no una excepción aceptable por antigüedad; los fallos generales requieren tratamiento explícito de CI. Los dos fallos previos de ayuda de Companies son antecedentes, no una ejecución nueva. No se repitió la suite completa; posteriormente se modificó concurrentemente companies-page.test.tsx, por lo que su estado en ese trabajo posterior queda pendiente, sin afirmar que sus dos fallos persistan o estén resueltos allí.

No se repitieron MariaDB/HTTP-SQL con fixtures ni Playwright con preparación persistente: no cambió el backend/contrato/persistencia y este preflight no autoriza escrituras de negocio o migraciones. Las 29/29 + 50/50 y las 35 comprobaciones/69 capturas siguen siendo antecedentes con su alcance anterior. Para el nuevo frontend se requiere validación visual dirigida de columnas, preferencias, contexto y listados globales, en entorno aislado autorizado para preparar datos; las pruebas de componente no sustituyen esa comprobación.

15.4. Entorno, gates, rollback y autorización

No hay nueva evidencia autorizada del destino. Motor/versión/esquema aplicado, plantilla real, FKs/CHECK/índices, clientes desplegados, proxy, sesiones, supervisor, backup/restore y valores efectivos de gates continúan PENDIENTES DE VERIFICACIÓN. No se infieren de defaults ni del compose de desarrollo. El SQL del apartado 6 sigue preparado y no ejecutado; sus tablas/migraciones no cambiaron.

Se verificó que los seis nombres de flags y sus dependencias siguen iguales. El plan de los apartados 8–11 sigue vigente como propuesta: persistencia compatible → lectores v3 → frontend coordinado → OS_CATALOG administrativo → OS_SOFTWARE, que abre selección y asociación juntas. No hay gate por compañía ni se añaden flags para simularlo. Mantener los cuatro flags application según su autorización independiente.

El rollback propuesto conserva lectores v3, UUID, productos, instalaciones e historiales; cierra nuevas dependencias y altas, permite las retiradas legítimas ensayadas y no activa D08.2. No es un procedimiento productivo ya ejecutado. Los smoke tests de lectura y escritura siguen separados; ninguna escritura, conexión al destino o activación se ejecutó en esta reevaluación.

15.5. Evidencias y dictamen vigente

Ejecuciones nuevas, diferencias y hashes: manifiesto 6992a4ac. El preflight anterior y sus evidencias se conservan sin sobrescribirlos. Esta intervención modifica únicamente este informe y añade evidencias diagnósticas; los cambios concurrentes ajenos permanecen sin certificar.

NO PREPARADO, para 6992a4ac745acf6b474a0f22d1a859b861119452 y sus artefactos generados localmente. Primero deben resolverse B-01 y la configuración aplicable de B-02, verificarse el artefacto ejecutable y revalidarse el frontend cambiado. Después faltan las comprobaciones y autorizaciones del destino enumeradas arriba. El código está identificado, pero eso no acredita una release operativa ni autoriza publicarla.

16. Reevaluación de a72d6a2e

Fecha: 26 de octubre de 2026. Candidato: a72d6a2ec8985e1d51f74db68a1b3aabb3693030, rama main; árbol limpio al comenzar. Node 24.20.0 y PNPM 11.25.0. Se aplica rdx-solid para contrastar diferencias y ejecutar comprobaciones proporcionadas; no se rediseña Resources ni se modifica código funcional.

Trazabilidad y alcance de las diferencias

El candidato está confirmado en Git y puede recuperarse mediante checkout de ese SHA; no depende del overlay histórico para identificar su código. Los objetos de git archive se compararon con las 1884 fuentes del GO: 1854 coinciden, 30 cambiaron y hay 9 fuentes añadidas en los ámbitos registrados. El lockfile conserva SHA-256 bcd468ab1f127fffeb7f37ef3bdb5f2c5e85d40c192f3bc4a7cae5b2209b7c17. No se ejecutó instalación limpia de dependencias; sigue siendo una comprobación pendiente para el empaquetado final.

Desde 6992a4ac, los commits 0a5fb282 y a72d6a2e incorporan las modificaciones concurrentes anteriormente pendientes y nuevas integraciones visuales. La relación completa figura en traceability.json.

Diferencia desde la reevaluación anterior Clasificación Tratamiento
Obtención de infraestructura desde el inventario y exportación del helper Frontend Assets Pruebas de infraestructura y tipos reejecutados
Navegación de compañía/personas, contexto de listas y rutas Frontend Companies Pruebas de compañía/personas/rutas y tipos reejecutados; dos aserciones de presentación siguen fallando
Creación de carpeta SMB y enlace posterior a publicación Frontend Assets/Companies/Resources Cambia composición de formularios y feedback; se revalidan Resources y publicaciones, sin guardar datos reales
Callback onSaved(id, resource) y props de lista/editor Contrato frontend entre consumidores Tipado de los cuatro módulos/aplicación revalidado; no cambia DTO HTTP ni contrato Resources 2/3
Traducciones, documentación, scripts de auditoría y evidencias Textos/documentación/validación No confundir sus resultados históricos con ejecuciones de este preflight
Backend, persistencia, seguridad, flags, tsup y lockfile Sin cambios desde 6992a4ac Reutilizables los antecedentes técnicos de esas fronteras; se reproducen B-01/B-02 y se conserva pendiente el destino

El GO completo no se transfiere automáticamente al nuevo frontend. La documentación SMB incorporada registra comprobaciones de su intervención; no se presentan como pruebas nuevas de este preflight ni como certificación de los 35 recorridos SO sobre este candidato. Antes de aprobar una release sigue pendiente la validación visual dirigida de los consumidores modificados y compartidos, con evidencias correspondientes al código que se publique.

Resultados nuevos

Comprobación Resultado
pnpm exec turbo run build --force Servidor/web compilan, 2 tareas correctas; advertencia de chunk web >500 kB
Hashes de dist 12 artefactos identificados; servidor idéntico al de 6992a4ac, web diferente
node --check apps/server/dist/index.js NO CUMPLE, B-01: salida 1 por createRequire duplicado, línea 23345 del bundle generado
Diagnóstico proxy local sin BD NO CUMPLE, B-02 en TLS→HTTP: trustProxy=false, secure=false, sessionCookieIssued=false; experimento completado con salida 0
Resources completo 124/124, HTTP de prueba en loopback y sin BD
Assets: infraestructura/publicaciones SMB 9/9
Companies: compañía/personas/rutas 29/31; fallan «Personas (1)» y «Esta persona no tiene acceso a Metis Desk»
Typechecks directos Resources, Companies, Assets y Web Los cuatro correctos
Biome/ESLint sobre 25 archivos cambiados TS/TSX/JSON Ambos correctos
pnpm typecheck raíz Salida 2; continúa TS2375 en calendario vendor, locale opcional
pnpm lint raíz Salida 1; 15 errores, 1 warning y 5 infos
pnpm check raíz Salida 1; 173 errores, 1 warning y 5 infos

Los dos fallos de Companies se han vuelto a ejecutar; ya no se describen aquí como estado desconocido del trabajo concurrente. Coinciden en sus expectativas con fallos previos, pero quedan pendientes de conciliar con la presentación actual; no se asume que su antigüedad justifique ignorarlos. Su responsable es Companies. No impiden compilar; sí impiden declarar satisfactoria esa validación y requieren resolución o decisión explícita de aceptación para una release. No se debilitaron asserts ni se modificaron los tests.

B-01 sigue siendo un bloqueo absoluto del artefacto, responsabilidad de build/servidor: éxito de tsup no garantiza que Node pueda interpretarlo. B-02 corresponde a backend/operación y a la topología TLS aprobada. No se modificaron banner, sharp, Secure ni confianza en proxy. La deuda de calendario, lint/formato y ejemplos permanece fuera de las correcciones de este encargo; su efecto sobre la política CI debe aceptarse o resolverse expresamente.

Persistencia, destino y plan operativo

No cambian los requisitos de MariaDB, plantilla SO, FKs/CHECK/índices o migración R2.1b descritos en los apartados 6–7. PENDIENTE DE VERIFICACIÓN en el destino: versión/motor, esquema efectivamente aplicado, bindings y datos existentes, controles activos, clientes desplegados, proxy, sesiones, backup/restauración, supervisor y valores efectivos de configuración. No se ha obtenido acceso autorizado de lectura al destino ni se han ejecutado las consultas SQL preparadas.

Contratos v2/v3, propósitos, guard administrativo y seis nombres/dependencias de gates siguen sin cambios. Mantener el orden documentado: persistencia preparada → lectores v3 → frontend compatible → catálogo administrativo SO → selección/asociación SO conjuntas. No hay etapa de selección SO independiente ni gate por compañía; no se añaden para forzar un piloto. Los cuatro flags application conservan su autorización propia y los valores efectivos no se infieren de defaults.

El plan de smoke de lectura/escritura y los ocho escenarios de rollback siguen preparados en los apartados 10–11. Cerrar nuevas dependencias/altas no borra ni reescribe referencias: deben mantenerse backend/lectores v3, UUID, licencias, instalaciones e historial, incluyendo inactivos y retirada legítima. No es un rollback productivo probado. No se restaura un backend incapaz de leer SO global ni se implementa D08.2.

No se repitieron suites MariaDB ni preparación Playwright con persistencia: no cambió el backend y este preflight no autoriza migraciones ni escrituras de negocio. Los resultados anteriores 29/29 + 50/50 se conservan como evidencia de integración de las fronteras sin cambios. La validación visual pendiente debe realizarse sobre una release identificada y un entorno aislado autorizado para preparar datos.

Dictamen y evidencias

NO PREPARADO, para a72d6a2ec8985e1d51f74db68a1b3aabb3693030 y sus artefactos generados localmente. Se confirma trazabilidad, pero B-01 impide ejecutar el servidor y B-02 sigue abierto para TLS→HTTP; también faltan aceptación de las pruebas fallidas, validación visual actual y comprobaciones reales del entorno. No procede elevar este candidato a «preparado para solicitar autorización» por el mero hecho de tener GO de un snapshot anterior.

Evidencias nuevas y comandos: manifiesto a72d6a2e. Se preservan los informes anteriores. Los logs corresponden a esta ejecución; ninguna evidencia de producción ni activación se declara realizada. Esta intervención solo actualiza el informe y conserva diagnósticos; no cambia funcionalidad, configuración privada, datos reales, flags o despliegues.

17. Resolución correctiva B-01/B-02

Snapshot y alcance

Intervención autorizada el 26-10-2026, sobre main, HEAD a72d6a2ec8985e1d51f74db68a1b3aabb3693030 más el diff local correctivo, sin commit nuevo. El antecedente solicitado 6992a4ac y la reevaluación de a72d6a2e se conservan en los apartados 15–16. Los diagnósticos anteriores describen esos snapshots sin la corrección; no son el dictamen del diff actual.

El árbol contiene además cambios concurrentes de interfaz SMB, documentación y auditorías, identificados en el manifiesto. Se han conservado. Esta intervención modifica build/configuración/HTTP del servidor, el borrado de cookie en Identity, scripts de prueba y documentación. No cambia el dominio de Resources, Assets o Companies, contratos v2/v3, gates, esquema, migraciones ni D08.2. No se ha accedido a producción ni cargado .env.

Skill consultada: rdx-solid, aplicada a la reproducción antes de corregir, responsabilidad de cada capa y pruebas de comportamiento. No se ha realizado trabajo visual ni una auditoría Playwright nueva; los cambios concurrentes de frontend siguen requiriendo validación propia.

B-01: procedencia y corrección

La compilación anterior con tsup 8.5.1 terminaba, pero Node 24.20.0 rechazaba apps/server/dist/index.js con SyntaxError: Identifier 'createRequire' has already been declared, línea 23345. El servidor tiene un único entrypoint, formato ESM, target Node 24. El banner introducía import { createRequire } from "node:module" en la primera línea. El código empaquetado de sharp/dist/sharp.mjs aportaba otra importación de createRequire desde module en el mismo ámbito. El banner es texto externo al análisis léxico de esbuild y no participa en su renombrado de símbolos. No se ha demostrado un defecto de sharp.

Se externaliza sharp, que necesita resolver sus binarios nativos desde su paquete, y se declara como dependencia runtime directa de @metis/server en la versión 0.35.5 ya existente. Antes de añadirla, la resolución desde el paquete servidor fallaba con MODULE_NOT_FOUND; confiar solo en la dependencia transitiva de Companies no basta con PNPM. El lockfile únicamente incorpora ese enlace en el importer del servidor, sin cambiar versiones. El banner conserva el puente require para las dependencias CommonJS, importando createRequire as createServerRequire.

Eliminar todo el banner podía romper dependencias CommonJS. Cambiar únicamente el alias solucionaba la colisión sintáctica pero conservaba el empaquetado de la dependencia nativa. Externalización más dependencia directa y alias evita ambos problemas con la configuración existente. No se cambia ESM/CJS ni se reescribe el bundle mediante expresiones regulares.

El comando oficial build termina ahora con check:build (node --check dist/index.js), que también falla si falta el artefacto. Se incorporó primero el guard y se observó el fallo antes de corregir. Dos builds limpios sucesivos produjeron JS y sourcemap idénticos byte a byte; los hashes figuran en las evidencias. El build raíz también pasa, con la advertencia ya conocida del tamaño del chunk web.

La prueba permanente pnpm test:server-runtime ejecuta el proceso compilado, sin tsx ni importación sustitutiva del código fuente: arranque anunciado, salud /api/__health, sesiones SQL, procesamiento y recuperación de logos y fotos PNG/JPEG/WebP, conversión a WebP de anchura 128 y rechazo de imagen corrupta. El proceso termina por SIGTERM con salida 0; existe un límite de cierre que haría fallar el test si necesitara SIGKILL. No es una comprobación limitada a node --check.

B-02: causa, política y configuración

Un control negativo nuevo con certificado TLS validado y la política original sin proxies reproduce secure=false, protocolo HTTP y ausencia de cookie (véase b02-negative-control.json en las evidencias). No se presenta como código antiguo recompilado: conserva explícitamente su política original de confianza. En el diagnóstico anterior, Express mantenía trust proxy=false. Aunque el cliente usaba HTTPS hasta el proxy, Node recibía HTTP y req.secure=false. Identity ya configuraba cookie.secure=true en producción: express-session evitaba emitir la cookie, en lugar de emitirla sin Secure. Faltaba un contrato de confianza configurable del servidor. La corrección pertenece al servidor y al borde HTTP de Identity; no cambia autorización por compañía.

Se añade TRUSTED_PROXY_CIDRS, validada al arrancar y aplicada a Express antes de las sesiones. Solo admite IPs/CIDRs explícitas, máximo 32, sin hosts, alias, número de saltos ni confianza universal. Producción exige una lista no vacía; desarrollo conserva confianza cerrada por defecto. Se rechazan encabezados X-Forwarded-Proto duplicados, listas o valores no canónicos antes de sesión. Una conexión no confiable no eleva req.secure aunque anuncie https.

El logout tenía además un desajuste de atributos: borraba la cookie sin copiar Secure. Ahora conserva el valor de seguridad de la cookie de sesión antes de destruirla. Se mantienen HttpOnly, SameSite Strict, Path, ámbito sin Domain, duración de ocho horas y política de renovación existente. Login posterior genera otra sesión; la anterior queda inválida en SQL.

La topología representativa verificada es HTTPS → un terminador TLS local → HTTP Node. El certificado local se valida explícitamente; no se desactiva la verificación TLS. Las IPs loopback .2/.3 son datos sintéticos para distinguir proxies confiables y no confiables, no recomendaciones de producción. El proxy de prueba sobrescribe protocolo, cadena de cliente y host y retira Forwarded. La infraestructura real, sus IPs, origen, reglas de cabeceras y accesos siguen pendientes del administrador. La confianza por IP no distingue procesos que comparten origen/NAT: restringir el acceso al backend es obligatorio.

Configuración por entorno y procedimiento: Proxy TLS y sesiones. No se ha introducido un proxy productivo nuevo ni elegido direcciones reales. No se certifica una cadena de varios terminadores; TLS-08 comprueba la sobrescritura de una cadena inyectada en la topología de un solo proxy.

Matriz ejecutada

ID Resultado nuevo
TLS-01 HTTPS real mediante proxy confiable: req.secure=true, cookie Secure
TLS-02 HTTP directo en producción: sin emisión de cookie de sesión insegura
TLS-03 HTTP directo con protocolo falsificado: no eleva confianza
TLS-04 Bootstrap/login y consulta posterior reales con sesión SQL válida
TLS-05 Proxy TLS de dirección no confiable: sin elevación ni cookie
TLS-06 Proxy confiable informa HTTP: req.secure=false, sin cookie productiva
TLS-07 Protocolo duplicado, contradictorio, lista o inválido: 400 sin cookie
TLS-08 Cadena cliente inyectada sobrescrita; IP observada correcta. Varios proxies reales: no aprobados/no verificados
TLS-09 Logout real invalida SQL; borrado con Secure/HttpOnly/Strict/Path y expiración pasada
TLS-10 Servidor compilado en NODE_ENV=development: HTTP, HttpOnly/Strict, sin Secure y sin confianza implícita
TLS-11 Servidor compilado en producción sin proxies: arranque rechazado antes de anunciar disponibilidad
TLS-12 Emisión posterior y relogin conservan Secure; cambia el identificador de sesión

Las pruebas comprueban también ausencia de Domain y expiración de ocho horas. Se conservan en evidencias únicamente metis.sid y sus atributos, nunca valores de cookie, claves privadas, contraseñas ni entorno privado. MemoryStore se usa solo en la matriz HTTP de política; el recorrido compilado utiliza el almacén SQL real. Origen incorrecto y CSRF inválido mantienen 403.

Validaciones y evidencias nuevas

Comprobación Resultado
Build servidor + guard de sintaxis, repetidos Correctos; artefactos reproducibles en este entorno
pnpm build Correcto, servidor y web; advertencia de chunk web >500 kB
pnpm --filter @metis/server test:http 19/19
pnpm test:server-runtime 8/8, MariaDB desechable retirada
Sharp: company-logo-processor.test.ts 4/4, formatos, inválidos, límites y animación
Cierre SO con regresiones, comando oficial 29/29 + 52/52; dos regresiones nuevas de configuración explican el aumento desde 50
Typechecks Server e Identity Ambos correctos
Biome y ESLint del diff correctivo TS/configuración Correctos
pnpm typecheck raíz Falla por TS2375 preexistente en calendario vendor (locale opcional)
pnpm lint / pnpm check raíz Fallan: lint 15 errores, check 173 errores; ambos con 1 warning y 5 infos. Detalles en el manifiesto
Tests de paquetes sin servidor 7 tareas correctas; Companies falla en las mismas dos aserciones de presentación del apartado 16

La prueba de runtime usa una compañía y una persona sintéticas: comprueba fronteras de autenticación e imágenes, no listados ni carga. El cierre SO utiliza sus fixtures amplias de 15 compañías y 50 personas/activos/puestos/perfiles y al menos 53 recursos en la principal. No se declara una auditoría visual con ese volumen en esta intervención. Toda persistencia se ejecutó exclusivamente sobre metis_desk_test en contenedores desechables.

No se ejecutó el pnpm test raíz completo porque la rama histórica de integración del servidor carga .env. Se ejecutaron por separado HTTP sin .env, runtime compilado aislado, cierre SO con regresiones y tests de los demás paquetes. Una primera ejecución de integración detectó un import no exportado en la nueva prueba; se corrigió su import sin cambiar la API de Companies y se repitió correctamente. No se modificaron asserts ajenos para ocultar fallos.

Comandos reproducibles y logs, hash de fuentes/artefactos, estado del árbol y resultados se recogen en manifest.json. runtime-results.json acredita los atributos de cookie y el recorrido compilado; integration.log contiene los resultados. Los builds idénticos no certifican otras plataformas nativas ni un entorno de dependencias distinto.

Dictamen correctivo y condiciones restantes

Ámbito Dictamen
B-01 RESUELTO: build, sintaxis, arranque compilado, imágenes y cierre verificados
B-02 RESUELTO EN ENTORNO REPRESENTATIVO: TLS real, confianza restringida, sesiones SQL y falsificación comprobados
Validación de producción PENDIENTE
Catálogo global SO GO previo preservado, con cierre y regresiones reejecutados para las fronteras afectadas
Snapshot global NO PREPARADO

Antes de una release siguen pendientes: topología/IPs/origen y seguridad del proxy real, plataforma y dependencias nativas de destino, esquema/motor MariaDB, gates efectivos, supervisor y comprobación de cookies en el origen público autorizado. Además, validar visualmente el frontend actual y certificar el trabajo concurrente, y resolver o aceptar explícitamente los fallos globales y las dos aserciones de Companies. El dominio SO no pierde su cierre técnico, pero este no acredita automáticamente todo el snapshot.

No se desplegó, no se ejecutaron migraciones reales, no se cambiaron gates ni datos reales. La corrección de B-01/B-02 no autoriza activación productiva.