From 01795a2d7abe737b86c6abe540c4598ff5878501 Mon Sep 17 00:00:00 2001 From: "Harol A. Reina H." Date: Sat, 3 Oct 2026 18:33:27 -0500 Subject: [PATCH 1/2] docs(roadmap): baseline Platform v2.25.0 (security release) --- docs/roadmap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/roadmap.md b/docs/roadmap.md index c1d82e3f..b06d6a02 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,6 +1,6 @@ # Roadmap — Verbara.Platform + Verbara.Platform.Web -**Última actualización:** 2026-10-03 · **Baselines actuales (released, tagged + GH Release + cosign):** Platform **`v2.24.0`** · Platform.Web **`v3.19.0-web`** · SDK **`2.4.0`** (nuget.org; **`2.5.0` ya publicado — el cascade `2.4.0` → `2.5.0` queda deferred como verbara-meta/R-021**) · Pro **`2.14.1-pro`** (GitHub Packages). **✅ 2026-10-03 `/xr:release`: Platform `v2.24.0` — release de seguridad ([GHSA-fxfp-76v2-xjg2](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-fxfp-76v2-xjg2), [GHSA-757c-652x-p67g](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-757c-652x-p67g); #323, #324).** **✅ 2026-08-26 `/xr:release` train: Platform `v2.23.0` + Web `v3.19.0-web` SHIPPED** — el tren de seguridad + corrección de imagen. Platform cifra el material de enrolamiento MFA **at rest** con DataProtection (cierra verbara-meta/**R-014**): migrador de arranque one-shot idempotente para las filas preexistentes, **sin cambio de esquema ni de API** (`mfa_secret` sigue `TEXT`) — y la durabilidad del keyring pasa a ser **load-bearing**, leer el bloque de impacto operativo antes de desplegar o hacer rollback. Además cae una tanda de **500s que estaban vivos en toda imagen shipeada**: `GET /admin/flows`, `DELETE /admin/skills/{name}` (borraba y _después_ fallaba), `GET /admin/audit` (todos los tenants, todas las llamadas); más el refresh de token que borraba cada permiso a mitad de sesión, los recovery codes de MFA que nunca podían canjearse, y el seeding RBAC abortando en boot dejando 5 de 11 role templates. **El host ya no depende de correr en UTC** (ADR-0002): una sola línea `RuntimeHostConfigurationOption` atascaba `QueueDistributionWorker` y dejaba `POST /api/setup` a medias en cualquier host no-UTC. Verificación MFA fallida ahora se audita y cuenta para el lockout; `SSH.NET` → `2026.0.0` (GHSA-q939-rpr3-3284); 22 bumps de terceros, cuatro majors que llegan a la imagen. **Web** saca las credenciales bearer del browser (Web/ADR-0011, openspec `stop-persisting-auth-secrets`, #247 — cierra verbara-meta/**R-015**): `auth-store` persistía su estado _entero_ sin `partialize`, así que el access token, el `mfaPending.mfaToken` **pre-autenticación** (una credencial que salta el primer factor) y, al impersonar, el `impersonation.originalToken` **del propio operador** quedaban en claro en `sessionStorage`, legibles por cualquier script del origin; la porción persistida es ahora exactamente los hechos de sesión no secretos. Más: todos los guards de security-admin sobre ids canónicos `domain:resource:action`, texto muted a WCAG AA con nombres accesibles en los controles icon-only, embed de webchat emitido en la raíz del outDir, floor de cobertura 38 → 41, 45 merges npm (seis del grupo `npm-security`). 4 imágenes cosign-signed (run `32946067672`); api `sha256:3834a956…` / realtime `sha256:6e976391…` en authorized-digests (verbara-website #97). Web multi-arch `sha256:903ff0e7…` (run `32946189306`). _**El cascade de pins `2.3.2` → `2.4.0` YA OCURRIÓ** (2026-07-28, PR #210, en `main` y **sin cortar versión**): `Directory.Packages.props` queda en `Verbara.Sdk.* 2.4.0` (7 paquetes) + `Verbara.Sdk.Pro.* 2.13.1-pro` (22) + `Microsoft.Extensions.* 10.0.10` (7), las tres familias **en un solo commit** — SDK `2.4.0` sube el floor transitivo de esa última familia y Platform la pinea **directo**, así que mover solo la mitad `Verbara.Sdk.*` da NU1605 fatal bajo `TreatWarningsAsErrors` (`NU1605` no está en ningún `NoWarn`). SDK `2.4.0` es un dependency-bump train **sin cambio de API** (`NATS.Client.Core` 2.8.2 → 3.0.0 major + OpenTelemetry → 1.17.0 + `Microsoft.Extensions.*` 10.0.9 → 10.0.10), así que **nada bajo `src/`/`tests/` cambió**: se movió el baseline, no se adoptó una feature — y la exposición de Platform a NATS es **cero** (el transporte realtime es SignalR + StackExchange.Redis). `Microsoft.Extensions.TimeProvider.Testing` se queda deliberadamente en `10.0.0` (test-only, otra servicing track). Rodó como su propio tren de dependencias (**verbara-meta/R-013**, `Verbara.Sdk/ADR-0040` D3), **nunca plegado a un release train**; deja como spec viva la capability `sdk-pin-cascade`, y el siguiente tag que se corte de `main` es el que publica estos pins._ **✅ 2026-07-27 `/xr:release` train: Platform `v2.22.0` + Web `v3.18.0-web` "agent-presence admin surfaces" SHIPPED** — cierra en la UI el Grupo A W3/W4 de **Verbara.Platform.Web/ADR-0009**: Platform surfacea `pendingPauseTimeoutMinutes` en `GET`/`PUT /api/v1/admin/auth/config` (#198 — el **driver MINOR**; puro surfacing de un campo ya persistido de `TenantAuthConfig`, sin endpoint/store/migración/`ApiJsonContext` nuevos), y Web añade el botón force-offline (endpoint vivo desde Platform `2.9.0`) + el editor del campo, que **exige Platform ≥ 2.22.0** (contra `2.21.2` el campo no viene en la respuesta y se descarta en el write). 4 imágenes cosign-signed (`release.yml` run `30324647348`); api `sha256:6f40317e…` / realtime `sha256:9c390d9c…` en authorized-digests (verbara-website #79) — **primer release donde ambos digests se emiten automáticamente**: el recordatorio de `release.yml` ya no está gateado en `matrix.name == 'api'` (#203). También en el tag: el **fast-path de CI docs/data-only** (gate job + clasificador fail-closed, verbara-meta ADR-0016; #200/#202), §6-validado en las dos fases (`pull_request` #201 + `merge_group` #202). **✅ 2026-07-26 Platform `v2.21.2`** — `/health/ready` devuelve **200 (no 503)** en un boot community/self-host sin licencia, con **cero cambio de source en Platform**: la severidad vive entera en Pro (`dialer-engine` settlea `Degraded`), y el agregado voltea sólo por el pin bump `2.12.0-pro` → `2.13.0-pro` (#194, Verbara.Sdk.Pro/ADR-0017). **✅ 2026-07-25 Platform `v2.21.1` + Web `v3.17.0-web`** (ADR-0036 document-truth transformers: se extingue la unión numérica `["integer","string"]` que .NET 10 reflejaba + `ComplianceRuleSummaryDto.severity` pasa a enum cerrado — **document-only, sin cambio de runtime**; Web migra `react-router-dom@7` → `react-router@8.3.0` por el advisory CSRF de RSC-mode) · **✅ 2026-07-24 Platform `v2.21.0` + Web `v3.16.0-web`** (management API keys minteadas con CSPRNG en vez de `Guid.NewGuid()` + invariant gate #7 + la ola de gates **verbara-meta/ADR-0012** Ola-2/Ola-3 y **verbara-meta/ADR-0013**) · **✅ 2026-07-20 Platform `v2.20.0` + Web `v3.15.0-web`** (dialer license enforcement en el punto de gasto + named OpenAPI response schemas 183 → 391, ADR-0035). _Header baselines corregidos 2026-07-28 (habían drifted desde `v2.19.0`) y los 5 releases `v2.20.0`→`v2.22.0` **backfilled en la tabla Shipped el mismo día** — cuarta repetición de la misma clase; ver las notas de 2026-07-12, 2026-07-01 y 2026-06-18._ **✅ 2026-07-14 `/xr:release` train: Platform `v2.19.0` + Web `v3.14.0-web` + SDK `v2.3.1` "CSAT voice + aggregate KPI" SHIPPED** — closes the CSAT train (`csat-completion`, ADR-0020; Pro `2.10.0-pro` published in-train 2026-07-13): voice trigger + survey-IVR handoff + anonymous HMAC-verified `POST /api/v1/csat/responses/voice` + scope-wide `GET /api/v1/analytics/csat` aggregate (resolves the wallboard ⟨NEEDS PRODUCT-OWNER INPUT⟩ in favor of aggregation) + live `preview-voice` + typed `OnCsatResponseRecorded` relay + Web scope-wide KPI card; api digest `1020f117…` / realtime `0881ff26…` in authorized-digests (website #63); SDK `2.3.1` = LMNT mid-send abort fix (#84), pins cascaded Platform + Pro. **✅ 2026-07-12 Web `v3.13.1-web` (hotfix)** — supervisor CSAT KPI card aligned to the real `CsatResponseDto` analytics contract (`averageRating`/`totalResponses`); image `sha256:af8b86b0…` cosign-verified end-to-end; first release cut via the `/xr:release` §H tag-push handoff. **✅ 2026-07-11/12 Platform `v2.18.0` + Web `v3.13.0-web` "CSAT consumer (digital-first)" SHIPPED** — the CSAT Runner train (Pro `2.9.0-pro`; ADR-0020); voice/TTS deferred to a Pro Path-A follow-up; api digest `dcf565b5…` / realtime `75691a53…` in authorized-digests. _GH Release objects for `v2.18.0` + SDK `v2.3.0` backfilled 2026-07-12 — en su momento ni `release.yml` (Platform) ni `publish.yml` (Sdk) creaban uno; gap encontrado por un fact-check de `/xr:pending`, parcheado en el procedimiento verbara-meta `/xr:release` §H.5 (#15) y **cerrado de raíz el 2026-07-28**: los cuatro workflows del ecosistema crean ahora el release object ellos mismos (Platform #207/#208, Web #246, Sdk #138; Sdk.Pro ya lo hacía)._ **✅ 2026-07-06 Platform `v2.17.0`** — Typification **E5 autonomous disposition (dark/OFF, ADR-0034)** + audit-trail integrity + report-only live-DB CI lane + released-image smoke + first `SECURITY.md`; cascades SDK `2.3.0` + Pro `2.8.1-pro`. _Header baselines corregidos 2026-07-12 (habían drifted desde v2.16.0; misma clase que los backfills 2026-07-01 y 2026-06-18 de abajo)._ **✅ 2026-06-28 AI-credit ledger `v2.16.0`** (signed append-only ledger + O(1) balance projection; inert behind 2 default-off kill-switches; ADR-0033) · **✅ 2026-06-24 Typification P2c.2 `v2.15.0` + Web `v3.11.0-web`** (platform-managed metered LLM / AI Credits) · **✅ 2026-06-23 `v2.14.1`** (impersonation + rate-limiter fail-closed fixes) — the three above were **backfilled into the Shipped table 2026-07-01** (had drifted since v2.14.0). _(El 🟢 E5 "dark + unreleased" del 2026-07-01 quedó released — dark/OFF — en `v2.17.0`, ver arriba.)_ **✅ 2026-06-22 Typification P2c.1 (per-tenant BYO LLM config, BYO-only) SHIPPED end-to-end** — Platform **`v2.14.0`** + Platform.Web **`v3.10.0-web`** (PR #74+#117 via merge queue; 4 AOT/IL + Web cosign images; GH Releases; api digest `6cc1a9ef…` registered in authorized-digests #34, Worker auto-deployed). Multi-provider pluggable (OpenAI-compat/Azure/Anthropic), encrypted creds, fail-closed, AI strictly opt-in. **BREAKING (multi-tenant):** the shared global LLM key is retired (single-tenant/dev auto-seeded). Also folds the **#72 auth-drain fix**. _Platform-managed LLM as a metered/gated/billed service = **P2c.2** (next)._ **✅ 2026-06-21 Typification P2b SHIPPED end-to-end** — Platform **`v2.13.0`** (API: PR #70+#71, 4 imágenes AOT/IL cosign-signed, GH Release, api digest en authorized-digests) + Platform.Web **`v3.9.0-web`** (UI: PR #112+#116). `release.yml` runs verdes (Platform 27905988770 / Web 27906388147). _Tren Session/Auth (2.9.x) + Typification (P0–P2b, 2.10.0→2.13.0) añadido a la tabla Shipped el 2026-06-18 (estaba drifted desde 2026-06-01)._ **✅ 2026-06-01 v2.7.0 (Inbound Conversation Delivery) + v2.8.0 (Telephony admin: trunk+DID) + v2.8.1 (realtime reference-smb hotfix) SHIPPED** — releases un-deferred; see Shipped table + [[project-telephony-admin-v281]]. _Histórico previo:_ Platform **`2.5.4 + ADR-0026 Phase A + Phase B en main`** (post-Phase A.5 + ADR-0025 K8s health contract fix + JWT Tier-1 hardening + observability + Phase A wizard fix + Phase B membership executive gate) · Platform.Web **`3.1.3-web` + Phase A editor en main** · SDK pin **`2.2.1`** · Pro pin **`2.6.0-pro`** (bumped 2026-05-29 para Phase B `IRealtimeSyncService.AddQueueMemberAsync(allowedChannels)` signature change) · **🎉 visibility flip EXECUTED 2026-05-10 — Platform + Web repos PUBLIC** · **✅ 2026-05-22 ADR-0022 Phase D CLOSED** (Native AOT shipping) · **✅ 2026-05-24 Phase A.5 CLOSED** (Plan B Test 5 PARTIAL→PASS) · **✅ 2026-05-25 ADR-0025 K8s health contract + Phase B-LK + Phase C-LK closed on v2.5.2** · **✅ 2026-05-25 JWT Tier-1 hardening + lab causality on v2.5.4** (TTL bump = primary driver; stale-cache fallback = insurance, never fired in lab) · **✅ 2026-05-26 R5.5 Phase D-LK 24h soak PASS + R5.5 train SHIPPED with Production Readiness Review** · **✅ 2026-05-28 ADR-0026 Phase A + ADR-0027 tenant-type gate SHIPPED** · **✅ 2026-05-29 ADR-0026 Phase B SHIPPED** (digital-routing executive gate; SMB Docker product polish = ZERO routing tech debt; release packaging deferred to first paying customer). +**Última actualización:** 2026-10-03 · **Baselines actuales (released, tagged + GH Release + cosign):** Platform **`v2.25.0`** · Platform.Web **`v3.19.0-web`** · SDK **`2.4.0`** (nuget.org; **`2.5.0` ya publicado — el cascade `2.4.0` → `2.5.0` queda deferred como verbara-meta/R-021**) · Pro **`2.14.1-pro`** (GitHub Packages). **✅ 2026-10-03 `/xr:release`: Platform `v2.25.0` — release de seguridad, nueve advisories (alta: [GHSA-4qm8-6258-jpr6](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-4qm8-6258-jpr6), [GHSA-879r-434c-qx3v](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-879r-434c-qx3v), [GHSA-6mgx-v32x-vhm4](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-6mgx-v32x-vhm4), [GHSA-cwf2-m5mc-jch2](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-cwf2-m5mc-jch2), [GHSA-55hw-wcx5-33hj](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-55hw-wcx5-33hj); moderada: [GHSA-9j4m-4xj8-wmmg](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-9j4m-4xj8-wmmg), [GHSA-63cv-jpx9-qp2q](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-63cv-jpx9-qp2q), [GHSA-23rw-vxw4-fv7j](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-23rw-vxw4-fv7j), [GHSA-jcx3-prpv-h984](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-jcx3-prpv-h984); #326, #327; cierra #283).** **✅ 2026-10-03 `/xr:release`: Platform `v2.24.0` — release de seguridad ([GHSA-fxfp-76v2-xjg2](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-fxfp-76v2-xjg2), [GHSA-757c-652x-p67g](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-757c-652x-p67g); #323, #324).** **✅ 2026-08-26 `/xr:release` train: Platform `v2.23.0` + Web `v3.19.0-web` SHIPPED** — el tren de seguridad + corrección de imagen. Platform cifra el material de enrolamiento MFA **at rest** con DataProtection (cierra verbara-meta/**R-014**): migrador de arranque one-shot idempotente para las filas preexistentes, **sin cambio de esquema ni de API** (`mfa_secret` sigue `TEXT`) — y la durabilidad del keyring pasa a ser **load-bearing**, leer el bloque de impacto operativo antes de desplegar o hacer rollback. Además cae una tanda de **500s que estaban vivos en toda imagen shipeada**: `GET /admin/flows`, `DELETE /admin/skills/{name}` (borraba y _después_ fallaba), `GET /admin/audit` (todos los tenants, todas las llamadas); más el refresh de token que borraba cada permiso a mitad de sesión, los recovery codes de MFA que nunca podían canjearse, y el seeding RBAC abortando en boot dejando 5 de 11 role templates. **El host ya no depende de correr en UTC** (ADR-0002): una sola línea `RuntimeHostConfigurationOption` atascaba `QueueDistributionWorker` y dejaba `POST /api/setup` a medias en cualquier host no-UTC. Verificación MFA fallida ahora se audita y cuenta para el lockout; `SSH.NET` → `2026.0.0` (GHSA-q939-rpr3-3284); 22 bumps de terceros, cuatro majors que llegan a la imagen. **Web** saca las credenciales bearer del browser (Web/ADR-0011, openspec `stop-persisting-auth-secrets`, #247 — cierra verbara-meta/**R-015**): `auth-store` persistía su estado _entero_ sin `partialize`, así que el access token, el `mfaPending.mfaToken` **pre-autenticación** (una credencial que salta el primer factor) y, al impersonar, el `impersonation.originalToken` **del propio operador** quedaban en claro en `sessionStorage`, legibles por cualquier script del origin; la porción persistida es ahora exactamente los hechos de sesión no secretos. Más: todos los guards de security-admin sobre ids canónicos `domain:resource:action`, texto muted a WCAG AA con nombres accesibles en los controles icon-only, embed de webchat emitido en la raíz del outDir, floor de cobertura 38 → 41, 45 merges npm (seis del grupo `npm-security`). 4 imágenes cosign-signed (run `32946067672`); api `sha256:3834a956…` / realtime `sha256:6e976391…` en authorized-digests (verbara-website #97). Web multi-arch `sha256:903ff0e7…` (run `32946189306`). _**El cascade de pins `2.3.2` → `2.4.0` YA OCURRIÓ** (2026-07-28, PR #210, en `main` y **sin cortar versión**): `Directory.Packages.props` queda en `Verbara.Sdk.* 2.4.0` (7 paquetes) + `Verbara.Sdk.Pro.* 2.13.1-pro` (22) + `Microsoft.Extensions.* 10.0.10` (7), las tres familias **en un solo commit** — SDK `2.4.0` sube el floor transitivo de esa última familia y Platform la pinea **directo**, así que mover solo la mitad `Verbara.Sdk.*` da NU1605 fatal bajo `TreatWarningsAsErrors` (`NU1605` no está en ningún `NoWarn`). SDK `2.4.0` es un dependency-bump train **sin cambio de API** (`NATS.Client.Core` 2.8.2 → 3.0.0 major + OpenTelemetry → 1.17.0 + `Microsoft.Extensions.*` 10.0.9 → 10.0.10), así que **nada bajo `src/`/`tests/` cambió**: se movió el baseline, no se adoptó una feature — y la exposición de Platform a NATS es **cero** (el transporte realtime es SignalR + StackExchange.Redis). `Microsoft.Extensions.TimeProvider.Testing` se queda deliberadamente en `10.0.0` (test-only, otra servicing track). Rodó como su propio tren de dependencias (**verbara-meta/R-013**, `Verbara.Sdk/ADR-0040` D3), **nunca plegado a un release train**; deja como spec viva la capability `sdk-pin-cascade`, y el siguiente tag que se corte de `main` es el que publica estos pins._ **✅ 2026-07-27 `/xr:release` train: Platform `v2.22.0` + Web `v3.18.0-web` "agent-presence admin surfaces" SHIPPED** — cierra en la UI el Grupo A W3/W4 de **Verbara.Platform.Web/ADR-0009**: Platform surfacea `pendingPauseTimeoutMinutes` en `GET`/`PUT /api/v1/admin/auth/config` (#198 — el **driver MINOR**; puro surfacing de un campo ya persistido de `TenantAuthConfig`, sin endpoint/store/migración/`ApiJsonContext` nuevos), y Web añade el botón force-offline (endpoint vivo desde Platform `2.9.0`) + el editor del campo, que **exige Platform ≥ 2.22.0** (contra `2.21.2` el campo no viene en la respuesta y se descarta en el write). 4 imágenes cosign-signed (`release.yml` run `30324647348`); api `sha256:6f40317e…` / realtime `sha256:9c390d9c…` en authorized-digests (verbara-website #79) — **primer release donde ambos digests se emiten automáticamente**: el recordatorio de `release.yml` ya no está gateado en `matrix.name == 'api'` (#203). También en el tag: el **fast-path de CI docs/data-only** (gate job + clasificador fail-closed, verbara-meta ADR-0016; #200/#202), §6-validado en las dos fases (`pull_request` #201 + `merge_group` #202). **✅ 2026-07-26 Platform `v2.21.2`** — `/health/ready` devuelve **200 (no 503)** en un boot community/self-host sin licencia, con **cero cambio de source en Platform**: la severidad vive entera en Pro (`dialer-engine` settlea `Degraded`), y el agregado voltea sólo por el pin bump `2.12.0-pro` → `2.13.0-pro` (#194, Verbara.Sdk.Pro/ADR-0017). **✅ 2026-07-25 Platform `v2.21.1` + Web `v3.17.0-web`** (ADR-0036 document-truth transformers: se extingue la unión numérica `["integer","string"]` que .NET 10 reflejaba + `ComplianceRuleSummaryDto.severity` pasa a enum cerrado — **document-only, sin cambio de runtime**; Web migra `react-router-dom@7` → `react-router@8.3.0` por el advisory CSRF de RSC-mode) · **✅ 2026-07-24 Platform `v2.21.0` + Web `v3.16.0-web`** (management API keys minteadas con CSPRNG en vez de `Guid.NewGuid()` + invariant gate #7 + la ola de gates **verbara-meta/ADR-0012** Ola-2/Ola-3 y **verbara-meta/ADR-0013**) · **✅ 2026-07-20 Platform `v2.20.0` + Web `v3.15.0-web`** (dialer license enforcement en el punto de gasto + named OpenAPI response schemas 183 → 391, ADR-0035). _Header baselines corregidos 2026-07-28 (habían drifted desde `v2.19.0`) y los 5 releases `v2.20.0`→`v2.22.0` **backfilled en la tabla Shipped el mismo día** — cuarta repetición de la misma clase; ver las notas de 2026-07-12, 2026-07-01 y 2026-06-18._ **✅ 2026-07-14 `/xr:release` train: Platform `v2.19.0` + Web `v3.14.0-web` + SDK `v2.3.1` "CSAT voice + aggregate KPI" SHIPPED** — closes the CSAT train (`csat-completion`, ADR-0020; Pro `2.10.0-pro` published in-train 2026-07-13): voice trigger + survey-IVR handoff + anonymous HMAC-verified `POST /api/v1/csat/responses/voice` + scope-wide `GET /api/v1/analytics/csat` aggregate (resolves the wallboard ⟨NEEDS PRODUCT-OWNER INPUT⟩ in favor of aggregation) + live `preview-voice` + typed `OnCsatResponseRecorded` relay + Web scope-wide KPI card; api digest `1020f117…` / realtime `0881ff26…` in authorized-digests (website #63); SDK `2.3.1` = LMNT mid-send abort fix (#84), pins cascaded Platform + Pro. **✅ 2026-07-12 Web `v3.13.1-web` (hotfix)** — supervisor CSAT KPI card aligned to the real `CsatResponseDto` analytics contract (`averageRating`/`totalResponses`); image `sha256:af8b86b0…` cosign-verified end-to-end; first release cut via the `/xr:release` §H tag-push handoff. **✅ 2026-07-11/12 Platform `v2.18.0` + Web `v3.13.0-web` "CSAT consumer (digital-first)" SHIPPED** — the CSAT Runner train (Pro `2.9.0-pro`; ADR-0020); voice/TTS deferred to a Pro Path-A follow-up; api digest `dcf565b5…` / realtime `75691a53…` in authorized-digests. _GH Release objects for `v2.18.0` + SDK `v2.3.0` backfilled 2026-07-12 — en su momento ni `release.yml` (Platform) ni `publish.yml` (Sdk) creaban uno; gap encontrado por un fact-check de `/xr:pending`, parcheado en el procedimiento verbara-meta `/xr:release` §H.5 (#15) y **cerrado de raíz el 2026-07-28**: los cuatro workflows del ecosistema crean ahora el release object ellos mismos (Platform #207/#208, Web #246, Sdk #138; Sdk.Pro ya lo hacía)._ **✅ 2026-07-06 Platform `v2.17.0`** — Typification **E5 autonomous disposition (dark/OFF, ADR-0034)** + audit-trail integrity + report-only live-DB CI lane + released-image smoke + first `SECURITY.md`; cascades SDK `2.3.0` + Pro `2.8.1-pro`. _Header baselines corregidos 2026-07-12 (habían drifted desde v2.16.0; misma clase que los backfills 2026-07-01 y 2026-06-18 de abajo)._ **✅ 2026-06-28 AI-credit ledger `v2.16.0`** (signed append-only ledger + O(1) balance projection; inert behind 2 default-off kill-switches; ADR-0033) · **✅ 2026-06-24 Typification P2c.2 `v2.15.0` + Web `v3.11.0-web`** (platform-managed metered LLM / AI Credits) · **✅ 2026-06-23 `v2.14.1`** (impersonation + rate-limiter fail-closed fixes) — the three above were **backfilled into the Shipped table 2026-07-01** (had drifted since v2.14.0). _(El 🟢 E5 "dark + unreleased" del 2026-07-01 quedó released — dark/OFF — en `v2.17.0`, ver arriba.)_ **✅ 2026-06-22 Typification P2c.1 (per-tenant BYO LLM config, BYO-only) SHIPPED end-to-end** — Platform **`v2.14.0`** + Platform.Web **`v3.10.0-web`** (PR #74+#117 via merge queue; 4 AOT/IL + Web cosign images; GH Releases; api digest `6cc1a9ef…` registered in authorized-digests #34, Worker auto-deployed). Multi-provider pluggable (OpenAI-compat/Azure/Anthropic), encrypted creds, fail-closed, AI strictly opt-in. **BREAKING (multi-tenant):** the shared global LLM key is retired (single-tenant/dev auto-seeded). Also folds the **#72 auth-drain fix**. _Platform-managed LLM as a metered/gated/billed service = **P2c.2** (next)._ **✅ 2026-06-21 Typification P2b SHIPPED end-to-end** — Platform **`v2.13.0`** (API: PR #70+#71, 4 imágenes AOT/IL cosign-signed, GH Release, api digest en authorized-digests) + Platform.Web **`v3.9.0-web`** (UI: PR #112+#116). `release.yml` runs verdes (Platform 27905988770 / Web 27906388147). _Tren Session/Auth (2.9.x) + Typification (P0–P2b, 2.10.0→2.13.0) añadido a la tabla Shipped el 2026-06-18 (estaba drifted desde 2026-06-01)._ **✅ 2026-06-01 v2.7.0 (Inbound Conversation Delivery) + v2.8.0 (Telephony admin: trunk+DID) + v2.8.1 (realtime reference-smb hotfix) SHIPPED** — releases un-deferred; see Shipped table + [[project-telephony-admin-v281]]. _Histórico previo:_ Platform **`2.5.4 + ADR-0026 Phase A + Phase B en main`** (post-Phase A.5 + ADR-0025 K8s health contract fix + JWT Tier-1 hardening + observability + Phase A wizard fix + Phase B membership executive gate) · Platform.Web **`3.1.3-web` + Phase A editor en main** · SDK pin **`2.2.1`** · Pro pin **`2.6.0-pro`** (bumped 2026-05-29 para Phase B `IRealtimeSyncService.AddQueueMemberAsync(allowedChannels)` signature change) · **🎉 visibility flip EXECUTED 2026-05-10 — Platform + Web repos PUBLIC** · **✅ 2026-05-22 ADR-0022 Phase D CLOSED** (Native AOT shipping) · **✅ 2026-05-24 Phase A.5 CLOSED** (Plan B Test 5 PARTIAL→PASS) · **✅ 2026-05-25 ADR-0025 K8s health contract + Phase B-LK + Phase C-LK closed on v2.5.2** · **✅ 2026-05-25 JWT Tier-1 hardening + lab causality on v2.5.4** (TTL bump = primary driver; stale-cache fallback = insurance, never fired in lab) · **✅ 2026-05-26 R5.5 Phase D-LK 24h soak PASS + R5.5 train SHIPPED with Production Readiness Review** · **✅ 2026-05-28 ADR-0026 Phase A + ADR-0027 tenant-type gate SHIPPED** · **✅ 2026-05-29 ADR-0026 Phase B SHIPPED** (digital-routing executive gate; SMB Docker product polish = ZERO routing tech debt; release packaging deferred to first paying customer). > ### 🛑 STRATEGIC PIVOT 2026-05-25 — No cloud until real customers exist > From 376abcdca1c06056d243b324f1993240c35e204a Mon Sep 17 00:00:00 2001 From: "Harol A. Reina H." Date: Sat, 3 Oct 2026 18:37:06 -0500 Subject: [PATCH 2/2] docs(roadmap): Platform.Web baseline v3.20.0-web --- docs/roadmap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/roadmap.md b/docs/roadmap.md index b06d6a02..188ecbe6 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,6 +1,6 @@ # Roadmap — Verbara.Platform + Verbara.Platform.Web -**Última actualización:** 2026-10-03 · **Baselines actuales (released, tagged + GH Release + cosign):** Platform **`v2.25.0`** · Platform.Web **`v3.19.0-web`** · SDK **`2.4.0`** (nuget.org; **`2.5.0` ya publicado — el cascade `2.4.0` → `2.5.0` queda deferred como verbara-meta/R-021**) · Pro **`2.14.1-pro`** (GitHub Packages). **✅ 2026-10-03 `/xr:release`: Platform `v2.25.0` — release de seguridad, nueve advisories (alta: [GHSA-4qm8-6258-jpr6](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-4qm8-6258-jpr6), [GHSA-879r-434c-qx3v](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-879r-434c-qx3v), [GHSA-6mgx-v32x-vhm4](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-6mgx-v32x-vhm4), [GHSA-cwf2-m5mc-jch2](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-cwf2-m5mc-jch2), [GHSA-55hw-wcx5-33hj](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-55hw-wcx5-33hj); moderada: [GHSA-9j4m-4xj8-wmmg](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-9j4m-4xj8-wmmg), [GHSA-63cv-jpx9-qp2q](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-63cv-jpx9-qp2q), [GHSA-23rw-vxw4-fv7j](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-23rw-vxw4-fv7j), [GHSA-jcx3-prpv-h984](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-jcx3-prpv-h984); #326, #327; cierra #283).** **✅ 2026-10-03 `/xr:release`: Platform `v2.24.0` — release de seguridad ([GHSA-fxfp-76v2-xjg2](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-fxfp-76v2-xjg2), [GHSA-757c-652x-p67g](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-757c-652x-p67g); #323, #324).** **✅ 2026-08-26 `/xr:release` train: Platform `v2.23.0` + Web `v3.19.0-web` SHIPPED** — el tren de seguridad + corrección de imagen. Platform cifra el material de enrolamiento MFA **at rest** con DataProtection (cierra verbara-meta/**R-014**): migrador de arranque one-shot idempotente para las filas preexistentes, **sin cambio de esquema ni de API** (`mfa_secret` sigue `TEXT`) — y la durabilidad del keyring pasa a ser **load-bearing**, leer el bloque de impacto operativo antes de desplegar o hacer rollback. Además cae una tanda de **500s que estaban vivos en toda imagen shipeada**: `GET /admin/flows`, `DELETE /admin/skills/{name}` (borraba y _después_ fallaba), `GET /admin/audit` (todos los tenants, todas las llamadas); más el refresh de token que borraba cada permiso a mitad de sesión, los recovery codes de MFA que nunca podían canjearse, y el seeding RBAC abortando en boot dejando 5 de 11 role templates. **El host ya no depende de correr en UTC** (ADR-0002): una sola línea `RuntimeHostConfigurationOption` atascaba `QueueDistributionWorker` y dejaba `POST /api/setup` a medias en cualquier host no-UTC. Verificación MFA fallida ahora se audita y cuenta para el lockout; `SSH.NET` → `2026.0.0` (GHSA-q939-rpr3-3284); 22 bumps de terceros, cuatro majors que llegan a la imagen. **Web** saca las credenciales bearer del browser (Web/ADR-0011, openspec `stop-persisting-auth-secrets`, #247 — cierra verbara-meta/**R-015**): `auth-store` persistía su estado _entero_ sin `partialize`, así que el access token, el `mfaPending.mfaToken` **pre-autenticación** (una credencial que salta el primer factor) y, al impersonar, el `impersonation.originalToken` **del propio operador** quedaban en claro en `sessionStorage`, legibles por cualquier script del origin; la porción persistida es ahora exactamente los hechos de sesión no secretos. Más: todos los guards de security-admin sobre ids canónicos `domain:resource:action`, texto muted a WCAG AA con nombres accesibles en los controles icon-only, embed de webchat emitido en la raíz del outDir, floor de cobertura 38 → 41, 45 merges npm (seis del grupo `npm-security`). 4 imágenes cosign-signed (run `32946067672`); api `sha256:3834a956…` / realtime `sha256:6e976391…` en authorized-digests (verbara-website #97). Web multi-arch `sha256:903ff0e7…` (run `32946189306`). _**El cascade de pins `2.3.2` → `2.4.0` YA OCURRIÓ** (2026-07-28, PR #210, en `main` y **sin cortar versión**): `Directory.Packages.props` queda en `Verbara.Sdk.* 2.4.0` (7 paquetes) + `Verbara.Sdk.Pro.* 2.13.1-pro` (22) + `Microsoft.Extensions.* 10.0.10` (7), las tres familias **en un solo commit** — SDK `2.4.0` sube el floor transitivo de esa última familia y Platform la pinea **directo**, así que mover solo la mitad `Verbara.Sdk.*` da NU1605 fatal bajo `TreatWarningsAsErrors` (`NU1605` no está en ningún `NoWarn`). SDK `2.4.0` es un dependency-bump train **sin cambio de API** (`NATS.Client.Core` 2.8.2 → 3.0.0 major + OpenTelemetry → 1.17.0 + `Microsoft.Extensions.*` 10.0.9 → 10.0.10), así que **nada bajo `src/`/`tests/` cambió**: se movió el baseline, no se adoptó una feature — y la exposición de Platform a NATS es **cero** (el transporte realtime es SignalR + StackExchange.Redis). `Microsoft.Extensions.TimeProvider.Testing` se queda deliberadamente en `10.0.0` (test-only, otra servicing track). Rodó como su propio tren de dependencias (**verbara-meta/R-013**, `Verbara.Sdk/ADR-0040` D3), **nunca plegado a un release train**; deja como spec viva la capability `sdk-pin-cascade`, y el siguiente tag que se corte de `main` es el que publica estos pins._ **✅ 2026-07-27 `/xr:release` train: Platform `v2.22.0` + Web `v3.18.0-web` "agent-presence admin surfaces" SHIPPED** — cierra en la UI el Grupo A W3/W4 de **Verbara.Platform.Web/ADR-0009**: Platform surfacea `pendingPauseTimeoutMinutes` en `GET`/`PUT /api/v1/admin/auth/config` (#198 — el **driver MINOR**; puro surfacing de un campo ya persistido de `TenantAuthConfig`, sin endpoint/store/migración/`ApiJsonContext` nuevos), y Web añade el botón force-offline (endpoint vivo desde Platform `2.9.0`) + el editor del campo, que **exige Platform ≥ 2.22.0** (contra `2.21.2` el campo no viene en la respuesta y se descarta en el write). 4 imágenes cosign-signed (`release.yml` run `30324647348`); api `sha256:6f40317e…` / realtime `sha256:9c390d9c…` en authorized-digests (verbara-website #79) — **primer release donde ambos digests se emiten automáticamente**: el recordatorio de `release.yml` ya no está gateado en `matrix.name == 'api'` (#203). También en el tag: el **fast-path de CI docs/data-only** (gate job + clasificador fail-closed, verbara-meta ADR-0016; #200/#202), §6-validado en las dos fases (`pull_request` #201 + `merge_group` #202). **✅ 2026-07-26 Platform `v2.21.2`** — `/health/ready` devuelve **200 (no 503)** en un boot community/self-host sin licencia, con **cero cambio de source en Platform**: la severidad vive entera en Pro (`dialer-engine` settlea `Degraded`), y el agregado voltea sólo por el pin bump `2.12.0-pro` → `2.13.0-pro` (#194, Verbara.Sdk.Pro/ADR-0017). **✅ 2026-07-25 Platform `v2.21.1` + Web `v3.17.0-web`** (ADR-0036 document-truth transformers: se extingue la unión numérica `["integer","string"]` que .NET 10 reflejaba + `ComplianceRuleSummaryDto.severity` pasa a enum cerrado — **document-only, sin cambio de runtime**; Web migra `react-router-dom@7` → `react-router@8.3.0` por el advisory CSRF de RSC-mode) · **✅ 2026-07-24 Platform `v2.21.0` + Web `v3.16.0-web`** (management API keys minteadas con CSPRNG en vez de `Guid.NewGuid()` + invariant gate #7 + la ola de gates **verbara-meta/ADR-0012** Ola-2/Ola-3 y **verbara-meta/ADR-0013**) · **✅ 2026-07-20 Platform `v2.20.0` + Web `v3.15.0-web`** (dialer license enforcement en el punto de gasto + named OpenAPI response schemas 183 → 391, ADR-0035). _Header baselines corregidos 2026-07-28 (habían drifted desde `v2.19.0`) y los 5 releases `v2.20.0`→`v2.22.0` **backfilled en la tabla Shipped el mismo día** — cuarta repetición de la misma clase; ver las notas de 2026-07-12, 2026-07-01 y 2026-06-18._ **✅ 2026-07-14 `/xr:release` train: Platform `v2.19.0` + Web `v3.14.0-web` + SDK `v2.3.1` "CSAT voice + aggregate KPI" SHIPPED** — closes the CSAT train (`csat-completion`, ADR-0020; Pro `2.10.0-pro` published in-train 2026-07-13): voice trigger + survey-IVR handoff + anonymous HMAC-verified `POST /api/v1/csat/responses/voice` + scope-wide `GET /api/v1/analytics/csat` aggregate (resolves the wallboard ⟨NEEDS PRODUCT-OWNER INPUT⟩ in favor of aggregation) + live `preview-voice` + typed `OnCsatResponseRecorded` relay + Web scope-wide KPI card; api digest `1020f117…` / realtime `0881ff26…` in authorized-digests (website #63); SDK `2.3.1` = LMNT mid-send abort fix (#84), pins cascaded Platform + Pro. **✅ 2026-07-12 Web `v3.13.1-web` (hotfix)** — supervisor CSAT KPI card aligned to the real `CsatResponseDto` analytics contract (`averageRating`/`totalResponses`); image `sha256:af8b86b0…` cosign-verified end-to-end; first release cut via the `/xr:release` §H tag-push handoff. **✅ 2026-07-11/12 Platform `v2.18.0` + Web `v3.13.0-web` "CSAT consumer (digital-first)" SHIPPED** — the CSAT Runner train (Pro `2.9.0-pro`; ADR-0020); voice/TTS deferred to a Pro Path-A follow-up; api digest `dcf565b5…` / realtime `75691a53…` in authorized-digests. _GH Release objects for `v2.18.0` + SDK `v2.3.0` backfilled 2026-07-12 — en su momento ni `release.yml` (Platform) ni `publish.yml` (Sdk) creaban uno; gap encontrado por un fact-check de `/xr:pending`, parcheado en el procedimiento verbara-meta `/xr:release` §H.5 (#15) y **cerrado de raíz el 2026-07-28**: los cuatro workflows del ecosistema crean ahora el release object ellos mismos (Platform #207/#208, Web #246, Sdk #138; Sdk.Pro ya lo hacía)._ **✅ 2026-07-06 Platform `v2.17.0`** — Typification **E5 autonomous disposition (dark/OFF, ADR-0034)** + audit-trail integrity + report-only live-DB CI lane + released-image smoke + first `SECURITY.md`; cascades SDK `2.3.0` + Pro `2.8.1-pro`. _Header baselines corregidos 2026-07-12 (habían drifted desde v2.16.0; misma clase que los backfills 2026-07-01 y 2026-06-18 de abajo)._ **✅ 2026-06-28 AI-credit ledger `v2.16.0`** (signed append-only ledger + O(1) balance projection; inert behind 2 default-off kill-switches; ADR-0033) · **✅ 2026-06-24 Typification P2c.2 `v2.15.0` + Web `v3.11.0-web`** (platform-managed metered LLM / AI Credits) · **✅ 2026-06-23 `v2.14.1`** (impersonation + rate-limiter fail-closed fixes) — the three above were **backfilled into the Shipped table 2026-07-01** (had drifted since v2.14.0). _(El 🟢 E5 "dark + unreleased" del 2026-07-01 quedó released — dark/OFF — en `v2.17.0`, ver arriba.)_ **✅ 2026-06-22 Typification P2c.1 (per-tenant BYO LLM config, BYO-only) SHIPPED end-to-end** — Platform **`v2.14.0`** + Platform.Web **`v3.10.0-web`** (PR #74+#117 via merge queue; 4 AOT/IL + Web cosign images; GH Releases; api digest `6cc1a9ef…` registered in authorized-digests #34, Worker auto-deployed). Multi-provider pluggable (OpenAI-compat/Azure/Anthropic), encrypted creds, fail-closed, AI strictly opt-in. **BREAKING (multi-tenant):** the shared global LLM key is retired (single-tenant/dev auto-seeded). Also folds the **#72 auth-drain fix**. _Platform-managed LLM as a metered/gated/billed service = **P2c.2** (next)._ **✅ 2026-06-21 Typification P2b SHIPPED end-to-end** — Platform **`v2.13.0`** (API: PR #70+#71, 4 imágenes AOT/IL cosign-signed, GH Release, api digest en authorized-digests) + Platform.Web **`v3.9.0-web`** (UI: PR #112+#116). `release.yml` runs verdes (Platform 27905988770 / Web 27906388147). _Tren Session/Auth (2.9.x) + Typification (P0–P2b, 2.10.0→2.13.0) añadido a la tabla Shipped el 2026-06-18 (estaba drifted desde 2026-06-01)._ **✅ 2026-06-01 v2.7.0 (Inbound Conversation Delivery) + v2.8.0 (Telephony admin: trunk+DID) + v2.8.1 (realtime reference-smb hotfix) SHIPPED** — releases un-deferred; see Shipped table + [[project-telephony-admin-v281]]. _Histórico previo:_ Platform **`2.5.4 + ADR-0026 Phase A + Phase B en main`** (post-Phase A.5 + ADR-0025 K8s health contract fix + JWT Tier-1 hardening + observability + Phase A wizard fix + Phase B membership executive gate) · Platform.Web **`3.1.3-web` + Phase A editor en main** · SDK pin **`2.2.1`** · Pro pin **`2.6.0-pro`** (bumped 2026-05-29 para Phase B `IRealtimeSyncService.AddQueueMemberAsync(allowedChannels)` signature change) · **🎉 visibility flip EXECUTED 2026-05-10 — Platform + Web repos PUBLIC** · **✅ 2026-05-22 ADR-0022 Phase D CLOSED** (Native AOT shipping) · **✅ 2026-05-24 Phase A.5 CLOSED** (Plan B Test 5 PARTIAL→PASS) · **✅ 2026-05-25 ADR-0025 K8s health contract + Phase B-LK + Phase C-LK closed on v2.5.2** · **✅ 2026-05-25 JWT Tier-1 hardening + lab causality on v2.5.4** (TTL bump = primary driver; stale-cache fallback = insurance, never fired in lab) · **✅ 2026-05-26 R5.5 Phase D-LK 24h soak PASS + R5.5 train SHIPPED with Production Readiness Review** · **✅ 2026-05-28 ADR-0026 Phase A + ADR-0027 tenant-type gate SHIPPED** · **✅ 2026-05-29 ADR-0026 Phase B SHIPPED** (digital-routing executive gate; SMB Docker product polish = ZERO routing tech debt; release packaging deferred to first paying customer). +**Última actualización:** 2026-10-03 · **Baselines actuales (released, tagged + GH Release + cosign):** Platform **`v2.25.0`** · Platform.Web **`v3.20.0-web`** · SDK **`2.4.0`** (nuget.org; **`2.5.0` ya publicado — el cascade `2.4.0` → `2.5.0` queda deferred como verbara-meta/R-021**) · Pro **`2.14.1-pro`** (GitHub Packages). **✅ 2026-10-03 `/xr:release`: Platform `v2.25.0` — release de seguridad, nueve advisories (alta: [GHSA-4qm8-6258-jpr6](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-4qm8-6258-jpr6), [GHSA-879r-434c-qx3v](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-879r-434c-qx3v), [GHSA-6mgx-v32x-vhm4](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-6mgx-v32x-vhm4), [GHSA-cwf2-m5mc-jch2](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-cwf2-m5mc-jch2), [GHSA-55hw-wcx5-33hj](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-55hw-wcx5-33hj); moderada: [GHSA-9j4m-4xj8-wmmg](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-9j4m-4xj8-wmmg), [GHSA-63cv-jpx9-qp2q](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-63cv-jpx9-qp2q), [GHSA-23rw-vxw4-fv7j](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-23rw-vxw4-fv7j), [GHSA-jcx3-prpv-h984](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-jcx3-prpv-h984); #326, #327; cierra #283).** **✅ 2026-10-03 `/xr:release`: Platform `v2.24.0` — release de seguridad ([GHSA-fxfp-76v2-xjg2](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-fxfp-76v2-xjg2), [GHSA-757c-652x-p67g](https://github.com/verbara/Verbara.Platform/security/advisories/GHSA-757c-652x-p67g); #323, #324).** **✅ 2026-08-26 `/xr:release` train: Platform `v2.23.0` + Web `v3.19.0-web` SHIPPED** — el tren de seguridad + corrección de imagen. Platform cifra el material de enrolamiento MFA **at rest** con DataProtection (cierra verbara-meta/**R-014**): migrador de arranque one-shot idempotente para las filas preexistentes, **sin cambio de esquema ni de API** (`mfa_secret` sigue `TEXT`) — y la durabilidad del keyring pasa a ser **load-bearing**, leer el bloque de impacto operativo antes de desplegar o hacer rollback. Además cae una tanda de **500s que estaban vivos en toda imagen shipeada**: `GET /admin/flows`, `DELETE /admin/skills/{name}` (borraba y _después_ fallaba), `GET /admin/audit` (todos los tenants, todas las llamadas); más el refresh de token que borraba cada permiso a mitad de sesión, los recovery codes de MFA que nunca podían canjearse, y el seeding RBAC abortando en boot dejando 5 de 11 role templates. **El host ya no depende de correr en UTC** (ADR-0002): una sola línea `RuntimeHostConfigurationOption` atascaba `QueueDistributionWorker` y dejaba `POST /api/setup` a medias en cualquier host no-UTC. Verificación MFA fallida ahora se audita y cuenta para el lockout; `SSH.NET` → `2026.0.0` (GHSA-q939-rpr3-3284); 22 bumps de terceros, cuatro majors que llegan a la imagen. **Web** saca las credenciales bearer del browser (Web/ADR-0011, openspec `stop-persisting-auth-secrets`, #247 — cierra verbara-meta/**R-015**): `auth-store` persistía su estado _entero_ sin `partialize`, así que el access token, el `mfaPending.mfaToken` **pre-autenticación** (una credencial que salta el primer factor) y, al impersonar, el `impersonation.originalToken` **del propio operador** quedaban en claro en `sessionStorage`, legibles por cualquier script del origin; la porción persistida es ahora exactamente los hechos de sesión no secretos. Más: todos los guards de security-admin sobre ids canónicos `domain:resource:action`, texto muted a WCAG AA con nombres accesibles en los controles icon-only, embed de webchat emitido en la raíz del outDir, floor de cobertura 38 → 41, 45 merges npm (seis del grupo `npm-security`). 4 imágenes cosign-signed (run `32946067672`); api `sha256:3834a956…` / realtime `sha256:6e976391…` en authorized-digests (verbara-website #97). Web multi-arch `sha256:903ff0e7…` (run `32946189306`). _**El cascade de pins `2.3.2` → `2.4.0` YA OCURRIÓ** (2026-07-28, PR #210, en `main` y **sin cortar versión**): `Directory.Packages.props` queda en `Verbara.Sdk.* 2.4.0` (7 paquetes) + `Verbara.Sdk.Pro.* 2.13.1-pro` (22) + `Microsoft.Extensions.* 10.0.10` (7), las tres familias **en un solo commit** — SDK `2.4.0` sube el floor transitivo de esa última familia y Platform la pinea **directo**, así que mover solo la mitad `Verbara.Sdk.*` da NU1605 fatal bajo `TreatWarningsAsErrors` (`NU1605` no está en ningún `NoWarn`). SDK `2.4.0` es un dependency-bump train **sin cambio de API** (`NATS.Client.Core` 2.8.2 → 3.0.0 major + OpenTelemetry → 1.17.0 + `Microsoft.Extensions.*` 10.0.9 → 10.0.10), así que **nada bajo `src/`/`tests/` cambió**: se movió el baseline, no se adoptó una feature — y la exposición de Platform a NATS es **cero** (el transporte realtime es SignalR + StackExchange.Redis). `Microsoft.Extensions.TimeProvider.Testing` se queda deliberadamente en `10.0.0` (test-only, otra servicing track). Rodó como su propio tren de dependencias (**verbara-meta/R-013**, `Verbara.Sdk/ADR-0040` D3), **nunca plegado a un release train**; deja como spec viva la capability `sdk-pin-cascade`, y el siguiente tag que se corte de `main` es el que publica estos pins._ **✅ 2026-07-27 `/xr:release` train: Platform `v2.22.0` + Web `v3.18.0-web` "agent-presence admin surfaces" SHIPPED** — cierra en la UI el Grupo A W3/W4 de **Verbara.Platform.Web/ADR-0009**: Platform surfacea `pendingPauseTimeoutMinutes` en `GET`/`PUT /api/v1/admin/auth/config` (#198 — el **driver MINOR**; puro surfacing de un campo ya persistido de `TenantAuthConfig`, sin endpoint/store/migración/`ApiJsonContext` nuevos), y Web añade el botón force-offline (endpoint vivo desde Platform `2.9.0`) + el editor del campo, que **exige Platform ≥ 2.22.0** (contra `2.21.2` el campo no viene en la respuesta y se descarta en el write). 4 imágenes cosign-signed (`release.yml` run `30324647348`); api `sha256:6f40317e…` / realtime `sha256:9c390d9c…` en authorized-digests (verbara-website #79) — **primer release donde ambos digests se emiten automáticamente**: el recordatorio de `release.yml` ya no está gateado en `matrix.name == 'api'` (#203). También en el tag: el **fast-path de CI docs/data-only** (gate job + clasificador fail-closed, verbara-meta ADR-0016; #200/#202), §6-validado en las dos fases (`pull_request` #201 + `merge_group` #202). **✅ 2026-07-26 Platform `v2.21.2`** — `/health/ready` devuelve **200 (no 503)** en un boot community/self-host sin licencia, con **cero cambio de source en Platform**: la severidad vive entera en Pro (`dialer-engine` settlea `Degraded`), y el agregado voltea sólo por el pin bump `2.12.0-pro` → `2.13.0-pro` (#194, Verbara.Sdk.Pro/ADR-0017). **✅ 2026-07-25 Platform `v2.21.1` + Web `v3.17.0-web`** (ADR-0036 document-truth transformers: se extingue la unión numérica `["integer","string"]` que .NET 10 reflejaba + `ComplianceRuleSummaryDto.severity` pasa a enum cerrado — **document-only, sin cambio de runtime**; Web migra `react-router-dom@7` → `react-router@8.3.0` por el advisory CSRF de RSC-mode) · **✅ 2026-07-24 Platform `v2.21.0` + Web `v3.16.0-web`** (management API keys minteadas con CSPRNG en vez de `Guid.NewGuid()` + invariant gate #7 + la ola de gates **verbara-meta/ADR-0012** Ola-2/Ola-3 y **verbara-meta/ADR-0013**) · **✅ 2026-07-20 Platform `v2.20.0` + Web `v3.15.0-web`** (dialer license enforcement en el punto de gasto + named OpenAPI response schemas 183 → 391, ADR-0035). _Header baselines corregidos 2026-07-28 (habían drifted desde `v2.19.0`) y los 5 releases `v2.20.0`→`v2.22.0` **backfilled en la tabla Shipped el mismo día** — cuarta repetición de la misma clase; ver las notas de 2026-07-12, 2026-07-01 y 2026-06-18._ **✅ 2026-07-14 `/xr:release` train: Platform `v2.19.0` + Web `v3.14.0-web` + SDK `v2.3.1` "CSAT voice + aggregate KPI" SHIPPED** — closes the CSAT train (`csat-completion`, ADR-0020; Pro `2.10.0-pro` published in-train 2026-07-13): voice trigger + survey-IVR handoff + anonymous HMAC-verified `POST /api/v1/csat/responses/voice` + scope-wide `GET /api/v1/analytics/csat` aggregate (resolves the wallboard ⟨NEEDS PRODUCT-OWNER INPUT⟩ in favor of aggregation) + live `preview-voice` + typed `OnCsatResponseRecorded` relay + Web scope-wide KPI card; api digest `1020f117…` / realtime `0881ff26…` in authorized-digests (website #63); SDK `2.3.1` = LMNT mid-send abort fix (#84), pins cascaded Platform + Pro. **✅ 2026-07-12 Web `v3.13.1-web` (hotfix)** — supervisor CSAT KPI card aligned to the real `CsatResponseDto` analytics contract (`averageRating`/`totalResponses`); image `sha256:af8b86b0…` cosign-verified end-to-end; first release cut via the `/xr:release` §H tag-push handoff. **✅ 2026-07-11/12 Platform `v2.18.0` + Web `v3.13.0-web` "CSAT consumer (digital-first)" SHIPPED** — the CSAT Runner train (Pro `2.9.0-pro`; ADR-0020); voice/TTS deferred to a Pro Path-A follow-up; api digest `dcf565b5…` / realtime `75691a53…` in authorized-digests. _GH Release objects for `v2.18.0` + SDK `v2.3.0` backfilled 2026-07-12 — en su momento ni `release.yml` (Platform) ni `publish.yml` (Sdk) creaban uno; gap encontrado por un fact-check de `/xr:pending`, parcheado en el procedimiento verbara-meta `/xr:release` §H.5 (#15) y **cerrado de raíz el 2026-07-28**: los cuatro workflows del ecosistema crean ahora el release object ellos mismos (Platform #207/#208, Web #246, Sdk #138; Sdk.Pro ya lo hacía)._ **✅ 2026-07-06 Platform `v2.17.0`** — Typification **E5 autonomous disposition (dark/OFF, ADR-0034)** + audit-trail integrity + report-only live-DB CI lane + released-image smoke + first `SECURITY.md`; cascades SDK `2.3.0` + Pro `2.8.1-pro`. _Header baselines corregidos 2026-07-12 (habían drifted desde v2.16.0; misma clase que los backfills 2026-07-01 y 2026-06-18 de abajo)._ **✅ 2026-06-28 AI-credit ledger `v2.16.0`** (signed append-only ledger + O(1) balance projection; inert behind 2 default-off kill-switches; ADR-0033) · **✅ 2026-06-24 Typification P2c.2 `v2.15.0` + Web `v3.11.0-web`** (platform-managed metered LLM / AI Credits) · **✅ 2026-06-23 `v2.14.1`** (impersonation + rate-limiter fail-closed fixes) — the three above were **backfilled into the Shipped table 2026-07-01** (had drifted since v2.14.0). _(El 🟢 E5 "dark + unreleased" del 2026-07-01 quedó released — dark/OFF — en `v2.17.0`, ver arriba.)_ **✅ 2026-06-22 Typification P2c.1 (per-tenant BYO LLM config, BYO-only) SHIPPED end-to-end** — Platform **`v2.14.0`** + Platform.Web **`v3.10.0-web`** (PR #74+#117 via merge queue; 4 AOT/IL + Web cosign images; GH Releases; api digest `6cc1a9ef…` registered in authorized-digests #34, Worker auto-deployed). Multi-provider pluggable (OpenAI-compat/Azure/Anthropic), encrypted creds, fail-closed, AI strictly opt-in. **BREAKING (multi-tenant):** the shared global LLM key is retired (single-tenant/dev auto-seeded). Also folds the **#72 auth-drain fix**. _Platform-managed LLM as a metered/gated/billed service = **P2c.2** (next)._ **✅ 2026-06-21 Typification P2b SHIPPED end-to-end** — Platform **`v2.13.0`** (API: PR #70+#71, 4 imágenes AOT/IL cosign-signed, GH Release, api digest en authorized-digests) + Platform.Web **`v3.9.0-web`** (UI: PR #112+#116). `release.yml` runs verdes (Platform 27905988770 / Web 27906388147). _Tren Session/Auth (2.9.x) + Typification (P0–P2b, 2.10.0→2.13.0) añadido a la tabla Shipped el 2026-06-18 (estaba drifted desde 2026-06-01)._ **✅ 2026-06-01 v2.7.0 (Inbound Conversation Delivery) + v2.8.0 (Telephony admin: trunk+DID) + v2.8.1 (realtime reference-smb hotfix) SHIPPED** — releases un-deferred; see Shipped table + [[project-telephony-admin-v281]]. _Histórico previo:_ Platform **`2.5.4 + ADR-0026 Phase A + Phase B en main`** (post-Phase A.5 + ADR-0025 K8s health contract fix + JWT Tier-1 hardening + observability + Phase A wizard fix + Phase B membership executive gate) · Platform.Web **`3.1.3-web` + Phase A editor en main** · SDK pin **`2.2.1`** · Pro pin **`2.6.0-pro`** (bumped 2026-05-29 para Phase B `IRealtimeSyncService.AddQueueMemberAsync(allowedChannels)` signature change) · **🎉 visibility flip EXECUTED 2026-05-10 — Platform + Web repos PUBLIC** · **✅ 2026-05-22 ADR-0022 Phase D CLOSED** (Native AOT shipping) · **✅ 2026-05-24 Phase A.5 CLOSED** (Plan B Test 5 PARTIAL→PASS) · **✅ 2026-05-25 ADR-0025 K8s health contract + Phase B-LK + Phase C-LK closed on v2.5.2** · **✅ 2026-05-25 JWT Tier-1 hardening + lab causality on v2.5.4** (TTL bump = primary driver; stale-cache fallback = insurance, never fired in lab) · **✅ 2026-05-26 R5.5 Phase D-LK 24h soak PASS + R5.5 train SHIPPED with Production Readiness Review** · **✅ 2026-05-28 ADR-0026 Phase A + ADR-0027 tenant-type gate SHIPPED** · **✅ 2026-05-29 ADR-0026 Phase B SHIPPED** (digital-routing executive gate; SMB Docker product polish = ZERO routing tech debt; release packaging deferred to first paying customer). > ### 🛑 STRATEGIC PIVOT 2026-05-25 — No cloud until real customers exist >