80 KiB
D08.1 — Contrato arquitectónico de adopción controlada particular → global
1. Estado del documento
Propuesta, 25 de octubre de 2026. Dictamen: APTA CON CONDICIONES. No ratifica D08 ni autoriza implementación, R2.7 o despliegue. Las condiciones y decisiones pendientes están en §§23–25. Los nombres nuevos de tablas, permisos, operaciones, DTO, estados y flags son propuestas, no capacidades existentes.
Entrega exclusivamente documental: este es el único archivo nuevo autorizado. No se ejecutan DDL, DML, fixtures, servicios ni pruebas de una adopción inexistente. No se cambian código, modelos, schemas, APIs, permisos, flags, dependencias, tests ni documentos históricos. Se conserva el árbol previo no confirmado.
Base principal leída completa: R2.6, especialmente §29. Se contrastan R2.0, D01–D10, seguridad, HTTP/DTO, consumidores e informes R2.2, R2.3, R2.4 y R2.5, consultados en esta misma secuencia de trabajo. No se reinterpretan sus evidencias históricas como nuevas pruebas.
Se consultan AGENTS.md, DESIGN.md, capas, composición, DDD, HTTP, software, aplicaciones del perfil y auditoría central. Se aplica rdx-solid y sus referencias de arquitectura/backend/decisiones para evaluar alternativas, agregados y transacciones. No se diseña una pantalla ni se realiza auditoría visual nueva.
Leyenda: V verificado; P propuesta fundamentada; A pendiente de aprobación; T dependencia técnica; R riesgo residual; F fuera de alcance. Una propuesta detallada no equivale a una decisión ratificada.
2. Resumen ejecutivo
D08.1-A/P: recomendar A2, sucesión de asociaciones seleccionadas de una compañía, con revisión humana de producto, preflight persistido e inmutable, confirmación atómica e idempotente y procedencia relacional. No se adopta el Resource como entidad: se documentan nuevas asociaciones al global y se cierran las anteriores por una causa explícita. Particular y global mantienen identidad, ámbito, propietario e historial. El particular sigue disponible en selectores.
Hallazgo V: ambos agregados tienen removed, pero significa retirada técnica. No tienen cierre por sucesión documental. Simular configured → removal_pending → removed para cambiar una referencia falsearía su historia. Se propone aprobación separada D08.1-B1 de un terminal documental superseded, exclusivo de estos agregados, con revisión causal y negociación de consumidores. No existe hoy; sin aprobarlo o una alternativa equivalente, la confirmación sigue bloqueada.
Los permisos explícitos de adopción, la auditoría central y el escritor transaccional conjunto tampoco existen. Los repositorios actuales abren transacciones propias y usan upsert: no se pueden encadenar sin adaptación. Estas son dependencias delimitadas, no garantías actuales.
Mantener A0/R2.6 mientras falte aprobación. Una futura primera fase puede preparar autorización, auditoría, lectores compatibles y preflight; confirmación y compensación requieren autorización y gates separados. No se cierra la aceptación global pendiente del programa.
3. Problema y justificación
R2.6 descubre candidatos; no acredita equivalencia ni mueve asociaciones. resourceId y asset/profile son targets inmutables de las raíces operativas. Actualizar solo la raíz rompería su coherencia con revisiones anteriores; reescribir también esas revisiones destruiría la evidencia histórica.
Adoptar tiene sentido cuando un operador autorizado decide documentar asociaciones concretas bajo un producto global ya verificado. Puede no convenir por edición, licencia, ambigüedad o consumidores solo locales. Mantener coexistencia es una decisión legítima, no un defecto que corregir automáticamente.
La operación no instala, desinstala, concede acceso ni consume licencias. Una sucesora configurada exige verificación expresa de disponibilidad. Versión instalada, licencia y forma de uso siguen siendo datos locales de cada asociación.
4. Contratos actuales verificados
Los enlaces apuntan a código vigente; los métodos futuros propuestos no se consideran implementados.
| Evidencia | Contrato V e implicación |
|---|---|
| Resource, ownership | Raíz company/UniqueID o global/null; create/createGlobal separados; owner/scope/plantilla fijos. |
| Modelo inicial, migración scoped | MariaDB, expansión explícita, CHECK scope/owner y FK; no catálogo de aplicaciones paralelo. |
| SoftwareInstallation, valores | Raíz UUID, compañía, asset/resource fijos; create solo pending/configured; update no cambia target; terminales inmutables. |
| ApplicationConfiguration, valores | Raíz UUID, compañía, profile/resource fijos; versión solo installed; historial de revisiones propias. |
| Transiciones Software, Profile | pending→configured o never_configured; configured→removal_pending→removed. No existe superseded ni closeForAdoption. |
| WorkProfile, Workstation | Agregados locales independientes. No se reasignan por adoptar una aplicación; el perfil controla configuraciones al comprobar borrado. |
| Mapper Software, Profile | Validan target fijo, disponibilidad y pareja abierta única; no equivalencia comercial. |
| Migración Software, Profile | QueryInterface crea raíces/revisiones, currentKey nullable UNIQUE y UNIQUE(configurationId,position). No hay dos Model Sequelize con hooks de adopción ya instalados. |
| Snapshots Software, Profile | FK RESTRICT a recursos, activo/perfil, licencia nullable y actor en revisiones. state STRING(20) no autoriza estados desconocidos al dominio. |
| Repo Software, Profile | get/save/remove abren transacción propia; persist privado usa ON DUPLICATE KEY UPDATE; remove elimina raíz y revisiones. Eliminar no es cerrar. |
| Sesión Resources, puerto | forTransaction recibe Transaction: catálogo compartido y compañía FOR UPDATE; resolve recupera inactivos; validateNewAssociation comprueba actividad/gate por propósito. |
| Dependencias Companies | Lectores Resources/Assets ligados a transacción; no hay escritor público de sucesión. ORM permanece en Infrastructure. |
| Guard global, Identity | Sesión y administrador inicial comprobados en servidor. No hay resources.adoption.confirm ni ACL granular operador–compañía. |
| DTO Software, Profile | Zod estricto, cinco estados, historial completo, sin procedencia de sucesión. Referencias globales negocian Resources-Contract: 2. |
| Software API/keys, Profile API/keys | Familias por compañía, timeout y validación de respuesta. No queries de planes/operaciones. |
currentKey es assetUUID:resourceUUID o profileUUID:resourceUUID, NULL si removed/never_configured. Las cerradas no bloquean otro registro con UUID nuevo del mismo par. No existe versión numérica general del agregado: hay UUID/posición de revisiones, fecha y valores reconstruidos. La última revisión detecta incluso un cambio que después vuelve al valor anterior; la fecha sola no basta.
La búsqueda de FK en migraciones encuentra revisiones como hijos directos de ambas raíces. No se consultó una BD real ni se garantiza ausencia de dependencias externas/futuras. Procesos, entorno, puesto y paneles son consumidores indirectos que también deben revisarse.
El prefijo actual de escritura operativa es catálogo compartido → compañía exclusiva, conforme al código y R2.4/R2.5. R2.2 describe una etapa anterior con lock exclusivo de catálogo; no se copia como comportamiento actual. CRUD Resource/propagación usa catálogo exclusivo y puede coordinar Access antes de compañía. Adopción no escribe esos recursos ni necesita locks Access.
La auditoría central está acordada como diseño futuro, todavía no implementado. Revisiones con actor/fecha y requestId no son por sí solas journal transversal ni idempotencia de adopción.
5. Invariantes
| ID | Regla futura obligatoria | Verificación exigida |
|---|---|---|
| I01 | UUID particular/global distintos y conservados; no cambiar owner/scope/plantilla. | Dominio, HTTP estricto y snapshots SQL. |
| I02 | Raíz anterior conserva UUID, target y todas sus revisiones; solo añade cierre aprobado. | Mapper, FK y comparación de revisiones previas. |
| I03 | Sucesora UUID v7 nueva, misma C y asset/profile, destino elegible. | create y procedencia tipada. |
| I04 | Cerradas históricas no se reabren ni reescriben. | Dominio y ausencia de UPDATE histórico. |
| I05 | Estado, versión, licencia, delivery y notas de sucesora son decisiones explícitas revisadas. | Plan y aceptación de huella; sin inferencia textual. |
| I06 | No fusionar, descartar ni actualizar asociaciones de destino por colisión. | Conflicto de par, UNIQUE y carreras. |
| I07 | Todas las seleccionadas o ninguna; no omitir conflictos al confirmar. | Una transacción y fallos por punto de escritura. |
| I08 | Solo referencias locales C y globales por propósito; permiso efectivo en servidor. | Puertos/policies y pruebas negativas. |
| I09 | Éxito requiere procedencia, revisiones y auditoría en el mismo commit. | Fallo de auditoría provoca rollback. |
| I10 | Repetición idéntica conserva resultado sin duplicar sucesoras/eventos efectivos. | Idempotencia durable y UNIQUE. |
| I11 | Gates off no ocultan historia ni revierten operaciones. | Lectores y despliegue compatibles. |
| I12 | Particular sigue disponible según sus reglas; sin archivo automático ni alias de identidad. | Recursos y selectores sin sustitución. |
Son compatibles con D01–D10. Cierre documental y negociación nuevos requieren aprobación adicional, no se consideran ya ratificados.
6. Alternativas
D08.1-A/P, comparación sin puntuaciones arbitrarias:
| Alternativa | Integridad, compatibilidad y reversibilidad | Coste, operación y pruebas | Recomendación |
|---|---|---|---|
| A0: mantener R2.6 | Conserva todo; no precisa compensación. | Menor riesgo/coste; el operador elige globales en altas nuevas. | Válida permanentemente y mientras falte aprobación. |
| A1: reasignar resourceId | Contradice sameTarget, I02 y D08; raíz e historial divergen o se destruye historia. | Simplicidad SQL aparente; exige rehacer dominio y consumidores. | Descartada bajo estas invariantes; requeriría modificar decisiones ratificadas. |
| A2: cierre y sucesión | Conserva recursos y raíces anteriores; nueva identidad y causa. Falta cierre documental. Compensar es otra sucesión. | Más coste en permisos, lectores, procedencia, transacción e idempotencia; pruebas de carreras/fallos. | Preferida condicionalmente, sin retirada ficticia. |
| A3: equivalencia documental | No mueve asociaciones; no sustituye validación por propósito ni prueba identidad universal. | Menor riesgo operativo, pero añade aprobación/corrección/auditoría de relación. | Funcionalidad independiente diferida, no prerrequisito oculto de A2. |
| Híbrida A2 + R2.6 | Solo seleccionadas pasan al global; demás consumidores siguen locales. | Lotes delimitados, obligación de explicar parcialidad. | Forma recomendada; sin alias ni A3 persistida implícita. |
7. Semántica de adopción
Una propuesta descubre un candidato. Un plan contiene fotografía, selección y evidencia revisable. Una decisión autorizada confirma expresamente ese plan vigente. Una operación confirmada existe únicamente después del commit y su auditoría.
Propuesta funcional sujeta a P02:
- Un plan tiene una compañía, una fuente particular y un destino global; nunca varias compañías/destinos.
- Selección individual explícita de raíces Software, Profile o ambas. Permitir adopción parcial respecto al inventario total.
- Confirmación atómica de todas las seleccionadas. Conflictos seleccionados bloquean el conjunto; no existe «seguir con las válidas».
- No seleccionadas, cerradas y otros consumidores se enumeran intactos. No hay marca de Resource «adoptado» que redirija usos futuros.
- Selección vacía produce
ADOPTION_NO_EFFECT, sin operación ficticia equivalente a A3. - Plan conservable sin ejecutar; cambiar selección/valores/evidencia crea otro plan inmutable. No se encadenan lotes automáticamente.
flowchart TD
R[Coincidencia R2.6 o destino elegido] --> E[Revisión comercial y operativa]
E --> P[Preflight persistido en una compañía]
P --> B{Completo y sin bloqueos seleccionados}
B -->|No| N[Nuevo plan o coexistencia]
B -->|Sí| C[Confirmación explícita e idempotente]
C --> V{Datos y permisos vigentes bajo locks}
V -->|No| F[Conflicto sin efectos operativos]
V -->|Sí| T[Cierre aprobado, sucesoras y auditoría]
T --> M[Commit único]
M --> H[Resultado e historia consultables]
H --> K[Compensación independiente si se aprueba]
8. Agregados afectados
D08.1-B/P y B1/A:
| Dimensión | SoftwareInstallation V | ApplicationConfiguration V | Sucesión P |
|---|---|---|---|
| Identidad/propietario | UUID y companyId obligatorio. | Igual. | Anterior conservada; sucesora UUID v7 nueva y misma C. |
| Target | assetId/resourceId fijos. | profileId/resourceId fijos. | Mismo asset/profile, nuevo Resource en otra raíz. |
| Cierre disponible | update pending→never_configured o removal_pending→removed; no closeForAdoption. | Igual. | Comando causal B1 condicionado; no remove/delete. |
| Alta | create(company,values,actor,time), solo pending/configured. | Igual. | create real, no rehydrate; estado revisado, nunca configured por defecto. |
| Campos obligatorios/nullable | assetId, resourceId, licencia nullable, versión nullable ≤100, state, notas nullable ≤4.000. | profileId, resourceId, delivery installed/web, versión nullable ≤100, state, notas nullable ≤4.000. | Todos explícitos; copiar/cambiar/vaciar requiere decisión del plan. |
| Versión/licencia/entrega | Licencia local válida al asociar; no prueba cobertura de fabricante. | Web exige versión null; no campo licencia. | No trasladar automáticamente ni introducir licencia en Profile. |
| Unicidad | currentKey UNIQUE par abierto; cerradas NULL. | Igual por profile/resource. | Liberar par anterior al cerrar; destino abierto debe estar libre. Destino histórico cerrado no bloquea por sí solo. |
| Historial | UUID/posición/actor/fecha y valores con target fijo. | Igual. | Nueva revisión de cierre y primera de sucesora; no modificar previas. |
| Elegibilidad | Activo no retirado, referencia disponible y licencia activa/vigente. | Perfil/persona activos, activo no retirado, aplicación disponible y forma de uso válida. | Policies actuales más validación Resources de nueva asociación por propósito. |
| Dependencias | Revisiones y vistas de equipo/puesto. | Revisiones, perfiles, entorno/procesos. | Procedencia añade FK; dependencias incompatibles bloquean, no se reasignan. |
B1: decisión separada de cierre documental
Se recomienda someter a aprobación superseded, terminal solo de estos dos agregados: pending/configured→superseded, conservando versión/licencia/delivery/notas/target anteriores. Se añade revisión causal vinculada a la operación. No afirma retirada técnica. removal_pending seleccionado bloquea: hay que resolver la retirada real fuera y repetir preflight. removed/never_configured quedan intactos y no se seleccionan.
No ampliar sin más ConfigurationSchema compartido con Access: introduciría el estado en familias sin sucesión. Se necesitan unions específicas de Software/Profile, transiciones, closed, currentKey, mappers, builders, historial, filtros, contadores, traducciones y negociación. Que STRING(20) admita el texto no resuelve nada de ello.
Sin B1: mantener A0. Puede evaluarse por separado un piloto solo pending→never_configured con sucesora pending, si expresa cancelación real de una necesidad; no cubre configuradas ni está autorizado implícitamente. Un indicador lateral que deje la anterior como configured tampoco resuelve closed/currentKey ni representación legacy sin otro contrato.
Ambos agregados están en Companies/MariaDB y pueden compartir una unidad tras adaptar sus puertos. Hoy no la comparten. No requieren transacción distribuida ni commits separados para cerrar y crear.
9. Modelo relacional propuesto
D08.1-C/P. Conceptual, sin migración ni SQL ejecutable. Companies posee planes y operaciones; Resources aporta referencias públicas ligadas a transacción, Identity autoriza y auditoría común registra. No se crea un framework ni dependencia Resources→Companies.
Todas las entidades e internas, incluidos items, evidencias, conflictos e intentos, tienen UniqueID/UUID v7. Fechas UTC. No hay notas ni JSON que sustituyan relaciones.
| Tabla conceptual | Datos y relaciones esenciales |
|---|---|
resource_adoption_plans |
id PK; companyId FK; sourceResourceId/targetResourceId FK; createdBy FK y nombre seguro conservado; createdAt/expiresAt; kind adoption/compensation; originalOperationId FK nullable para compensación; status ready/blocked; schemaVersion/policyVersion; fingerprint BINARY(32) y creationRequestFingerprint separado; nombres/proveedor/active/template/scope/owner observados y revisión Resource mediante FK. Inmutable. |
resource_adoption_plan_evidence |
id, planId FK, kind vendor-document/product-reference/operator-verification, referenceText/explanation acotados sin secretos, actorId/fecha. Evidencia humana, no permiso. |
resource_adoption_plan_software_items |
id, planId, sourceInstallationId FK, sourceRevisionId FK/posición, assetId FK, role source/destination, selected, observedState, action keep/succeed, proposedState/version/licenseResourceId/notes, decisiones explícitas de versión/licencia y evidencia de compatibilidad. Observación histórica mediante revisión conservada y columnas necesarias. |
resource_adoption_plan_application_items |
Variante tipada: sourceConfigurationId/revisionId, profileId, role source/destination, selected, observedState, acción y proposedState/delivery/version/notes, decisión de aplicabilidad; sin licencia. |
resource_adoption_plan_dependencies |
id, planId, dependencyKind/Id, revisión o huella observada, disposition keep/block. FK tipadas cuando exista tabla estable; referencias diagnósticas sin FK se reconocen como tales, no se inventa FK polimórfica. |
resource_adoption_plan_conflicts |
id, planId, code, severity, blocksConfirmation; FK nullable a item software o perfil, o ninguna para conflicto de plan, CHECK como máximo una. Detalle público acotado, no SQL. |
resource_adoption_commands |
id PK solicitado v7, companyId/actorId FK, action confirm/compensate, idempotencyKey UUID, planId FK, requestFingerprint, state pending/committed/rejected, fecha, resultCode, resultOperationId FK nullable. Reserva durable, no adopción confirmada. |
resource_adoption_operations |
id PK v7 servidor; commandId FK UNIQUE, planId FK UNIQUE; compañía/origen/destino/actor/FK; nombres históricos mínimos, authorizedAt/committedAt, kind; originalOperationId FK UNIQUE nullable para compensación completa. Solo resultados confirmados, sin estado parcial. |
resource_adoption_software_items |
id, operationId FK, planItemId FK UNIQUE, predecessorId/successorId FK software_installations, predecessorClosureRevisionId/successorInitialRevisionId FK; UNIQUE predecessorId, UNIQUE successorId, CHECK anterior≠sucesora. Solo ejecutadas. |
resource_adoption_application_items |
Mismas relaciones tipadas hacia application_configurations/revisiones. No entityId genérico en lugar de FK. |
| Auditoría común: operaciones/eventos/cambios tipados | Modelo futuro ya acordado: actor, petición, resultado, efectos y causalidad; vínculo único con operación de adopción. No journal paralelo sustitutorio. |
| Intentos comunes | ID, commandId opcional, requestId, actor autenticado cuando exista, acción, código seguro y fecha, referencia al resultado original. Rechazo/transitorio se distingue de efecto confirmado. Integración futura con auditoría común. |
erDiagram
COMPANY ||--o{ ADOPTION_PLAN : delimita
COMPANY ||--o{ ADOPTION_OPERATION : delimita
RESOURCE ||--o{ ADOPTION_PLAN : fuente_particular
RESOURCE ||--o{ ADOPTION_PLAN : destino_global
ACTOR ||--o{ ADOPTION_COMMAND : solicita
ADOPTION_PLAN ||--o{ PLAN_SOFTWARE_ITEM : observa
ADOPTION_PLAN ||--o{ PLAN_PROFILE_ITEM : observa
ADOPTION_PLAN ||--o{ PLAN_EVIDENCE : fundamenta
ADOPTION_PLAN ||--o{ PLAN_CONFLICT : explica
ADOPTION_PLAN ||--o{ PLAN_DEPENDENCY : conserva
ADOPTION_COMMAND ||--o{ AUDIT_ATTEMPT : diagnostica
ADOPTION_PLAN ||--o{ ADOPTION_COMMAND : solicita
ADOPTION_COMMAND ||--o| ADOPTION_OPERATION : confirma
ADOPTION_OPERATION ||--o{ SOFTWARE_SUCCESSION : produce
ADOPTION_OPERATION ||--o{ PROFILE_SUCCESSION : produce
SOFTWARE_INSTALLATION ||--o| SOFTWARE_SUCCESSION : predecesora
SOFTWARE_INSTALLATION ||--o| SOFTWARE_SUCCESSION : sucesora
APPLICATION_CONFIGURATION ||--o| PROFILE_SUCCESSION : predecesora
APPLICATION_CONFIGURATION ||--o| PROFILE_SUCCESSION : sucesora
ADOPTION_OPERATION ||--|| AUDIT_OPERATION : registra
ADOPTION_OPERATION o|--o| ADOPTION_OPERATION : compensada_por
Las filas destination del plan son observaciones keep, nunca seleccionables; conservan testigos de parejas abiertas/cerradas además del inventario source. Cada operación tiene al menos un item en total; cada colección tipada puede estar vacía. Una sucesora puede ser predecesora de compensación: son roles diferentes. Los fallos pertenecen a planes/intentos, no a líneas fingidas de una ejecución parcial.
Restricciones y límites del motor
Propuesta: RESTRICT al borrar/actualizar identidades, sin cascadas hacia procedencia, raíces, revisiones o auditoría. UNIQUE(companyId,actorId,action,idempotencyKey) reserva petición; commandId también es único global. CHECK asegura coherencia state/resultOperationId/resultCode y referencias locales de cada fila.
FK compuestas para misma C: claves candidatas UNIQUE(id,companyId), incluidas en raíces operativas si se necesitan, y columnas correspondientes en elementos. Para revisión de raíz: UNIQUE(id,configurationId) y FK compuesta desde elemento; en revisión Resource, (id,resourceId). Son índices futuros explícitos, no ya existentes. Tipos/longitudes/collation deben coincidir con las columnas vigentes; UniqueID no impone un formato físico UUID distinto al actual.
FK simple garantiza existencia, no owner/scope, permiso, vigencia, plantilla o equivalencia. Estas condiciones requieren servicios bajo transacción. No proponer CHECK con consultas a otras tablas. CHECK local puede asegurar IDs distintos, campos por estado y referencias exclusivas; que haya items, no ciclos de compensación, mismo asset/profile y target correcto requiere validación transaccional.
currentKey UNIQUE nullable permite varios históricos cerrados; no es un índice parcial WHERE. El mapper verifica su correspondencia con estado/target y B1 debe mantenerla. MariaDB FK admite ausencia de padre si un componente es NULL: no usar owner global nulo en una FK compuesta para fingir comprobación de pertenencia.
Índices iniciales propuestos: planes/operaciones (companyId,fecha,id), operaciones (sourceResourceId,id)/(targetResourceId,id), comandos por clave única y (companyId,state,id), items por plan/operación y referencias de navegación, conflictos por (planId,id). Requieren EXPLAIN/volumen en R2.7. Constraints con nombres únicos en la BD 11.8 ensayada, sin asumir reglas de MariaDB 12.1; documentación oficial.
Sin purga inicial. Consecuencia funcional pendiente de P07: las FK RESTRICT de observaciones de planes también retienen raíces/revisiones no seleccionadas o de planes abandonados. Crear un preflight no altera su estado operativo, pero sí puede impedir su borrado posterior. Este coste no se oculta como compatibilidad aditiva: requiere aprobación antes de habilitar planes persistidos. Si no se acepta, rediseñar previamente observaciones históricas normalizadas con identidad conservada y referencias vivas opcionales, sin borrar evidencia ni fingir FK polimórficas.
Endpoints delete actuales deben rechazar explícitamente toda raíz/revisión retenida por plan o procedencia antes de borrar revisiones; FK RESTRICT como defensa final. Igual protección para Resource, compañía y revisiones/actores referenciados. No cambiar a SET NULL para facilitar borrado. Se conservan nombres seguros históricos además de referencias vivas, según auditoría central. Retención/anonimización definitiva es decisión funcional pendiente, no recomendación jurídica; una purga futura no puede permitir reutilizar una clave confirmada y necesita tombstone relacional suficiente.
10. Preflight
D08.1-D/P. Solo crea metadatos de plan y auditoría; no cambia Resources ni asociaciones. Una lectura efímera no es confirmable. Observación coherente y guardado dentro de una transacción breve según §12; al responder libera locks, sin snapshot entre peticiones.
Entrada: compañía del path, fuente/destino, selección tipada UUID, valores deseados por sucesora y evidencia; creationId v7 para reintento del mismo plan. Todos los nullable explícitos. Actor/owner/scope/capacidades no proceden del body.
| Bloque del plan | Datos revisables |
|---|---|
| Identidad | C, UUID/ámbito/owner de ambos, nombres/proveedor observados, descripción/URL pública para distinguir edición, active y plantilla real. |
| Elegibilidad | Resultado separado software-installation/application-configuration, razones y gate efectivo. Solo propósitos seleccionados bloquean confirmación. |
| Inventario | Abiertas/cerradas de la fuente, UUID, asset/profile y contexto propio autorizado, última revisión/posición, estado; seleccionadas frente a intactas. |
| Valores | Software: versión/licencia/estado; Profile: delivery/versión/estado; antes/propuesto y decisión explícita conservar/cambiar/vaciar, sin secretos de licencia. |
| Conflictos | Bloqueos de plan/seleccionadas, avisos de no seleccionadas, asociaciones destino abiertas/cerradas, dependencias y revisión humana necesaria. |
| Efectos | Cierre B1 exacto si aprobado, nueva raíz por item, conservación del resto, resultado esperado; ninguna instalación/desinstalación física. |
| Control | planId, versión de schema/policy, fingerprint, createdAt/expiresAt, ready/blocked, cobertura y conteos exactos de la fotografía, permisos requeridos. |
Colecciones paginadas en servidor sobre filas persistidas del plan, cursor ligado a plan/tipo, orden UUID, pageSize 1..100 (20 por defecto). No consultar inventario vivo en cada página fingiendo que es el plan original. Solo inventario completo produce ready; el complete de una página R2.6 no acredita cobertura de dependencias.
Presupuestos propuestos sujetos a P04: 100 seleccionadas, 10.000 observadas, vigencia 30 minutos. No son benchmarks. Exceso/fallo de fuente produce blocked y ADOPTION_PLAN_TOO_LARGE/ADOPTION_PLAN_INCOMPLETE, nunca truncamiento silencioso confirmable. Expirar no borra el registro. Validar límites con volumen antes de ratificar producción.
Repetir creationId exige mismo actor/C y misma huella de entrada canónica creationRequestFingerprint; devuelve el plan original, aunque haya quedado obsoleto, sin volver a observar y generar otra fotografía bajo ese ID. La huella de entrada excluye fechas/observaciones generadas por servidor y se distingue de fingerprint del plan.
R2.6 localiza destinos; ni name-provider ni name-only otorgan conformidad. Evidencia: referencia identificada del proveedor, ficha comercial/edición, inventario con identificador comercial o verificación explícita de lo instalado/disponible. Debe explicar aplicabilidad de versión, licencia y forma de uso. Si falta proveedor o hay ambigüedad, exigir evidencia adicional concreta y explicación; un checkbox o repetir el nombre no basta. Edición incompatible bloquea la pareja: otro destino o coexistencia, sin «forzar» ni inventar provider.
Regla propuesta de evidencia confirmable: una operator-verification y al menos una product-reference o vendor-document identificable, especialmente si falta provider; explanation debe distinguir producto/edición y no repetir solo el nombre. Una product-reference puede remitir al inventario técnico autorizado, sin exigir documentación pública inexistente.
Zod puede validar estructura/presencia, no demostrar veracidad comercial. La comprobación comercial sigue siendo responsabilidad humana auditable. No se copian notas administrativas globales; notas operativas antiguas quedan en la raíz anterior, y cualquier nota sucesora se revisa explícitamente sin credenciales.
11. Conflictos
D08.1-E/P. B = bloqueante; H = bloqueante con revisión humana; W = advertencia no seleccionada; I = repetición informativa. H no permite bypass. Excluir una asociación exige otro plan y explica parcialidad. Detalles solo sobre información ya autorizada.
| Condición verificable | Severidad / bloquea | Revisión y alternativa | Código propuesto / efecto |
|---|---|---|---|
| Destino global inactivo | B / sí | Otro destino o reactivación autorizada fuera, luego preflight. | ADOPTION_TARGET_UNAVAILABLE; blocked/stale. |
| No elegible Software | B / sí si software seleccionado | Corregir destino; no OS global. | ADOPTION_SOFTWARE_INELIGIBLE; blocked. |
| No elegible Profile | B / sí si perfil seleccionado | Otra aplicación; no seleccionada solo W. | ADOPTION_PROFILE_INELIGIBLE. |
| Fuente de B/scope incorrecto; referencia o raíz inexistente | B / sí | Respuesta uniforme sin datos de B; nueva selección. | ADOPTION_REFERENCE_NOT_FOUND; 404. |
| Instalación seleccionada cerrada | B / sí | Conservar intacta; seleccionar otra abierta en nuevo plan. | ADOPTION_SOFTWARE_CLOSED. |
| Configuración seleccionada cerrada | B / sí | Igual para perfil. | ADOPTION_PROFILE_CLOSED. |
| Cerrada observada, no seleccionada | W / no | Conservar target/historial. | ADOPTION_HISTORY_PRESERVED; keep. |
| removal_pending seleccionada | H / sí | Resolver retirada real fuera; preflight nuevo. | ADOPTION_WITHDRAWAL_IN_PROGRESS. |
| Asociación destino ya abierta en mismo asset/profile | H / sí | No merge. Excluir o resolver fuera y nuevo plan. | ADOPTION_DESTINATION_ALREADY_OPEN. |
| Carrera de currentKey asset/global | B / sí | Rollback; regenerar plan, sin upsert a raíz ajena. | ADOPTION_SOFTWARE_PAIR_CONFLICT. |
| Carrera de currentKey profile/global | B / sí | Igual para perfil. | ADOPTION_PROFILE_PAIR_CONFLICT. |
| Licencia ajena, tipo inválido, inactiva/caducada | B / sí | Otra local válida o null explícito admisible. | ADOPTION_LICENSE_UNAVAILABLE. |
| Cobertura comercial de licencia sin acreditar | H / sí | Evidencia o null revisado sin afirmar cobertura. | ADOPTION_LICENSE_COMPATIBILITY_UNCONFIRMED. |
| Versión de otra edición o no revisada | H / sí | Verificar/proponer valor o null; no inferir del nombre. | ADOPTION_VERSION_UNCONFIRMED. |
| delivery web con versión no nula | B / sí | Corregir null o installed en otro plan. | ADOPTION_DELIVERY_CONFLICT; 400 si DTO inválido. |
| Activo retirado, perfil/persona inactivos | B / sí | Conservar anterior; resolver legítimamente fuera. | ADOPTION_CONTEXT_UNAVAILABLE. |
| Cambio de revisión/estado/licencia/contexto/inventario | B / sí | Nuevo preflight aunque valores vuelvan al anterior. | ADOPTION_PLAN_STALE; cero efectos. |
| Plan expirado/incompleto/huella distinta | B / sí | Nuevo plan revisado. | ADOPTION_PLAN_EXPIRED/INCOMPLETE/STALE. |
| Permiso insuficiente | B / sí | Sujeto habilitado; sin elevar rol por body. | FORBIDDEN; 403 antes de datos protegidos. |
| Flags necesarios off | B / sí para ejecución nueva | Procedimiento de activación, no botón que los cambie. | ADOPTION_FEATURE_DISABLED; 409. |
| Misma clave/contenido finalizado | I / no ejecuta | Resultado original tras autorizar consulta. | Mismo resultado, sin efectos nuevos. |
| Misma clave/contenido diferente o contexto inválido | B / sí | No reutilizar ni revelar resultado ajeno. | ADOPTION_IDEMPOTENCY_CONFLICT o 404 seguro. |
| Dependencia incompatible sobre raíz a cerrar | H / sí | Resolver fuera o excluir en nuevo plan; no mover su FK. | ADOPTION_DEPENDENCY_CONFLICT. |
| Nueva dependencia/consumidor no preparado | B / sí | Contrato/soporte antes de confirmar. | ADOPTION_DEPENDENCY_CHANGED. |
| B1, auditoría o escritor unitario no disponibles | B / sí | Mantener A0 y gate de confirmación off. | ADOPTION_NOT_READY. |
| Fallo intermedio | B / sí | Rollback total, recuperar por clave. | INTERNAL_ERROR/ADOPTION_RETRY_REQUIRED. |
| Selección vacía | B / sí | Coexistencia; A3 aparte. | ADOPTION_NO_EFFECT. |
Pertenencia/tipo inaccesible no se convierte en 409 detallado que revele datos. La vigencia de licencia se vuelve a comprobar al cruzar medianoche UTC aunque sus revisiones no cambien. Todos los conflictos seleccionados se resuelven antes de confirmar; no hay confirmación parcialmente exitosa.
12. Concurrencia
D08.1-F/P. Huella detecta cambio; locks y transacción protegen validación/escritura. Ninguna sustituye a la otra.
Huella canónica
SHA-256 d081-plan-v1: secuencia de campos tipados, UTF-8, longitudes y marcadores diferentes para ausente/null/texto/bool/entero; colecciones ordenadas por tipo/UUID; UUID minúscula, fechas ISO UTC, posiciones enteras. Strings validadas preservan semántica: no aplicar normalizador de coincidencias a valores operativos. No depender de orden de propiedades ni JSON.stringify para igualdad de dominio. HTTP representa 64 caracteres hex; persistencia 32 bytes.
Incluye versión de schema/policy, C/plan/tipo, fuente/destino con scope/owner/template/active y revisión/posición, datos públicos comerciales observados; selección/acciones/evidencia/valores sucesores; revisión/posición/valores de todas las raíces observadas; pares destino; testigos de activo/perfil/persona/licencia con actividad/vigencia y revisiones disponibles; dependencias; gates relevantes; createdAt/expiresAt. En tablas sin revisión, incluir columnas relevantes validadas o su huella; no inventar rowVersion existente. El día UTC de vigencia de licencia se revalida además.
Servidor recupera plan persistido y reconstruye observaciones bajo locks; separa intención inmutable y datos vigentes. Nueva revisión invalida aunque el valor vuelva al anterior. Nueva raíz incluso no seleccionada invalida conservadoramente inventario; propagación de plantilla puede invalidar revisión Resource. Permiso se comprueba aparte: un booleano hasheado no acredita autorización.
Token propuesto (planId,fingerprint,expiresAt) comprobado contra filas del servidor; no credencial portadora ni permiso para saltar lecturas. Hash diferente→conflicto, nunca aprobación de un hash nuevo enviado por navegador. No hay snapshot entre peticiones.
Orden de locks
- Autorizar petición sin retener locks de usuario mientras se espera compañía; política vigente al inicio como R2.2, sin revocación retroactiva prometida.
- Abrir unidad; primera operación, puerto Resources de escritura: catálogo
LOCK IN SHARE MODEy compañía CFOR UPDATE. - Bloquear comando reservado y plan, por ese orden. Reserva previa breve confirma solo metadatos, sin retener locks operativos (§14).
- Current reads compartidas de fuente/destino/licencias por UUID ordenado mediante puertos propietarios; definiciones protegidas por catálogo. No invocar CRUD Resource ni elevar lock compartido a exclusivo.
- Leer/proteger contexto/dependencias mediante APIs ligadas; raíces Software por UUID y después Profile por UUID, orden fijo. Comprobar que todos los escritores del contexto respetan mutex de compañía.
- Revalidar conjunto/huella/parejas/testigos. Mutex cubre pares destino sin fila aún; UNIQUE es defensa final. No SKIP LOCKED que omita seleccionadas.
- Persistir cierre, sucesoras, procedencia y auditoría; commit libera locks.
No asumir que snapshot ordinario REPEATABLE READ tomado antes de esperar es lectura actual; revalidación requiere current reads y conjunto coherente bajo mutex. No imponer SERIALIZABLE global. Escrituras SQL externas sin protocolo quedan fuera de esa garantía y exigen controles operativos.
Catálogo exclusivo de desactivación serializa con asociación: si desactivación commit primero, rechazo; si adopción primero, sucesoras se conservan y una desactivación posterior puede causar needsReview. No se promete impedir desactivación legítima posterior. Deadlock/timeout→rollback y error reintentable; reintentos internos, si existen, acotados sobre unidad completa con revalidación, no continuación de un item.
13. Atomicidad
D08.1-G/P. Un caso de uso Companies coordina; puerto Application describe unidad de negocio, Infrastructure abre una Transaction y liga escritores/lectores propietarios. Sin ORM en Domain/Application. Reutilizar policies/create y añadir comando B1 si aprobado. No encadenar endpoints ni save actuales suponiendo que heredan una transacción externa: no la admiten.
Dependencias T: escritores internos ligados para ambas raíces, lectura actual de contexto/dependencias, B1, resultado/procedencia y auditoría. Composición explícita, sin exportar modelos de Resources ni crear DI framework.
Upsert actual no es alta segura de sucesora: ON DUPLICATE KEY UPDATE puede colisionar con currentKey de otra raíz y actualizar sus valores. Exigir INSERT estricto, nuevo UUID y conflicto UNIQUE saneado. Para predecesoras: UPDATE por identidad/testigo y append de revisión; comprobar filas afectadas e IDs, nunca reinterpretar colisión de pareja como actualización idempotente.
sequenceDiagram
participant U as Operador
participant H as HTTP Companies
participant C as Coordinador Infrastructure
participant R as Resources público
participant DB as MariaDB
U->>H: Plan, huella, clave y confirmación
H->>H: Sesión, permiso, CSRF y DTO
H->>C: Reserva durable autorizada
C->>DB: Reserva y auditoría; commit breve
C->>DB: BEGIN unidad operativa
C->>R: Sesión ligada a Transaction
R->>DB: Catálogo S y compañía X
C->>DB: Comando, plan, referencias, contexto y raíces
C->>C: Revalidar huella, policies y conflictos
alt Plan válido
C->>DB: Cierres y revisiones, INSERT sucesoras
C->>DB: Procedencia, auditoría, comando committed
C->>DB: COMMIT
H-->>U: Resultado original persistido
else Rechazo previo a escrituras operativas
C->>DB: Comando rejected y auditoría
C->>DB: COMMIT solo metadatos
H-->>U: Conflicto original almacenado
else Error durante escritura
C->>DB: ROLLBACK unidad operativa
C->>DB: Intento fallido en otra transacción
H-->>U: Error seguro; consultar misma clave
end
Reserva no crea/cierra asociaciones y puede quedar pending tras caída. La promesa atómica abarca todos los efectos operativos, resultado y auditoría de éxito, no borrar la existencia de intentos. Preparar y validar todos los candidatos antes de escribir; fallo posterior aborta todo.
En Sequelize v6, devolver Result.fail normalmente resuelto en managed transaction no provoca rollback. Después de la primera escritura operativa hay que abortar controladamente en Infrastructure, esperar rollback y convertir al resultado apropiado fuera. Antes de efectos sí se puede persistir deliberadamente rechazo/auditoría. Es una condición que debe probarse; documentación v6.
| Fallo | Resultado |
|---|---|
| Antes de iniciar, sin permiso/DTO inválido | Sin datos privados ni efectos operativos; intento seguro según política. |
| Reserva/auditoría de solicitud no persiste | No iniciar adopción. |
| Validación final | Rechazo auditable, cero cierres/sucesoras; nuevo plan si stale. |
| Tras cerrar una raíz, al crear sucesora/revisión | Rollback de todas las raíces, claves, revisiones y procedencia. Reserva pending recuperable. |
| Auditoría de éxito o antes de commit | Rollback total; no éxito sin evidencia. |
| Conexión perdida durante commit | Estado incierto para cliente: recuperar por clave, no declarar rollback ni crear otra clave. |
| Después de commit / respuesta perdida | Éxito durable y resultado original al reintentar autorizado. |
| Presentación o invalidación de caché | No revierte éxito. Mostrar resultado conocido y actualizar queries afectadas. |
| También falla registrar intento tras rollback | Diagnóstico técnico seguro con requestId; no prometer persistencia con BD caída. |
No hay acción externa contra equipos/licencias en esta unidad, ni necesidad demostrada de transacción distribuida/outbox. Automatización remota futura sería otro contrato.
14. Idempotencia
D08.1-H/P. Separar planId (fotografía/intención), commandId UUID v7 cliente y operationId UUID v7 servidor (resultado). Idempotency-Key UUID v7 generado una vez por confirmación y reutilizado tras timeout; no por click/nombre. Scope UNIQUE(companyId,actorId,action,key). Consultar exige permiso vigente; conocer una clave no entrega resultados de otro sujeto.
Huella de solicitud: versión, acción, C, actor autenticado, commandId, planId/fingerprint revisada, originalOperationId al compensar y aceptación explícita. No requestId de transporte. Valores por item están en plan cubierto por hash.
- Reserva breve mediante INSERT estricto y auditoría; UNIQUE arbitra simultáneas. Existente→comparar huella/autorizar. No upsert que cambie payload ni lock retenido mientras usuario revisa.
- committed/rejected→resultado persistido antes de exigir vigencia del plan o gates de ejecuciones nuevas. Sí revalidar sesión/capacidad de consulta. Plan expirado/gate off no borra commit.
- pending→unidad §13. Compañía y comando serializan; segundo relee resultado bajo locks y no repite. Otro comando tampoco confirma dos veces un plan: UNIQUE(planId) y comprobación consumido.
- Rechazo determinista previo a efectos: persistir rejected/código/auditoría en esa unidad; repetición conserva rechazo. Corrección necesita nuevo plan/comando/clave.
- Error técnico con rollback: reserva sigue pending, sin resultado final. Intento aparte y reintento idéntico con validación completa. 500/503 transitorio no es resultado confirmado ni rechazo de negocio cacheado. Commit incierto exige leer fila, no marcar rejected.
stateDiagram-v2
[*] --> pending: reserva autorizada durable
pending --> committed: efectos y auditoría en commit único
pending --> rejected: rechazo previo a efectos
pending --> pending: rollback técnico o caída
committed --> committed: repetir devuelve resultado
rejected --> rejected: repetir devuelve rechazo
Estados del comando propuesto, no de Resource/Software/Profile. No durable «a medias». Espera excedida→503 ADOPTION_RETRY_REQUIRED, Retry-After acotado; no dos ejecutores. No se necesita lease/worker: reintento válido retoma pending bajo mutex.
Resultado original se reconstruye de operación/items/revisiones iniciales inmutables, nunca de valores actuales de sucesoras. Conserva UUID, hechos al commit y códigos; requestId del wrapper puede cambiar. Lectura de estado actual es distinta. No purgar claves/resultados inicialmente; retención final P07. Botón deshabilitado solo ayuda UX.
| Caso | Comportamiento |
|---|---|
| Misma clave/contenido finalizado | Mismo resultado de negocio, sin nuevas sucesoras/revisiones/eventos efectivos. |
| Misma clave con otro contenido | 409 ADOPTION_IDEMPOTENCY_CONFLICT, sin resultado ajeno. |
| Dos peticiones idénticas simultáneas | UNIQUE y serialización; relectura o retry misma clave si excede espera. |
| Dos claves, mismo plan | Una operación; otra ADOPTION_PLAN_ALREADY_CONFIRMED con referencia autorizada. |
| Dos planes sobre misma raíz | Primera confirma; segunda stale/cerrada o UNIQUE predecessorId, sin efectos parciales. |
| Timeout antes/después del commit, restart | Consultar pending/rechazo/resultado; recuperar misma operación, no nueva clave. |
15. Auditoría
D08.1-C/H y T. Usar el diseño común acordado, hoy pendiente. Procedencia explica old/new; auditoría explica actor, solicitud y efectos. No sustituir el mecanismo común por un journal paralelo.
Éxito: actor de sesión/nombre histórico seguro, C, acción, requestId/fechas, evento causal y cierres/altas/cambios tipados con UUID y revisiones. No registrar que cambió Resource: solo se referencia. Plan/reserva son escrituras de metadatos y también se auditan en sus commits; lectura R2.6 no se convierte en evento de adopción.
Reintento puede registrar intento técnico vinculado al original, sin duplicar efectos de negocio. Rechazo no aparenta éxito. Fallo post-rollback genera intento en transacción independiente. Ningún éxito sin auditoría persistida en su propia unidad.
Nunca cuerpo HTTP íntegro, cookies, CSRF, tokens, contraseñas, seriales secretos, credenciales ni notas administrativas globales. Referencias documentales aportadas deben ser seguras. Logs técnicos conservan causa saneada/requestId; no sustituyen auditoría durable.
Dependencia mínima bloqueante: escritor/lector común ligado a transacción que cubra estos caminos y falle conjuntamente con negocio. Cubrir adopción no declara completada toda la auditoría central. No habilitar confirmación con auditoría diferida a un TODO.
16. Compensación
D08.1-I/P, sujeta a P06. No rollback ni «deshacer» automático: otra operación autorizada con plan, clave, actor y procedencia puede cerrar sucesoras documentales y crear nuevas raíces particulares. La adopción original y su resultado permanecen confirmados/inmutables; el vínculo de compensación explica el hecho posterior.
Propuesta inicial: compensación completa una sola vez, sin parcial ni recursiva. Todas las sucesoras deben seguir abiertas pending/configured y con la misma última revisión que su primera revisión al commit. Una nueva revisión, incluso notas o un cambio luego revertido, bloquea esta compensación acotada. Cualquier dependencia nueva/incompatible bloquea el conjunto.
Revalidar: no compensación previa, particular original actualmente disponible, asset/profile/persona, licencia/versión/entrega propuestas y par particular libre. Las particulares anteriores no se reabren: crear otras con UUID nuevo. Valores nuevamente revisados, sin restaurar snapshot ciegamente; ambas historias se conservan completas.
Cerrar referencia global existente no exige global activo ni reabrir gates de asociación global. Crear la particular compensatoria sí exige policies locales y gate específico de compensación. Cerrar adopción no impide consultar resultados ni debe obligar a activar globales para recuperar contexto.
flowchart LR
A[Particular anterior cerrada] --> O[Adopción confirmada]
O --> G[Sucesora global]
G --> V{Sin evolución ni dependencias nuevas y contexto válido}
V -->|No| X[Compensación bloqueada: intervención nueva]
V -->|Sí| C[Compensación autorizada]
C --> H[Cierre documental de sucesora global]
C --> N[Nueva particular con UUID nuevo]
H --> J[Adopción e historias conservadas]
N --> J
Misma atomicidad/locks/auditoría/idempotencia; action=compensate, originalOperationId FK UNIQUE. Timeout/repetición recupera la misma compensación. Una sucesora incompatible impide modificar cualquiera. Nunca borrar sucesoras ni restaurar backup para hacer desaparecer la adopción.
Sin aprobar B1 y su cierre inverso documental tampoco hay compensación habilitada. Si hubo evolución, conservar estado y elaborar una intervención específica nueva; «manual» no es un bypass para sobrescribir trabajo posterior.
17. Seguridad
D08.1-J/P. D04 conserva soporte compartido, no tenant por cliente. Verificar pertenencia no crea ACL inexistente. A nunca usa fuente/licencia/asset/profile de B, tampoco admin. Si se exige limitar operador a compañías, es dependencia Identity antes de activar, no filtro frontend.
| Operación | Vigente V | Propuesta P/A |
|---|---|---|
| Coincidencias/producto público | Sesión vigente, proyección mínima; gate catálogo en detector. | Sin cambios; no autoriza adopción. |
| Uso propio C | APIs operativas actuales/contexto C. | Sin cambios ni uso transversal. |
| Crear/consultar plan | No capacidad específica. | resources.adoption.plan + C; admin inicial si P03 se aprueba. |
| Confirmar | No existe. | resources.adoption.confirm + C, aceptación y revalidación de propósito/gates. |
| Consultar comandos/operaciones | No existe. | resources.adoption.history + C; leer catálogo no concede evidencia sensible. |
| Compensar | No existe. | resources.adoption.compensate + history + C y gate propio. |
Son capacidades conceptuales, no grants. Recomendación inicial: política explícita Identity no delegable para admin inicial. Aunque coincida el sujeto con global.manage, no deducir permiso de adopción desde leer/gestionar catálogo. Hace falta contrato público de autorización por acción que exprese lo aprobado. Sin RBAC/ACL nuevos por omisión; si se requiere delegación o dos personas, diseñarlos antes.
Autorizar antes de datos protegidos, al inicio de cada confirmación/consulta/reintento. Actor de sesión active/authVersion, nunca body. Autorización al inicio no promete cancelación retroactiva si se revoca después, conforme R2.2; P03 debe ratificarlo.
UUID/C/scope/tipo/propósito se comprueban en servidor bajo unidad. Global stock application, campos globales válidos e integración ausente; usage/nombre de copia no bastan. Propósito derivado del item tipado, no string libre para elevar acceso. Enlaces reautorizan; planes sin notas administrativas globales.
401 sin sesión; 403 capacidad; 404 uniforme de contexto/referencia/plan/operación no accesible. 409 detallado solo sobre información autorizada. POST requiere origen/CSRF, incluso preflight que escribe metadatos. DTO/query estrictos; UUID/token/clave no son permiso.
18. HTTP/DTO
D08.1-K/P. Todas las rutas/DTO siguientes son propuestas, ninguna se introduce ahora. Superficie Companies /api/resource-adoptions/:companyId, separada del detector Resources. JSON solo transporte. Implementar posteriormente con Zod estricto e inferencia, sin interfaces duplicadas.
Contratos comunes
Params UUID, headers relevantes validados, origen/CSRF en POST. Idempotency-Key para confirmar/compensar. Query vacía salvo listados. Arrays únicos/acotados y nullable explícitos. No admitir actorId, owner/scope, capabilities, force, SQL ni destino diferente por item.
| DTO conceptual | Contenido |
|---|---|
| CreateAdoptionPlan | creationId v7, sourceResourceId, targetResourceId; softwareItems [{installationId, proposedState pending/configured, version, licenseResourceId, notes, versionDecision, licenseDecision}]; applicationItems [{configurationId, proposedState, delivery, version, notes, versionDecision}]; evidence [{kind,referenceText,explanation}]. Nullable explícitos; preserve/replace/clear coherentes con los valores y evidencia. |
| AdoptionPlanSummary | ID/C/kind, source/target mínimos observados, fechas/versiones/fingerprint, ready/blocked, cobertura, conteos exactos y bloqueos, efecto previsto y aceptación requerida. |
| AdoptionPlanItem | Unión software/profile con UUID/revisión/contexto autorizado, valores observados/propuestos, keep/succeed y conflictos; licencia solo software, cerradas keep. |
| ConfirmAdoption | commandId v7, planId, fingerprint y acceptReviewedPlan: true. Sin valores editables; modificarlos exige plan nuevo. |
| AdoptionResult | operationId, commandId, planId, C/kind, fecha y actor autorizado, source/target observados, conteos, enlaces a elementos/auditoría. Líneas: IDs/revisiones anteriores y sucesoras, causa y valores al commit, sin historia administrativa global. |
| CommandStatus | pending, committed con referencia a resultado, o rejected con código seguro. GET no ejecuta pendientes. |
| CreateCompensationPlan | creationId, originalOperationId, evidencia y valores explícitos para todas las nuevas particulares. |
| ConfirmCompensation | Mismo envelope de confirmación, action derivada de ruta/plan y permiso correspondiente. |
Límites propuestos: referenceText 500, explanation 2.000, evidencia 1..20; versión/notas conservan 100/4.000; selecciones/páginas §10. Pendientes de prueba/ratificación; no valores de negocio autocompletados.
Operaciones
| Método/ruta tras prefijo | Auth y entrada | Salida/HTTP | Idempotencia/concurrencia/paginación |
|---|---|---|---|
POST /plans |
plan + C + CSRF; CreateAdoptionPlan. | 201 nuevo o 200 mismo creationId; 400/401/403/404/409. Plan con conflictos puede ser 201 blocked, sin éxito operativo. | creationId ligado a actor/C/contenido, observación/guardado en unidad. |
GET /plans/:planId |
plan + C, query vacía. | 200 summary/fotografía; 401/403/404. | Inmutable; expiración derivada, no valores vivos. |
GET /plans/:planId/items y /conflicts |
plan + C; type si aplica, cursor/pageSize. | 200 page {items,nextCursor}; 400/401/403/404. | Cursor C/plan/tipo, orden UUID, 1..100. |
POST /confirm |
confirm + C + CSRF; ConfirmAdoption e Idempotency-Key. | 200 resultado tanto inicial como repetición; 400/401/403/404/409, 500 o 503 retry. Location al resultado. | Reserva durable y locks §§12–14; mismo resultado de negocio. |
GET /commands/:commandId |
history + C, query vacía. | 200 estado; 401/403/404. | Recuperación; private,no-store; no ejecutar. |
GET /operations |
history + C; cursor/pageSize, sourceId/targetId/kind opcionales validados. | 200 page; 400/401/403/404. | committedAt/id, cursor ligado a filtros/C. |
GET /operations/:operationId y /result |
history + C, query vacía. | 200 summary o resultado original; 401/403/404. | Hechos originales inmutables; estado compensatorio actual separado en consulta de operación. |
GET /operations/:operationId/items |
history + C; type/cursor/pageSize. | 200 líneas causales; 400/401/403/404. | Orden estable; sin todo el historial por defecto. |
POST /operations/:operationId/compensation-plans |
compensate/history + C + CSRF; CreateCompensationPlan. | 201/200 plan o 400/401/403/404/409. | creationId, observación de evolución, gate compensatorio de preflight. |
POST /compensate |
compensate/history + C + CSRF; ConfirmCompensation y clave. | 200 resultado; códigos base y conflictos §16. | action compensate, UNIQUE originalOperationId, atomicidad e idempotencia. |
Detalle/result pueden componerse en una sola respuesta si distingue hechos originales de estado actual; la separación funcional no obliga a viajes redundantes. No endpoint merge ni cambio de resourceId/scope.
Negociación y errores
Resources-Contract: 2 cubre globales, no estados nuevos. P05/B1: proponer X-Metis-Operational-Contract: 2 para sucesión y su representación en rutas afectadas de software/perfil/entorno/procesos, sin cambiar significado del header Resources. Desconocido→400; cliente sin soporte que recibiría B1→409 OPERATIONAL_CLIENT_UPGRADE_REQUIRED, Vary correspondiente, nunca lista parcial ni superseded traducido a removed.
Todos los lectores deben desplegarse antes del primer B1: backend antiguo tampoco rehidrata ese estado. Rutas nuevas exigen contrato propuesto. Otra representación de cierre exige revisar P05, no declarar aditiva una respuesta que rompe schemas estrictos.
Errores propuestos: §11 y ADOPTION_PLAN_ALREADY_CONFIRMED, ADOPTION_IDEMPOTENCY_CONFLICT, ADOPTION_RETRY_REQUIRED, ADOPTION_COMPENSATION_CHANGED, ADOPTION_ALREADY_COMPENSATED, ADOPTION_HISTORY_IN_USE. {code,requestId} y conflictos tipados solo autorizados; categorías HTTP explícitas, sin mapear FORBIDDEN a 409 por defecto. Rechazo almacenado sin SQL/stack/mensajes del motor.
19. Consumidores
D08.1-L/P. S sin cambios; E extensión aditiva; G requiere gate de escritura; X incompatible sin preparación; D depende de decisión.
| Consumidor | Impacto | Contrato necesario |
|---|---|---|
| ResourceDetail | S/E | Recursos intactos; posible enlace autorizado a operación, sin convertir UUID en misma entidad. |
| ApplicationCoincidencesDialog | S/E/G | Sigue informativo; «Preparar plan» solo permiso/gate; ninguna coincidencia confirma ni selecciona raíces. |
| SoftwareInstallation | G/X/D | B1, closed/currentKey, procedencia, historial y delete protegido; target anterior fijo. |
| ApplicationConfiguration | G/X/D | Igual, delivery/versión propios; no deriva instalaciones de equipo. |
| WorkProfile | E/X en proyección | Identidad/actividad/target intactos; sucesora abierta y cerrada histórica diferenciadas; borrado respeta referencias. |
| Workstation y activo | E/X en lectura | Mantener equipo/perfiles, no contar predecesora cerrada como abierta ni copiar configuraciones entre perfiles. |
| Entorno/procesos | D/X | Clasificación/contadores revisan B1; referencias a UUID antiguo no se mueven automáticamente. |
| Selectores | S | Particular/global siguen conforme a reglas de elegibilidad, sin ocultación, alias, selección ni prioridad por adopción. |
| Catálogo global | S | Sin versiones/licencias locales ni uso transversal; Resource no cambia. |
| Borrado de raíces/revisiones observadas | X/D | RESTRICT por planes persistidos puede bloquear delete aun sin adopción; P07 debe aprobarlo o cambiar el modelo antes de activar preflight. |
| Inventario y consumers solo locales | S | Remoto, Access, SMB, dominio, certificados, soporte, buzones/carpetas conservan UUID y allowlist; se enumeran intactos. |
| Historiales | E/X | Anterior enlaza operación/sucesora; nueva señala predecesora/operación, sin fusionar arrays de revisiones. |
| APIs Companies | E nuevas rutas; X B1 | Nuevos contratos; lector antiguo recibe upgrade seguro. CRUD ordinario no adquiere permiso de sucesión. |
| Auditoría | T/E | Consulta causal autorizada, sin elevar acceso a historia administrativa global. |
| TanStack Query | E | Claves por sujeto/C/plan/operación, invalidación dirigida tras commit, sin duplicar estado remoto. |
UI solo funcional: plan explicable, selección explícita, valores revisados, bloqueos visibles, confirmación y resultado enlazable. Diseño detallado se difiere; seguiría DESIGN, patrones de diálogo, i18n y organización por entidad/operación.
Tras commit: invalidar softwareKeys.company(C) si hay software, applicationKeys.company(C) si perfil, planes de fuente/C y operaciones de C/sujeto. Uso/entorno comparten queries operativas. Si hay derivadas independientes de puesto/dashboard/procesos, añadir sus claves precisas por contextos afectados al inspeccionarlas. Referencias/candidatos por propósito solo si su proyección depende de vínculos modificados; producto/actividad no cambian, por tanto no vaciar todo Resources ni catálogo global. Coincidencias R2.6 permanecen.
Fallo de invalidación se recupera con refetch dirigido; no revierte commit. Repetir resultado puede reintentar actualización local. Logout/401/403 elimina proyecciones sensibles del sujeto; caché no acredita permiso.
20. Flags y despliegue
Ningún flag se crea/cambia ahora; existentes default false. P08: gates nuevos independientes, también default false:
| Gate propuesto | Habilita | No habilita |
|---|---|---|
| RESOURCE_ADOPTION_PREFLIGHT_ENABLED | Crear planes de adopción autorizados. | Confirmar ni compensar. |
| RESOURCE_ADOPTION_CONFIRM_ENABLED | Nueva ejecución de plan válido y prerrequisitos completos. | Propósitos cerrados, permisos ni compensación. |
| RESOURCE_ADOPTION_COMPENSATION_PREFLIGHT_ENABLED | Preparar plan compensatorio autorizado. | Ejecutarlo ni abrir adopción directa. |
| RESOURCE_ADOPTION_COMPENSATE_ENABLED | Confirmar compensación revisada. | Forzar evolucionadas, borrar historia ni asociar nuevos globales. |
Lectura autorizada de resultados/operaciones previos y resolución usada no se apaga con escritura. Catálogo de lectura no concede adopción. Adopción nueva exige catálogo y gates por tipos seleccionados: software o perfiles. Gate de picker mixto no es permiso de escritura ni requisito técnico de destino elegido por UUID válido. Compensación particular aplica §16, sin reabrir asociación global.
Despliegue futuro, no ejecución:
- Aprobar semántica/alcance/versionado y permisos. Inventariar lectores/escritores/dependencias. Resolver o aceptar expresamente deuda/gates previos de R2.4–R2.6 sin declararlos cerrados por este documento.
- Diseñar/ensayar migraciones explícitas en MariaDB 11.8 desechable con CHECK/FK activos. DDL separado del DML; no rollback ficticio de ALTER TABLE ni foreign_key_checks=0. Ensayo de recuperación separado de compensación.
- Desplegar auditoría/autorización y lectores compatibles en todos los backends/clientes, con gates cerrados. No escribir B1 con instancias antiguas activas.
- Ejecutar matriz §21 y volumen. Activar solo preflight limitado, revisar cobertura/coste/permisos; lectura correcta no activa confirmación.
- Piloto de confirmación autorizado por compañía/selección acotada. Monitorizar latencia, consultas, contención, deadlocks, UNIQUE/auditoría, rechazos/stale, pending antiguos y recuperación por clave; sin secretos en logs.
- Compensación exige aprobación/prueba propia; no activarla junto al piloto.
- Gates off detienen comandos nuevos, no borran resultados. Validación al inicio no promete cancelar una transacción en curso: drenar escrituras si se exige parada inmediata y coordinar instancias/env; no cambio instantáneo supuesto.
Rollback de despliegue: antes de B1, volver solo a versión compatible con expansión. Desde la primera revisión nueva, lectores B1 son versión mínima obligatoria; backend previo no es downgrade seguro. Cerrar escrituras y corregir hacia delante o usar versión preparada que siga leyendo B1. Compensar tampoco elimina ese requisito histórico. Restaurar backup no es «deshacer adopción».
21. Matriz de pruebas R2.7
Diseño futuro, no ejecutado. U unidad/DTO/canonicalización; M MariaDB real; H HTTP real con sesión/CSRF; P Playwright MCP. Base desechable metis_desk_test; ≥15 compañías y principal con ≥50 personas/activos/recursos/perfiles/puestos; volumen ampliado para límites/históricos. Unitarias pequeñas. Barreras observables como las existentes, sin sleeps arbitrarios.
| ID | Escenario | Expectativa | Capas |
|---|---|---|---|
| T01 | UUID diferentes, homónimos | Recursos intactos; sucesora UUID nueva, target anterior conservado. | U,M,H,P |
| T02 | Proveedor ausente/name-only | Sin evidencia adicional no confirmar; no asumir fabricante. | U,H,P |
| T03 | Misma marca, edición diferente | Bloqueo comercial explícito, no merge heurístico. | U,H,P |
| T04 | Destino inactivo/OS/copia application inválida | Sin nueva asociación; proyección segura. | U,M,H |
| T05 | Fuente/licencia/asset/profile B bajo A, también admin | 404/error seguro, cero efectos. | U,M,H |
| T06 | Sin asociaciones/selección vacía | Plan no-effect, no operación equivalente A3. | U,H,P |
| T07 | Solo Software, solo Profile y ambas | Exactamente seleccionadas, un commit; resto intacto. | U,M,H,P |
| T08 | pending/configured/removal_pending/terminales | B1 aprobado solo donde corresponda; cerradas keep y retirada bloqueada. | U,M,H,P |
| T09 | Destino abierto/cerrado histórico | Abierto bloquea; cerrado no colisiona; sin upsert sobre otra raíz. | U,M,H |
| T10 | Carrera par asset/global y profile/global | Un resultado válido; otro stale/conflict y sin efectos parciales. | M,H |
| T11 | Licencia ajena/inactiva/caducada/cobertura no acreditada/null revisado | Policies y evidencia correctas, medianoche UTC revalidada. | U,M,H |
| T12 | Versión incompatible/web con versión | Bloqueo/schema; no inferencia del nombre. | U,H,P |
| T13 | Cambio/reversión de valores, revisión/dependencia nueva tras plan | stale, sin sobrescribir; revisión detectada aunque valores iguales. | U,M,H,P |
| T14 | Orden, null/ausente/vacío, UUID/Unicode/posiciones | Huella determinista y diferencias significativas; no permiso por hash. | U |
| T15 | Simultáneas misma clave, distintas claves mismo plan, planes misma raíz | Un efecto, resultado/conflicto explícito, auditoría sin duplicados efectivos. | M,H |
| T16 | Misma clave/body diferente/actor distinto | Conflicto/denegación sin datos ajenos; reserva inmutable. | U,M,H |
| T17 | Timeout antes/después de commit y restart | Pending recuperable o resultado original; no nueva clave/sucesoras. | M,H,P |
| T18 | Fallo antes de cierre, después de cierre, durante alta/revisión | Rollback integral; hashes de raíces/claves/revisiones como antes. | M,H |
| T19 | Fallo procedencia/auditoría/antes de commit | Sin efectos ni evento de éxito huérfano. | M,H |
| T20 | Result.fail tras escritura administrada | Adaptador aborta realmente; detectar commit accidental. | M |
| T21 | Error de respuesta/cache después de commit | Resultado durable; ningún rollback fingido ni reejecución distinta. | M,H,P |
| T22 | Desactivación en ambos órdenes de locks | Rechazo si desactivar primero; si adopción primero, preservar sucesoras y revisión derivada. | M,H |
| T23 | Compensación sin evolución | Nuevas particulares UUID nuevas, historia preservada, un vínculo inverso. | U,M,H,P |
| T24 | Sucesora modificada/nueva dependencia, incluso valor restaurado | Bloqueo completo, sin sobrescribir. | U,M,H,P |
| T25 | Compensación repetida/parcialmente incompatible | Resultado original; una incompatible implica cero cambios. | M,H,P |
| T26 | Compensar con global/gates off y particular activo/inactivo | No reabrir globals para cerrar existente; policies locales obligatorias. | U,M,H |
| T27 | Sin sesión/permiso, origen/CSRF inválidos | 401/403 y cero datos privados/efectos. | H,P |
| T28 | Cada flag off, resultado previo, proyección sin secretos | Nueva ejecución bloqueada; resultado autorizado legible. | U,M,H,P |
| T29 | Cliente/backend anterior y ConfigurationSchema compartido | Upgrade seguro, sin B1 en Access ni lectores viejos atendiendo B1. | U,M,H,P |
| T30 | Delete de raíz/revisión/Resource con procedencia | Error de negocio y RESTRICT, sin borrar revisiones parcialmente. | M,H,P |
| T31 | Plan explicable, conflictos, selección, confirmación, recuperación | Sin automático; foco/teclado y resultado auditable. | H,P |
| T32 | 0/1/límite/exceso, paginación, error y contenido extenso | No truncar a ready; límites/cobertura reales y responsive. | U,M,H,P |
| T33 | Regresiones R2.2–R2.6, Identity, Assets, perfiles/puestos, licencias/SMB/Access/remoto/historia | Defaults off, UUID/referencias preservados, consumidores locales sin globales nuevos. | U,M,H,P |
| T34 | Caída pending, rechazo repetido, resultado tras evolucionar sucesoras | Recuperación sin lease ficticio; rechazo/resultado estables; GET no ejecuta. | M,H |
| T35 | Varias instancias, deadlock/timeout/carga/lotes | Reintento unitario acotado y coste/latencia medidos sin SLA inventado. | M,H |
MCP futuro: carga/error/vacío, selección revisable, motivos, Tab/Shift+Tab/Escape, foco inicial/retorno; anchos 1600/1440/1280/1024/768/390, capturas inspeccionadas y datos extensos según procedimiento. No se preparan fixtures ni navegador en D08.1.
22. Riesgos residuales
| Tipo | Riesgo y tratamiento |
|---|---|
| R | Evidencia humana incorrecta: estructura/trazabilidad no demuestra identidad comercial. Mantener A0 si no se resuelve. |
| A/T | B1 rompe estado cerrado de lectores actuales; requiere aprobación y despliegue, no basta VARCHAR. |
| T/R | APIs actuales cargan colecciones/historial; preflight necesita proyección acotada y persistida e índices/mediciones propios. Tiempos R2.6 no estiman confirmación. |
| T/R | Mutex exige todos los escritores cooperantes. Inventario y pruebas; SQL externo/futuro sin lock queda fuera. |
| T | Upsert, transacciones privadas y Result.fail post-escritura necesitan adaptación probada, no se cambian aquí. |
| A | Parcialidad, permisos/doble aprobación, retención y compensación requieren propietario de producto. |
| T | Auditoría central no implementada; no confirmar sin capacidad común necesaria. |
| R | Lotes largos retienen locks y serializan C; medir límites, no dividir commit de un plan. |
| R | Primera revisión B1 impide downgrade a backend anterior aunque se compense después. |
| R | BD caída impide prometer intento durable; nunca éxito sin auditoría atómica. |
| F | Deduplicación automática, alias global, cambios de UUID/owner, licencias automáticas, ejecución remota, purgas y nueva ACL. |
23. Decisiones pendientes
| ID | Clase | Propuesta y cuestión a resolver | Aprobación/dependencia |
|---|---|---|---|
| P01 — B1 | A | Cierre documental superseded específico o alternativa que no falsee retirada; pending/configured permitidos, removal_pending bloqueado. | Producto/arquitectura; sin resolver no confirmar A2 configurada. |
| P02 — A | A | Selección parcial hasta 100, un commit por plan y resto explícitamente intacto, frente a exigir todas las asociaciones. | Producto; si exige todas, revisar cobertura/conflictos/límites. |
| P03 — J | A/T | Permisos por acción: admin inicial no delegable recomendado, sin dos personas obligatorias. Decidir delegación, separación de funciones o ACL. | Producto/seguridad e Identity; no permiso implícito desde global.manage. |
| P04 — D/F | A/T | Vigencia 30 min, 100 seleccionadas/10.000 observadas y evidencia acotada; ratificar tras medir. | Producto/operación, sin rendimiento prometido. |
| P05 — K/L | A/T | Negociación Operational-Contract: 2 y schemas específicos/lectores B1. | Arquitectura/consumidores; ampliación D09 explícita. |
| P06 — I | A | Compensación completa única, sin evolución, sin parcial/recursiva; se puede diferir sin anunciar reversibilidad. | Producto/seguridad. Intervención posterior no significa bypass. |
| P07 — C/H | A | Retención/consulta/privacidad; sin purga inicial y protección RESTRICT también de observaciones no seleccionadas/planes abandonados, o rediseño explícito previo. Resolver anonimización por responsable competente si corresponde. | Producto/privacidad; claves confirmadas no reutilizables. |
| P08 — despliegue | A/T | Gates separados, piloto y versión mínima; resolver/aceptar deuda previa antes de activar. | Producto/operación. Aprobación técnica no abre flags. |
| T01 | T | Escritor/lector común de auditoría, cobertura atómica de metadatos/efectos. | Implementación futura y prueba de fallos. |
| T02 | T | Puerto Companies de unidad de adopción, current reads y escritores ligados/INSERT estricto. | Conforme capas, sin modificar repositorios en D08.1. |
| T03 | T | Modelo físico/FK compuestas, eliminación protegida, UNIQUE e idempotencia. | Ensayos MariaDB 11.8 con restricciones activas. |
| T04 | T | Inventario de dependencias/escritores y actualización de procesos/entorno/counters. | Responsables consumidores; FK no basta. |
| T05 | T | Autorización pública Identity por acción y negociación de clientes. | Antes de confirmar, no solo frontend. |
Locks/idempotencia están definidos como propuesta y contrastados con prefijo actual, pero garantías nuevas requieren T02/T03 y carreras. No se dan por ratificadas parcialidad, permisos, retención, estados o compensación. Una aprobación que excluya P01/P05 debe delimitar expresamente el alcance restante.
24. Recomendación
Mantener A0 y recomendar A2: selección explícita, cierre documental aprobado, nuevas raíces y procedencia relacional, sin A1 ni equivalencia automática. A3 puede evaluarse independientemente, sin obligación nueva para R2.6.
Propuesta de alcance futuro, sin autorizarlo:
- R2.7a: autorización/auditoría, ensayo de expansión, lectores compatibles y preflight completo e inmutable. Sin confirmar asociaciones. Puede revisarse antes de aprobar toda compensación.
- R2.7b: tras P01–P05/P08 y T01–T05, confirmación síncrona de una C/fuente/destino, selección acotada, ambas familias en una unidad, consulta/historial/idempotencia y pruebas de fallos/carreras. Sin automatismos ni lotes entre compañías.
- Compensación posterior: P06 y pruebas propias, gate independiente. Hasta entonces no ofrecer «deshacer» ni prometer reversibilidad.
Es planificación documental: no abre ramas/tareas ejecutables, migraciones ni R2.7. Aprobar arquitectura no autoriza esas fases.
25. Condiciones de aprobación
Matriz de consistencia
| Propuesta | Contrato actual | Compatibilidad | Cambio requerido | Decisión |
|---|---|---|---|---|
| Conservar Resources/UUID | D01/D07, Resource scoped | Compatible. | Ningún owner/scope/plantilla cambia. | I01/P. |
| Sucesoras UUID nuevas | D08/sameTarget/revisiones | Compatible como comando nuevo no existente. | Procedencia/comando, sin UPDATE target. | A2/P. |
| superseded documental | Cinco estados/closed actuales | Incompatible sin ampliación de lectores/schemas; no falsea retirada. | Aprobar B1 y evolución explícita de contrato operativo/D09; schemas específicos/counters. | P01/P05. |
| Piloto pending→never_configured | Transición existente | Solo cancelación real; no configuradas. | Aprobar alcance alternativo separado. | No autorizado. |
| Atomicidad conjunta | Repositorios con transacción propia | Garantía nueva no disponible. | Puerto unitario y rollback real. | T02. |
| Destino por propósito | D02/D04-R/D06/sesión Resources | Compatible. | Puerto vigente en misma unidad. | P/T. |
| Permiso de adopción | D03/D04, admin global no implica adopción | Extensión explícita. | Aprobar sujetos/contrato Identity. | P03/T05. |
| Procedencia relacional | D08/normalización | Compatible, tablas nuevas no existentes. | Modelo físico/migración futura/ensayo. | T03. |
| Auditoría en commit | Diseño acordado aún pendiente | Requisito compatible y bloqueante. | Mecanismo común y cobertura. | T01. |
| Idempotencia de comando | No-op update/creationId global | Aquellas capacidades no bastan. | Reserva/resultados/UNIQUE/retención. | H/P07/T03. |
| Selección de C | D04/consumers locales | Compatible si producto aprueba parcialidad. | Cobertura/exclusiones explícitas. | P02. |
| Compensación | D08: nueva sucesión sin borrar historia | Compatible condicionada; no existe. | Plan inverso/evolución/gate/auditoría. | P06. |
| Particular en picker | D07/R2.6 | Compatible. | No ocultar ni sustituir. | Sin cambio. |
| B1 en entorno/procesos | R2.4/R2.5/DTO estrictos | Incompatible sin preparación. | Lectores/contadores/negociación. | T04/P05. |
| Gates y despliegue | D10/default false | Compatible con gates separados; no downgrade histórico. | Preflight/versión mínima, no activar ahora. | P08. |
No se cambia D01–D10 ni se ratifica D08 en este archivo. Ampliar estados/negociación es decisión adicional pendiente. Si la solución elegida contradice un contrato ratificado, debe aprobarse/documentarse su evolución explícita antes de implementarla, conservando documentos históricos.
Dictamen
APTA CON CONDICIONES: arquitectura viable y revisable con decisiones funcionales/dependencias delimitadas. Para ratificar el contrato de confirmación: resolver P01–P05/P08, aceptar procedencia/idempotencia/locks y asignar T01–T05. Para compensación, P06; para purga, P07 y contrato adicional. Aprobar rumbo con condiciones no permite omitirlas al programar.
P07 debe resolver además el régimen inicial de retención y su impacto en delete antes de habilitar preflight persistido; una futura purga sigue necesitando contrato adicional.
Antes de implementar: aprobación escrita de semántica/alcance, HTTP/seguridad/versionado y plan relacional. Antes de activar: constraints/migraciones ensayadas, lectores/escritores compatibles, autorización/auditoría implementadas, matriz §21 ejecutada con resultados/limitaciones, flags default off y tratamiento explícito de deuda/gates previos. G6 histórico R2.4 y aceptación global pendiente R2.5/R2.6 no se cierran aquí.
Verificación de esta entrega
Entorno WSL, Node 24.20.0, PNPM 11.25.0, estado Git y snapshot de archivos sin secretos comprobados. Inspección de dominio, Zod, persistencia, guards, locks, composición, keys y consumidores; pruebas existentes R2.4, R2.5, R2.6 y barreras consultadas como evidencia, sin ejecutarlas de nuevo. Fuentes externas primarias citadas de MariaDB/Sequelize v6, sin atribuirle APIs v7.
Cierre documental realizado: 25 apartados y enlaces locales comprobados sin destinos ausentes; cinco bloques Mermaid revisados estáticamente, sin afirmar renderizado con un motor Mermaid; fences equilibrados, ausencia de espacios finales/conflictos y comparación de hashes de los 3.168 archivos previos, sin modificaciones. Solo se añade este documento. No ejecutar typecheck/lint/test/check/build ni nuevas pruebas SQL/HTTP/MCP: no cambia código y la petición prohíbe pruebas/fixtures de una adopción inexistente. 105/105, 6/6, 50/50 y 22 comprobaciones MCP/12 capturas son resultados históricos R2.6, no nuevos de D08.1.