43 KiB
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.pyypackage.json: opción--operating-systems-closurey 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
- 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.
- 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.
- 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.
- 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.
- Desplegar lectores web/DTO v3 y rutas de detalle. Comprobar productos existentes, historial, versiones instaladas y clientes anteriores, con cuentas de mínimo privilegio.
- Autorizar OS_CATALOG=true y OS_SOFTWARE=false. Verificar administración, revisión, identidad, publicación y lectura ordinaria de productos aprobados.
- 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.
- 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 medianteResourceSchema.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.