metis-desk/docs/architecture/cierre-tecnico-catalogo-global-sistemas-operativos.md

43 KiB
Raw Blame History

Cierre técnico — Catálogo global de sistemas operativos

Fecha: 25 de octubre de 2026. Base inspeccionada: main, d2bf856c973419277f0b30f6437242cd82f7d720. Node.js 24.20.0 y PNPM 11.25.0.

Dictamen vigente: GO técnico para el snapshot de fuentes registrado en la resolución del apartado 19. El NO-GO inicial queda levantado por causa demostrada, regresiones correctas y nueva validación visual. No equivale a CI global verde ni a autorización de despliegue o activación. Producción permanece sin activar por esta intervención.

1. Dictamen ejecutivo del cierre inicial

Dictamen inicial: NO-GO. La persistencia, los contratos y la concurrencia del catálogo SO superaban las pruebas aisladas. Sin embargo, fallaba la prueba de presentación del SO actual en el panel de software y había cambios concurrentes en mapa, diálogos y traducciones posteriores a la evidencia visual. No se certificó esa interfaz con capturas anteriores. Además, las comprobaciones generales del repositorio conservaban errores ajenos al catálogo. Su resolución posterior se documenta en el apartado 19.

Este dictamen no declara defectuoso el modelo de persistencia ni autoriza una activación. Se debe estabilizar una revisión candidata, resolver los bloqueos y validar sus recorridos afectados antes de emitir GO. No se ha desplegado, activado ni consultado configuración efectiva de producción.

La intervención añade pruebas y documentación; no cambia el comportamiento funcional ni SoftwareInstallation. La única corrección realizada durante el cierre afecta a la prueba de reinicio de gates: conservaba un cliente HTTP conectado al puerto anterior. La repetición completa pasa.

2. Fuentes, alcance y cambios concurrentes

Fuentes normativas consultadas: auditoría previa, decisión aprobada, registro de implementación, decisión original del SO actual, R2.0–R2.6, persistencia R2.1b, estado D08.2 y documentación de capas, composición, contratos y pruebas de docs/arquitectura/.

Se aplicó rdx-solid y su referencia de pruebas para probar contratos observables con HTTP y MariaDB reales, reutilizando las fixtures existentes. No se necesitó ni instaló una skill adicional. No se realizó diseño UI en este cierre.

El árbol quedó limpio en la base indicada. Después aparecieron modificaciones concurrentes en Assets/Companies: acciones de nodos del mapa, extracción de controladores/diálogos de instalación e historial y traducciones. Se conservaron. No forman parte de las correcciones de este cierre. Las pruebas generales reflejan el árbol existente durante su ejecución; el manifiesto de evidencias permite distinguirlo de la base.

Archivos propios del cierre:

  • apps/server/src/global-operating-systems-closure.integration.test.ts: matriz DB-SO, concurrencia, fallos controlados, contratos y cierre de gates.
  • apps/server/src/global-operating-systems-legacy.fixture.ts: reconstrucción de plantilla antigua y comparación SQL tras dos evoluciones.
  • scripts/resource-scope-test.py y package.json: opción --operating-systems-closure y comando reproducible.
  • Este informe y .artifacts/resources-global-operating-systems-closure/.

3. Inventario y capacidades

«Implementada» describe el código y la prueba citada. «Aislado» describe exclusivamente contenedores de prueba. La configuración efectiva de producción es no verificada en todas las filas.

Capacidad / propietario Código Entorno aislado y evidencia Producción
Resources: producto SO global sobre stock template:os Implementada DB-SO-01, 19 No verificada
Identidad comercial, revisión previa y UUID por producto Implementada Unitarias, suite SO original, C1/C3 No verificada
Edición conocida/no aplicable/desconocida y borradores Implementada Suite SO original y Resources No verificada
Evolución conservadora de plantilla antigua Implementada B3, dos ejecuciones SQL No verificada
Administración y publicación protegidas Implementada HTTP, permisos, CSRF y gates No verificada
DTO SO, DTO application y referencias públicas por propósito Implementada Contratos v2/v3, DB-SO-02/10, D No verificada
Companies: instalación por activo, versión e historial Implementada DB-SO-04–18 No verificada
Licencias particulares y pertenencia a compañía Implementada DB-SO-08/09 y R2.4 No verificada
SO particular anterior y coexistencia Implementada B3, DB-SO-07/20 No verificada
Selectores mixtos y capabilities SO Implementada Suite SO original y D No verificada
Assets/puestos/panel/historial/mapa: SO actual y enlaces Implementada; validación actual bloqueada Evidencia visual anterior; regresión actual del panel No verificada
Frontend: catálogo, formulario, revisión, es/en y estados Implementada Resources; evidencia visual anterior delimitada abajo No verificada
Caché acotada por catálogo, UUID y propósito Implementada Prueba específica reejecutada, Resources No verificada
Cerrar gates manteniendo lectura/historial/retirada Implementada F y suites SO/R2.4 No verificada
Unicidad semántica física SQL multicampo Ausente por decisión No se promete; C1 verifica policy y lock No aplicable
Globalidad de licencias/SMB/acceso/otros/copias Ausente deliberadamente DB-SO-03/19 y regresiones No aplicable
Adopción, fusión, sucesión D08.2, inventario automático Ausente; fuera de alcance No implementado No aplicable
Activación operativa de una revisión candidata estable Bloqueada Pendientes del apartado 18 No realizada

4. Decisiones materializadas y archivos principales

Resources conserva la propiedad del producto. La identidad declarativa usa proveedor, familia, versión principal, estado de edición y edición. La normalización conserva tildes y no equipara sinónimos. Una identidad publicada queda fija incluso al desactivar el producto; otro producto comercial necesita otro UUID. No hay fusión automática de particulares ni reasignación de instalaciones.

SoftwareInstallation conserva identidad, activo, producto inmutable, versión instalada, licencia particular, estado y revisiones. ApplicationConfiguration sigue admitiendo exclusivamente aplicaciones. Los repositorios globales comparten infraestructura con elegibilidad configurada por tipo; no se creó otro catálogo persistente.

Área Archivos / responsabilidad
Dominio Resources api/domain/operating-system-identity.ts, evolve-operating-system-template.ts, resource-catalog-seed.ts
Aplicación Resources api/application/operating-system-identity-policy.ts, global-resource.use-cases.ts, resource-global-gates.ts, resource-reference-service.ts
Persistencia sequelize-global-resource.repository.ts, global-operating-system-reader.ts, resource-reference-reader.ts, resource-reference-metadata.ts, verify-global-resource-enablement.ts
Contratos common/operating-system-identity.ts, DTO de referencias/requests/responses y contrato del cliente Resources
Composición modules/resources/src/api/module.ts, configuración de servidor e identity-runtime.ts
UI Resources web/global-operating-systems/ y componentes compartidos de web/global-applications/
Consumidores SO actual de Assets/Companies, selectores de software, panel/historial/mapa y software-reference-href.ts
Consultas y textos Query keys e invalidación explícita de global-applications; traducciones es/en de módulos y navegación web

Las rutas de Resources de la tabla son relativas a modules/resources/src/. No se modificaron vendor ni archive/. D08 continúa sin ratificación global; D08.2 mantiene su resolución con condiciones y no equivale a adopción implementada.

5. Preparación y esquema MariaDB

Prueba real: MariaDB 11.8.9-MariaDB-ubu2404, imagen 11.8 fijada por digest en el lanzador. Cada ejecución crea un contenedor y base metis_desk_test desechables, puerto efímero de loopback y credenciales temporales. No carga .env. El lanzador elimina contenedor, volumen y credenciales temporales al terminar.

Evidencia: schema.json, con versión, SQL mode, collation, columnas, índices, FKs, CHECK, DDL, engines y resultado de migración. Las tablas son InnoDB; las vistas no tienen engine propio. foreign_key_checks=1 y check_constraint_checks=1. La migración completa scope, ownerCheck, integrationCheck y nullableOwner; repetirla no aplica cambios. El CLI posterior confirma esquema scoped.

Se inspeccionaron, entre otros: PK de Resource/instalación/revisiones; resource_company_identity; unicidad (resourceId, position) de revisión; currentKey único de instalación y (configurationId, position) de revisión; FKs de instalación a activo, Resource y licencia y de revisiones a sus raíces; CHECK resource_scope_owner y resource_global_no_integration.

Las FKs referenciales no sustituyen las policies de tipo, scope, pertenencia de licencia o disponibilidad: estas se verifican por HTTP y persistencia. Tampoco existe UNIQUE SQL de identidad comercial EAV. No se ha añadido DDL para SO ni se ejecutó migración sobre una base real.

Volumen de la suite de cierre: 15 compañías; principal con 50 personas, 50 activos, 50 puestos, 50 perfiles y al menos 53 recursos particulares, además de productos globales e instalaciones de prueba. Las pruebas unitarias conservan conjuntos pequeños. No se afirma que la suite de cierre sea un benchmark de carga.

6. Matriz DB-SO

Todos los casos usan endpoints reales, validación Zod, casos de uso y Sequelize/MariaDB. Se comprueban tanto HTTP como filas/revisiones o ausencia de ellas.

Caso Comprobación Resultado
DB-SO-01 Crear SO stock global, compañía nula 201; correcto
DB-SO-02 Crear aplicación; listado exclusivamente application junto al SO 201; correcto
DB-SO-03 Licencia como global 409; ninguna raíz
DB-SO-04 Instalar desde A 201; correcto
DB-SO-05 Instalar mismo UUID desde B con versión/licencia propias 201; independiente
DB-SO-06 Segundo activo A 201; instalación distinta
DB-SO-07 Particular y global homónimos UUID y filas independientes; candidatos separados
DB-SO-08 Licencia A en instalación A 200; asociación propia
DB-SO-09 Licencia A desde B 404; licencia B anterior preservada
DB-SO-10 SO como ApplicationConfiguration 404; ninguna configuración
DB-SO-11 Desactivar producto utilizado 200; instalaciones intactas
DB-SO-12 Nueva instalación con producto inactivo 409; ninguna fila
DB-SO-13 Historial y resolución inactiva 200; conservados
DB-SO-14 Cambiar versión instalada a 24H2 Revisión adicional; mismo producto
DB-SO-15 Cambiar destino de instalación 409 SOFTWARE_TARGET_IMMUTABLE; historial intacto
DB-SO-16 Retirar producto inactivo removal_pending → removed; dos revisiones
DB-SO-17 Replay del mismo creationId 200; SQL idéntico, no reactiva
DB-SO-18 Activar/desactivar Mismo UUID, seis revisiones del producto y referencias conservadas
DB-SO-19 Stock frente a copia y tipos no autorizados Copia creada localmente; todos los intentos globales no elegibles 409
DB-SO-20 Editar particular antiguo incompleto 200; valores preservados, nueva revisión y scope local

Resultado: 20/20 DB-SO. La suite contiene 28 escenarios y una prueba contenedora: 29/29 tests. Resultados estructurados e informe de ejecución.

7. Evolución doble de plantilla antigua

B3 reconstruye exclusivamente en la fixture desechable una plantilla anterior con proveedor, edición y descripción, un campo propio, sección/nombre personalizados y override de disponibilidad. Crea un particular incompleto y dos revisiones antes de evolucionar. Después ejecuta dos veces el seed real mediante el repositorio SQL.

Se conservan UUID/orden de bindings originales, sección, personalización, disponibilidad, valores y las dos revisiones. Se añaden los tres campos de identidad nuevos como opcionales; la segunda ejecución no cambia definiciones ni bindings. Los snapshots de raíz, características, especificación e historial del particular son idénticos: no se fabrica familia, versión ni edición para recursos heredados.

La suite SO complementaria prueba edición conocida, borrador desconocido y edición no aplicable explícita con activación revisada. Evidencia: legacy-evolution.json.

8. Concurrencia y rollback

Prueba Coordinación real y garantía observada
C1: dos altas equivalentes Se retiene la primera escritura y se observa espera InnoDB del segundo escritor en el catálogo; 201/409 y una sola raíz equivalente.
C2: desactivación primero Asociación espera el lock real; después del commit relee disponibilidad y devuelve 409 sin instalación.
SO complementaria: instalación primero Desactivación espera la instalación; ambas confirman en orden válido, conservando instalación histórica.
C3: identidad/instalación/metadatos/desactivación Cuatro peticiones concurrentes; identidad publicada rechazada; exactamente una actualización administrativa con revisión esperada confirma. La instalación es aceptada o rechazada según orden serial válido; filas y revisión final coinciden.
C4a: fallo tras escribir revisión Resource Hook SQL lanza fallo controlado comprobado; HTTP 500 saneado; rollback de raíz/características/especificación/revisiones. Reintento con mismo UUID crea correctamente.
C4b: fallo tras escribir revisión de instalación Fallo inyectado comprobado; ninguna instalación/revisión parcial; snapshot del producto idéntico.

La consulta final encuentra cero revisiones huérfanas de Resource e instalación. No se usan esperas arbitrarias para ordenar las carreras: barreras y observación de locks. Son intercalaciones concretas comprobadas, no una demostración de todos los posibles órdenes ni una prueba de fallos de hardware. El lock de catálogo serializa escritores; no hay unicidad semántica física multicampo ni equivalencia de sinónimos. Las escrituras SQL externas que omitan las policies quedan fuera de esa garantía.

9. Seguridad y aislamiento

Autenticación real por formulario HTTP, sesión y CSRF. Usuario ordinario recibe 403 para administración y altas; token CSRF inválido recibe 403. La compañía se comprueba en servidor. La licencia ajena se rechaza sin cambiar la asociación existente. El propósito de perfiles no admite SO. Copias, licencias, soporte, SMB, acceso y certificados no adquieren globalidad.

Los fallos controlados no exponen sentencia SQL, stack ni mensaje interno al cliente. Las evidencias conservadas no incluyen contraseña, cookies ni storageState. El cierre no inspeccionó datos ni credenciales de producción.

10. Compatibilidad y regresiones de aplicaciones

Contrato Resources 3 para software mixto con SO global: DTO SO propio, kind=os, scope=global, companyId=null, identidad comercial y href. El DTO application conserva kind=application. Los particulares conservan su proyección y pertenencia.

La suite prueba capabilities v2 con exactamente las cuatro claves anteriores y v3 con capacidad SO; el cliente v2 y el cliente sin cabecera reciben 409 al leer una colección que requiere SO global. Versión 4 no soportada devuelve 400. No se realiza downgrade silencioso de esa colección. El contrato anterior sigue operativo para contextos compatibles probados en R2.4; no se afirma compatibilidad total de clientes antiguos con SO global.

Reejecutadas en contenedores independientes: R2.3 administración 12/12, R2.4 software 13/13, R2.5 perfiles 11/11, R2.6 coincidencias 6/6 y SO original 12/12. Cubren alta/edición/estado, selección, instalación, historial, UUID, perfiles, licencias, exclusiones y negociación. El nuevo DB-SO-02 verifica que aplicaciones no recibe SO con ambos tipos persistidos; DB-SO-10 comprueba exclusión de perfiles. Se conserva la prueba R2.6 y su filtro específico de application; no se amplía R2.6 a SO.

Regresión HTTP/MariaDB del cierre: 50/50 (servidor/contratos HTTP, configuración, diagnósticos, permisos de relaciones, dominios, SMB, accesos, membresías, relaciones tipadas, publicaciones y propagación de plantillas). Evidencias de regresiones y regressions.log.

11. Caché frontend

Reejecutada en los 116/116 tests de Resources la prueba SO global: invalida software y su catálogo sin refrescar aplicaciones ni perfiles de global-applications.test.tsx. Verifica invalidación de catálogo SO, candidatos/resolución para software y colección de instalaciones; mantiene sin invalidar catálogo application, coincidencias, candidatos/resolución de perfiles y ApplicationConfiguration. No invalida toda la caché.

El test comprueba estado de TanStack Query; por sí solo no prueba todos los refetch de navegador. Las etiquetas y navegación entre activo/puesto se probaron visualmente en la intervención anterior. La regresión actual del panel impide extender esa garantía a la interfaz concurrente sin nueva comprobación.

12. Validación técnica y fallos delimitados

Comando / ámbito Resultado de este cierre
pnpm --filter @metis/{resources,companies,assets,web,server} typecheck, ejecutado individualmente Los cinco paquetes correctos
Biome y ESLint de los dos nuevos TS y Biome de package.json Correctos
Resources 116/116 correctos; necesita loopback para su prueba HTTP
Companies, ejecución detallada sin aislamiento de procesos 305 tests: 302 correctos, 3 fallos detallados abajo
Assets 29 ficheros de prueba correctos en ejecución ordinaria
Web 3 ficheros de prueba correctos
Suites HTTP/MariaDB Correctas según apartados 6 y 10
pnpm build Servidor y web correctos; advertencia de chunk web mayor de 500 kB
pnpm typecheck, y Turbo de paquetes con dependencias Bloqueado por packages/shadcn-ui/src/components/calendar.tsx:165, incompatibilidad locale con exactOptionalPropertyTypes
pnpm lint 15 errores, 4 warnings y 5 infos generales
pnpm check 170 errores, 4 warnings y 5 infos en el árbol durante la ejecución

El error vendor y los dos fallos de companies-page.test.tsx (textos de ayuda de compañía/persona) ya constaban antes del cierre. Los errores generales de lint/formato abarcan código y ejemplos ajenos al catálogo; no se han reparado indiscriminadamente ni se considera el repositorio globalmente validado.

El tercer fallo es actual: software.test.tsx:126, el render del panel no contiene «Windows 11 Pro». Coincide con la modificación concurrente de software-installations-panel.tsx; la evidencia dirigida anterior pasaba este test. El hecho demostrado es la regresión de la prueba de presentación. Su causa final y la validación de la nueva interacción pertenecen al cambio concurrente; no se certifican ni se corrigen por inferencia en este cierre.

Las primeras pruebas dentro del sandbox de red fallaron en tests que levantan HTTP local. Resources se repitió con loopback permitido y pasó; se conservan ambos resultados. No se atribuye ese fallo al código. No se ejecutó el pnpm test raíz sin filtro: el script server carga .env y usa una base configurada; se sustituyó por las integraciones explícitas desechables, sin acceso a configuración local.

Logs conservados en technical/. Los resultados no equivalen a validar futuras modificaciones del árbol.

13. Playwright anterior: reutilización delimitada

Se verificó el informe original .artifacts/playwright/authenticated-al820anx/global-operating-systems-report.json: 28 comprobaciones y 27 capturas. Se recalcularon todos los SHA-256, coincidentes. Es evidencia de la intervención anterior, ninguna ejecución nueva de Playwright en este cierre. Se conservan copia del informe, verificación y capturas en ese mismo directorio.

Incluye catálogo vacío, formulario/revisión/identidad rechazada, retorno de foco, borrador, es/en, carga/error/reintento, búsqueda y paginación con 51 SO, claro/oscuro a 320/390/768/1024/1280/1600 px, lectura ordinaria, navegación real de SO desde activo, puesto, historial y mapa, clic en equipo y selector global/particular. Contraste mínimo medido de textos: claro 4,71:1, oscuro 6,85:1. Instalación sintética: 15 compañías y principal con al menos 50 personas, activos, recursos, perfiles y puestos.

No se repitieron indiscriminadamente los recorridos. Su vigencia se limita a los componentes y comportamiento anteriores: los cambios concurrentes de navegación, panel y diálogos requieren nuevas pruebas afectadas por su responsable. Los hashes prueban conservación de archivos, no equivalencia del código modificado. No hay evidencia nueva de accesibilidad/responsive de esas modificaciones.

14. Gates y configuración mínima

Todos los flags de entorno tienen predeterminado false. Se mapean en la composición de Resources; administration=true es una capacidad interna adicional sometida a autorización, no un flag público que sustituya los permisos.

Variable Propósito y dependencia Escritura / administración Selectores Lectura existente al cerrar
RESOURCE_GLOBAL_OS_CATALOG_ENABLED Catálogo SO; requiere scoped e integridad activa Abre alta/edición/reactivación administrativa SO con permisos Solo junto a OS_SOFTWARE Conservada
RESOURCE_GLOBAL_OS_SOFTWARE_ENABLED Asociación SO; requiere OS_CATALOG Abre nuevas dependencias SO en instalaciones Abre candidatos SO junto a OS_CATALOG Conservada; retirada legítima permitida
RESOURCE_GLOBAL_CATALOG_ENABLED Catálogo application Alta/edición/reactivación application Base de gates application Conservada
RESOURCE_GLOBAL_SOFTWARE_ENABLED Asociación application; requiere CATALOG Nuevas dependencias application en software No sustituye SOFTWARE_CANDIDATES Conservada
RESOURCE_GLOBAL_SOFTWARE_CANDIDATES_ENABLED Selección application; requiere CATALOG No abre por sí solo la asociación Candidatos application de software Conservada
RESOURCE_GLOBAL_PROFILE_ENABLED Aplicaciones en perfiles; requiere CATALOG Nuevas dependencias application en perfil Candidatos application para perfil Conservada; nunca abre SO en perfiles

Las lecturas públicas/históricas permanecen; cerrar gates no borra referencias. Las escrituras no son todas equivalentes: se bloquean nuevas dependencias y la administración habilitada por catálogo, pero se mantiene la retirada legítima probada. Los flags no convierten un usuario ordinario en administrador.

Mínimo para catálogo y asociación SO: OS_CATALOG=true y OS_SOFTWARE=true, lectores v3 y autorización administrativa. Los cuatro gates application no son dependencia de SO; conservar su configuración aprobada independiente. Para preparar solo administración SO se abre primero OS_CATALOG y se mantiene OS_SOFTWARE=false. No se propone cambiar valores efectivos sin autorización.

15. Secuencia de despliegue propuesta

  1. Fijar una revisión candidata estable, resolver los bloqueos y obtener autorización del responsable de producto/operación. Identificar clientes v2 y plan de actualización.
  2. Mantener cerradas nuevas escrituras/asociaciones SO. Respaldar el entorno mediante el procedimiento operativo existente; comprobar motor, versión y preflight de R2.1b con permisos de operación.
  3. Si falta scoped, ejecutar la migración explícita con escrituras pausadas según R2.1b. No utilizar las fixtures destructivas ni el lanzador de pruebas sobre esa base.
  4. Desplegar backend compatible con Resources 3 y gates SO cerrados. El arranque evoluciona la plantilla y valida integridad; comprobar campos/UUID/personalizaciones y ausencia de alteraciones históricas. No rellenar particulares con datos inventados.
  5. Desplegar lectores web/DTO v3 y rutas de detalle. Comprobar productos existentes, historial, versiones instaladas y clientes anteriores, con cuentas de mínimo privilegio.
  6. Autorizar OS_CATALOG=true y OS_SOFTWARE=false. Verificar administración, revisión, identidad, publicación y lectura ordinaria de productos aprobados.
  7. Autorizar OS_SOFTWARE=true; comprobar capabilities/candidatos y asociación en compañía autorizada con licencia propia. Comprobar compañía ajena, perfil rechazado e inactivos.
  8. Verificar activo, puesto, panel, historial y mapa; revisar errores y resultados correlacionados por petición. Confirmar lectura/retirada de instalaciones existentes. Registrar revisión y decisiones de autorización.

Los pasos operativos son una propuesta, no acciones ejecutadas. El preflight del entorno destino sigue pendiente; la preparación aislada no lo sustituye.

16. Rollback sin pérdida de referencias

Cerrar primero RESOURCE_GLOBAL_OS_SOFTWARE_ENABLED=false y después RESOURCE_GLOBAL_OS_CATALOG_ENABLED=false, conservando backend/lectores Resources 3 y esquema evolucionado. Mantener los cuatro flags application según su autorización independiente. Reiniciar/desplegar configuración por el procedimiento de operación y verificar capabilities.

No borrar productos, instalaciones, revisiones ni campos; no modificar particulares ni reescribir UUID. No restaurar un backend previo incapaz de interpretar SO global una vez existan referencias. Verificar lectura pública, colección v3, historial y retirada removal_pending → removed. F ensaya el caso más restrictivo: los seis gates cerrados, lectura/historial/retirada correctos y nueva alta rechazada. Las suites complementarias verifican bloqueo de nuevas asociaciones y conservación de las existentes.

17. Criterios objetivos de GO y riesgos

Criterio Estado
DB-SO-01–20, evolución doble, integridad referencial Cumplido en MariaDB aislada
Concurrencia en ambos órdenes, identidad y rollback atómico Cumplido en las intercalaciones probadas
Contratos v2/v3 e incompatibilidades explícitas Cumplido en casos ensayados
Regresiones backend de aplicaciones/perfiles/licencias/otros Cumplido
Seguridad sin apertura involuntaria Cumplido en matriz ensayada
Caché acotada Cumplido por prueba reejecutada
Gates y rollback reproducibles Cumplido en aislado; operación destino pendiente
Regresión de SO actual del árbol candidato Bloqueado por fallo del panel
Evidencia visual vigente de los cambios concurrentes No verificada
Validación general del repositorio No satisfactoria, fallos generales separados
Revisión candidata estable y autorización de activación Pendiente

Riesgos residuales: identidad EAV protegida por policy/locks, no UNIQUE comercial; normalización conservadora no descubre sinónimos; particulares equivalentes seguirán coexistiendo; los clientes anteriores necesitan actualización cuando su contexto incorpora SO global; no se midió rendimiento de producción ni indisponibilidad de infraestructura real. Son límites explícitos, no capacidades implementadas de D08.2.

18. Pendientes, responsables y reproducción

Pendiente Responsable de resolver / autorizar
Corregir o actualizar justificadamente el contrato de render del panel; repetir su prueba Responsable del cambio concurrente Companies/mapa
Validar con Playwright los recorridos modificados, teclado/foco, tamaños y estados; conservar nuevas capturas Responsable de UI del cambio concurrente
Resolver error vendor y fallos generales o documentar aceptación explícita ajena al catálogo Mantenedores del repositorio; usuario autoriza cualquier modificación vendor
Fijar revisión candidata y repetir comprobaciones afectadas tras integrar cambios Responsable de integración
Preflight/backup del destino, política de clientes y autorización de gates Operación y responsable de producto designados por el usuario
Emitir GO posterior y activar Responsable autorizado; no realizado en este cierre

Comandos reproducibles desde WSL, Node 24 y PNPM fijado:

pnpm test:global-operating-systems:closure
python3 scripts/resource-scope-test.py --operating-systems
python3 scripts/resource-scope-test.py --catalog
python3 scripts/resource-scope-test.py --software
python3 scripts/resource-scope-test.py --profiles
python3 scripts/resource-scope-test.py --coincidences
pnpm --filter @metis/resources test
pnpm --filter @metis/companies test
pnpm --filter @metis/assets test
pnpm --filter @metis/web test
pnpm --filter @metis/resources typecheck
pnpm --filter @metis/companies typecheck
pnpm --filter @metis/assets typecheck
pnpm --filter @metis/web typecheck
pnpm --filter @metis/server typecheck
pnpm exec biome check apps/server/src/global-operating-systems-closure.integration.test.ts apps/server/src/global-operating-systems-legacy.fixture.ts package.json
pnpm exec eslint apps/server/src/global-operating-systems-closure.integration.test.ts apps/server/src/global-operating-systems-legacy.fixture.ts
pnpm typecheck
pnpm lint
pnpm check
pnpm build

Las integraciones necesitan Docker y loopback. pnpm test:global-operating-systems:closure incluye las 50 regresiones HTTP/MariaDB y limpieza automática. El fallo inicial del cliente de prueba y las ejecuciones generales fallidas se reconocen arriba; los resultados satisfactorios corresponden a las repeticiones identificadas. No se presenta ninguna prueba de navegador anterior como nueva ni se declara producción preparada mientras persistan los bloqueos.

19. Resolución dirigida del bloqueo del panel

Intervención posterior del 25 de octubre de 2026 sobre el mismo HEAD d2bf856c, conservando los cambios concurrentes. Los apartados 1–18 registran el cierre inicial; los resultados siguientes corresponden a ejecuciones nuevas y sustituyen la clasificación provisional del fallo del panel.

Se consultaron rdx-solid y su referencia de pruebas para separar fixture, contrato y comportamiento, y ui-ux-pro-max para la revisión visual. Su búsqueda dirigida de foco/teclado se concretó en apertura por Enter, navegación de menú, Tab dentro del diálogo, Escape, retorno e indicador de foco. Se respetaron DESIGN.md y el procedimiento Playwright; no se instaló ningún auditor, skill ni dependencia. No se necesitó rediseñar ni modificar primitivas shadcn.

Causa raíz demostrada

Clasificación: fixture incorrecta, no defecto funcional de resolución del SO. El helper concurrente software-installation-options.ts:26 filtra los recursos particulares mediante item.companyId === companyId. La fixture original de software.test.tsx cargaba en TanStack Query objetos sin companyId, especificación ni historial. Esa entrada no cumplía ResourceSchema (common/inventory.ts:35–42) y el filtro la excluía; name() devolvía —, por lo que fallaba assert.ok(html.includes("Windows 11 Pro")).

La prueba renderiza SoftwareInstallationsPanel mediante SSR con consultas precargadas y staleTime=Infinity: una instalación configurada del activo solicitado, otra de otro ordenador, versión 24H2, Resource Windows y licencia particular. No había petición pendiente ni error remoto. No intervienen negociación HTTP, selector de SO o invalidación de caché en esa expectativa.

Al comenzar esta intervención, el cambio concurrente ya había añadido companyId y el test aislado pasó 3/3. Para comprobar causalidad se ejecutó una copia temporal del test de HEAD contra el consumidor actual: reapareció el fallo exacto de Windows en :126, con las otras dos pruebas correctas. Se eliminó únicamente esa copia temporal. El primer intento con un fichero oculto no tomó la transformación JSX esperada y produjo React is not defined; se corrigió el procedimiento antes de aceptar la reproducción. No se usó ese error de herramientas como evidencia de la regresión.

La reproducción y el resultado corregido están conservados como before-fixture.log y fixed-test.log en las evidencias de esta intervención.

Corrección y alcance

  • software.test.tsx: conserva el arreglo concurrente y construye ahora ambos Resources particulares completos mediante ResourceSchema.parse, incluyendo compañía, valores, especificación e historial. El schema impedirá volver a omitir la pertenencia. Se mantienen todas las expectativas originales de nombres, versión, enlaces, licencia y separación por ordenador.
  • current-operating-systems.test.tsx: añade render es/en del SO global configurado, activo/inactivo, enlace global y versión instalada, y confirma que la instalación retirada muestra el estado vacío correspondiente.
  • scripts/global-operating-systems-ui-audit.py: amplía el recorrido MCP existente con consumidores, menús y diálogos del mapa en ambos temas/cinco resoluciones, teclado/foco, medición de contraste, guardado real de versión y propagación activo/puesto.
  • Este informe y el enlace del registro de implementación comunican el dictamen actualizado. No se cambia código funcional, contratos, dominio, plantilla, migraciones, gates ni permisos. No se sobrescriben los cambios concurrentes del mapa.

Matriz REG-SO y regresiones

Caso Evidencia dirigida
REG-SO-01 global Windows configurado Nuevo render global es/en, selector y recorrido MCP desde activo/puesto/mapa
REG-SO-02 Windows particular Test original del panel y OSUI-01/02/17; navegación particular real MCP
REG-SO-03 Windows y Ubuntu OSUI-06/07: ambos visibles, orden determinista, aplicaciones excluidas
REG-SO-04 pendiente OSUI-03/04/05/18: no acredita SO actual
REG-SO-05 retirado OSUI-03/04/05/18 y nuevo render global retirado
REG-SO-06 sin SO OSUI-03/04/05/18 y OSUI-16: «No registrado» / «Not recorded»
REG-SO-07 referencia no disponible OSUI-10: mensaje explícito, nunca ausencia
REG-SO-08 error de lectura OSUI-11: error previo/resolver y carga diferenciados; reintento visible
REG-SO-09 cambio de ordenador principal OSUI-08/12 y pruebas de ficha: seleccionar el nuevo activo excluye SO del anterior y de otra compañía
REG-SO-10 modificar versión OSUI-09 y guardado real 24H2 → 25H2 en diálogo del mapa; lectura actualizada en puesto y activo
REG-SO-11 global inactivo con instalación histórica Nuevo render activo/inactivo y retirada; suite MariaDB DB-SO-11–18
REG-SO-12 caché acotada Prueba específica reejecutada dentro de Resources; aplicaciones/perfiles permanecen sin invalidar

La suite dirigida ejecuta software.test.tsx, current-operating-systems.test.tsx, workstation-detail.test.tsx, workplace-map-layout.test.ts, workplace-node-actions.test.tsx y workspace-routes.test.ts: 93/93. El test originalmente fallido aislado con la fixture validada pasa 3/3. Resources pasa 116/116, incluido caché. Assets y Web pasan sus 29 y 3 ficheros respectivamente.

Companies completo pasa 305 de 307 tests: únicamente fallan los dos tests previos de ayuda de compañía/persona de companies-page.test.tsx. El test de software ya no falla. Los cuatro typechecks dirigidos de Resources/Companies/Assets/Web y ambos builds son correctos. Biome y ESLint dirigidos pasan sobre 26 archivos TS/TSX/JSON modificados de los consumidores. La sintaxis del script Python se comprueba mediante AST.

Integración, compatibilidad y fallos generales

Se repitió python3 scripts/resource-scope-test.py --operating-systems-closure --regressions: 29/29 + 50/50, exclusivamente en MariaDB desechable metis_desk_test. Incluye DB-SO-01–20, evolución doble, locks, atomicidad, versiones de contrato, aislamiento y rollback de gates; cero revisiones huérfanas. Las regresiones R2.3–R2.6 del cierre anterior siguen siendo antecedentes, no ejecuciones nuevas. No cambia su código backend y la repetición del cierre/HTTP-SQL confirma las fronteras afectadas.

Se repitieron las comprobaciones generales: pnpm typecheck continúa fallando en el calendario vendor (locale y exactOptionalPropertyTypes); pnpm lint conserva 15 errores y pnpm check 170. No se modificaron esas fuentes ni se relajaron validaciones. Los fallos de textos de ayuda no afectan selección, pertenencia o navegación del SO; el error de tipado vendor no aparece en los typechecks dirigidos ni impide los builds/recorridos probados; los diagnósticos generales de lint/formato están fuera de los archivos dirigidos verificados. Se clasifican como deuda general no bloqueante para el dictamen técnico del catálogo, sin declarar CI global verde ni autorizar omitir los controles de una publicación.

Nueva evidencia Playwright MCP

Ejecución final: .artifacts/playwright/authenticated-6u28upls, comando python3 scripts/visual-audit.py --global-operating-systems --check, salida cero y limpieza confirmada. Usa el servidor Docker stdio fijado en .codex/config.toml, Chromium 155.0.8059.12 y una instalación MariaDB desechable. Vite anuncia su puerto efímero y el navegador usa ese mismo origen. No se accede a una base real.

Resultado: 35 comprobaciones, 69 capturas nuevas y 69 SHA-256 verificados, conservados con el informe nuevo. No son las 27 capturas anteriores. La primera repetición del recorrido básico (authenticated-w6qb_oez) también pasó; otra ampliación (authenticated-z63g8xvr) pasó antes de incorporar las mediciones de contraste/foco al recorrido final. El informe final concentra todas las comprobaciones; no se suman como escenarios distintos las repeticiones.

Se comprobaron listado/detalle, borrador, formulario/revisión y error de identidad, selectores mixtos, panel e historial, activo, puesto, mapa y enlaces global/particular. Los consumidores, menús, historial y editor de instalación se capturaron en 320, 390, 768, 1280 y 1600 px, claro y oscuro; el listado incluye además 1024 px. Sin desbordamiento horizontal de página en los casos comprobados. La tabulación permanece en el diálogo; Escape cierra y devuelve foco al trigger; el menú admite Enter/flechas y muestra indicador de foco computado. Se inspeccionaron las capturas móviles de menú claro y editor oscuro, además de las verificaciones DOM.

Contraste mínimo medido de texto de menú: 17,22:1 claro / 14,52:1 oscuro, diez mediciones con foco visible. En el listado: 4,71:1 / 6,85:1. Se mantienen etiquetas accesibles, mensajes de carga/error/reintento y formulario es/en. Las pruebas de fallo y carga del listado usan interceptación de transporte únicamente para esos estados; las operaciones de catálogo, consulta, guardado y navegación usan la API real.

Se guardó 25H2 mediante el editor de instalación abierto desde el nodo SO global; se comprobó su lectura en el puesto y después en el activo y la navegación a la ficha particular coexistente. El menú/editor nuevo también se abrió en inglés. Volumen: 15 compañías; principal con 50 personas, perfiles y puestos, al menos 50 activos/recursos y 51 SO globales. No se ejecutó lector de pantalla real, zoom nativo ni una certificación WCAG completa; no se atribuyen esas pruebas.

El snapshot de fuentes registra HEAD y SHA-256 de 1884 archivos de los módulos/consumidores y biblioteca propia. La comparación al finalizar no detectó cambios. El manifiesto de la intervención registra fecha, comandos, resultados y hashes de evidencias. La revisión está identificada por HEAD más ese snapshot de trabajo; no se presenta HEAD solo como si incluyera los cambios sin commit.

Dictamen actualizado y límites operativos

GO técnico del catálogo global SO para el snapshot registrado. Se levantan los dos bloqueos específicos: la prueba pasa por la corrección demostrada de su fixture y los consumidores concurrentes relevantes tienen evidencia visual nueva. Los contratos funcionales, typechecks/builds dirigidos, aislamiento, persistencia y regresiones requeridas son satisfactorios. No se ha encontrado un bloqueo propio del catálogo que comprometa integridad o seguridad en los escenarios ensayados.

Permanecen los riesgos del apartado 17: unicidad comercial por policies/locks, convivencia de particulares, actualización necesaria de clientes incompatibles y ausencia de ensayo de infraestructura real/rendimiento de producción. La deuda general continúa abierta para sus mantenedores; puede impedir una publicación por la política CI del repositorio y requiere su tratamiento operativo, aunque no demuestra un defecto del catálogo validado.

Los pendientes iniciales del panel y validación visual quedan cerrados para este snapshot. Integración debe fijar la revisión a publicar y repetir comprobaciones si cambia el código. Operación/producto deben autorizar el despliegue, comprobar el destino y decidir gates según apartados 14–16. GO técnico, autorización de despliegue y activación efectiva son estados distintos: no se ha autorizado ni realizado aquí la activación de producción.

Reproducción específica

Desde modules/companies:

TSX_TSCONFIG_PATH=../../tsconfig.json node --import tsx --test --test-isolation=none src/web/software-installations/shared/software.test.tsx
TSX_TSCONFIG_PATH=../../tsconfig.json node --import tsx --test --test-isolation=none src/web/software-installations/shared/software.test.tsx src/web/software-installations/shared/current-operating-systems.test.tsx src/web/workstations/detail/ui/workstation-detail.test.tsx src/web/workstations/detail/helpers/workplace-map-layout.test.ts src/web/workstations/detail/helpers/workplace-node-actions.test.tsx src/web/workspace/shared/workspace-routes.test.ts

Desde la raíz:

bash scripts/setup-playwright-wsl.sh
python3 scripts/visual-audit.py --global-operating-systems --check
pnpm test:global-operating-systems:closure

Los comandos de typecheck, Resources, Assets, Web y builds del apartado 18 continúan siendo aplicables. Los servidores HTTP de prueba requieren loopback permitido. Las fixtures anteriores se reproducen usando el test de HEAD en una copia temporal dentro del paquete, conservando la configuración TSX del comando aislado; no se restaura el archivo de trabajo.