# Cambios del 8 y 9 de octubre de 2026 · admira.tv y repos relacionados

Registro para el Consejo y para los agentes: qué se hizo, dónde y dónde está la documentación. Todo está fusionado,
desplegado y verificado salvo donde se indica. Las horas son de Madrid.

Ayuda para personas: https://admira.tv/help/#novedades-2026-10-09 · Hub MCP: https://admira.tv/mcp/#cambios-2026-10-09

## admira.tv (este repo)

| PR | Qué (en pocas palabras) | Detalle | Documentación |
|---|---|---|---|
| [#54](https://github.com/csilvasantin/admira-tv/pull/54) | Playlists: arreglos de creación, fase 1 | `GET /api/playlist` devuelve `synthetic:true`, `origin{live,hashtag}`, `rev` y `liveRev` cuando la lista la componen las vivas o el #hashtag; el POST sólo da 409 si la `rev` guardada no coincide; el censo de etiquetas sólo se escribe con pistas del player. La parrilla muestra «sigue la playlist viva X» con **Fijar a mano** y **Crear y asignar**. En `/playlists/`, «Borrar» sólo vacía la copia local del navegador; borrar las plantillas de la flota es otra acción y exige escribir **BORRAR** | [help#playlists-vivas](https://admira.tv/help/#playlists-vivas) |
| [#55](https://github.com/csilvasantin/admira-tv/pull/55) | Qué emite cada pantalla | Página `/emision/` y `GET /api/emision?screen=&at=&tag=`: réplica pura de `rebuild()` de `canal.html` | [emision.md](https://admira.tv/mcp/emision.md) · [help#que-emite](https://admira.tv/help/#que-emite) |
| [#56](https://github.com/csilvasantin/admira-tv/pull/56) | Kioskos: publicar `-tema` con clave | `tools/publica-playlists-kioskos.py` lee `CONTROL_PLAYLIST_KEY` del entorno o de `admira-vault` y la manda en `X-Control-Key` | [player-contract.md §6](https://admira.tv/mcp/player-contract.md) |
| [#57](https://github.com/csilvasantin/admira-tv/pull/57) | Modelo único E1+E2: D1, horario, resolver | Esquema `migrations/programacion/0001.sql`, `horario.js` y `resolver.js` puros; capas 500/400/300/200/100 y mezclas | [programacion.md](https://admira.tv/mcp/programacion.md) |
| [#58](https://github.com/csilvasantin/admira-tv/pull/58) | E3: lectura `GET /api/programacion` | Sólo lectura, memoria por `meta.version` | [programacion.md §3.1](https://admira.tv/mcp/programacion.md) |
| [#59](https://github.com/csilvasantin/admira-tv/pull/59) | E4: API de escritura con `rev` | Playlists, asignaciones y circuitos; historial y auditoría; 409/428/422; visor sin emails | [programacion.md §3.2](https://admira.tv/mcp/programacion.md) |
| [#60](https://github.com/csilvasantin/admira-tv/pull/60) | E5: importador del legado KV→D1 | Simula por defecto; `?aplicar=1`, `?pisar=1`, `?archivar=1`; idempotente por `ref_externa` | [programacion.md §5.1](https://admira.tv/mcp/programacion.md) |
| [#61](https://github.com/csilvasantin/admira-tv/pull/61) | D1 `admira-programacion` creada y conectada | Carlos la creó (WEUR); binding `PROGRAMACION_DB`. Importación aplicada: 34 playlists + 34 asignaciones (versión 68); paridad 7/7 con `/api/emision` | [programacion.md §0](https://admira.tv/mcp/programacion.md) |
| [#62](https://github.com/csilvasantin/admira-tv/pull/62) | E6+E7: modo sombra y doble escritura | Comparación tras la respuesta del player (tabla `sombra`, panel `/programacion/sombra/`) y espejo KV→D1 en `waitUntil`. **Encendidos por Carlos el 9-oct** (`sombra`, `espejo`; `motor` apagado; versión 69); simulación posterior: 0 escrituras | [programacion.md §3.4–§5](https://admira.tv/mcp/programacion.md) |
| [#64](https://github.com/csilvasantin/admira-tv/pull/64) | Acceso: fin del bucle de recarga | `/users/` y `/remotecontrol/` esperan a la verja; contrato `AdmiraTvAuth.ready()` / `expired()` | [acceso-paginas.md](https://admira.tv/mcp/acceso-paginas.md) · [help#paginas-acceso](https://admira.tv/help/#paginas-acceso) |
| [#65](https://github.com/csilvasantin/admira-tv/pull/65) | Parrilla en el iPad: tarjetas visibles | Columna de ~386 px: consulta de contenedor + `align-content:start` y `flex-shrink:0` en `.slot` | [help#parrilla-ipad](https://admira.tv/help/#parrilla-ipad) |
| [#66](https://github.com/csilvasantin/admira-tv/pull/66) | Parrilla: miniaturas con portada del Stock | Safari del iPad no carga el primer fotograma: `poster`/`thumbnail` de `stock/index.json` | [help#parrilla-ipad](https://admira.tv/help/#parrilla-ipad) |
| [#67](https://github.com/csilvasantin/admira-tv/pull/67) | Parrilla: vista previa con portada | La «Vista previa» y el visor enseñan la portada mientras no reproducen | [help#parrilla-ipad](https://admira.tv/help/#parrilla-ipad) |

Otros PR fusionados esas fechas, de otras líneas de trabajo: [#52](https://github.com/csilvasantin/admira-tv/pull/52)
(backoffice del quiosco segmentado `/audiencia`), [#53](https://github.com/csilvasantin/admira-tv/pull/53) (aviso de
privacidad visible en Audiencia) y [#63](https://github.com/csilvasantin/admira-tv/pull/63) (⌘ Experto: `/idioma` y
`/arquitectura`).

## Otros repos (referencias; se documentan allí)

| PR | Qué (en pocas palabras) | Detalle |
|---|---|---|
| [omnipublicity-api #34](https://github.com/csilvasantin/omnipublicity-api/pull/34) | E0: escribir `-tema` exige clave | Escribir `/control/playlist?screen=<pantalla>-tema` exigirá `CONTROL_PLAYLIST_KEY` en cuanto esté puesta. **Aún no lo está**: nada cambia hoy |
| [pixeria #86](https://github.com/csilvasantin/pixeria/pull/86) | Asignar al circuito respeta lo sintético | El modo «añadir» respeta el borrador sintético: envía `rev`, relee una vez ante un 409 y salta la pantalla cuya lista no puede leer |
| [pixeria #87](https://github.com/csilvasantin/pixeria/pull/87) | Adaptador: MP4 grandes por partes | Más de 8 MB: partes de 25 MB por `/stock-upload/{start,part,complete,abort}` y `/stock-publish {r2Staged}`. Acaba con el 503 «Worker exceeded resource limits» con ficheros de ~70 MB. Tope 500 MB |
| [pixeria #88](https://github.com/csilvasantin/pixeria/pull/88) | Resto de subidas al Stock por partes | La caja de importación del Adaptador (tope 500 MB), y `app.js` (archivos locales y por URL) y `scripts/stock-subir.py` (tope 2 GB los dos) |
| [pixer-worker #8](https://github.com/csilvasantin/pixer-worker/pull/8) | Subida por partes: tamaño y limpieza | `/stock/upload/complete` comprueba el tamaño declarado; las subidas a medias se barren a las 24 h |
| [xpaceos #100](https://github.com/csilvasantin/xpaceos/pull/100) | Gente caminando por defecto | `/gente on` por defecto en todos los Xpacios; lo elegido a mano se conserva con la marca `elegido` |

Pixeria y admira.studio comparten código (admira.studio es el espejo que genera `sync.sh`), así que #86–#88 valen en
los dos dominios.

**«Programar players» de Pixeria** (`functions/players-programar.js`): modo prueba (sólo lecturas, devuelve el plan y
una `firma`) y modo real (exige la firma de la prueba del mismo lote). `STOCK_NOTIFY_KEY` ya está puesta en los dos
proyectos de Pages (pixeria y admira-studio). El 9-oct se dieron de alta en la parrilla las **18 pantallas de prueba de
Altadis BCN** (circuito `altadis_bcn`, nombres acabados en «· PRUEBA») y se programaron de verdad con «I want true love
· Altadis» (vertical y horizontal). Documentación: https://github.com/csilvasantin/pixeria/blob/main/docs/adaptador.md
(«Subida por partes al Stock» y «Programación de players»).

## Player nativo de iPad (repo nuevo, privado)

`csilvasantin/admira-player-ipad` (SwiftUI + AVPlayer), v0.1 del 9-oct: «Por defecto» + Stock + parrilla cada 4, caché
en disco, sin red, informa a `/signage/now` y compañía. Verificado en el «iPad de Admin» como
`altadis-bcn-001-p1-vertical` (`/api/emision` → `vivo: true`). Firma gratuita: caduca el 16-oct-2026. Documentación:
https://admira.tv/mcp/ipad-nativo.md · Cómo probar en el iPad: https://admira.tv/mcp/ipad-pruebas.md

## Pendiente

- Modelo único: E8 (mando en vivo), E9 (el player lee `/api/programacion`; **acceso por decidir**, recomendado lectura
  pública por pantalla), E10–E14. Desviación 6 (spots sobre una base exacta) abierta.
- `CONTROL_PLAYLIST_KEY` y `PROGRAMACION_SERVICE_KEY`: sin poner (opcionales; las pone Carlos).
- Player de iPad: id de pantalla por aparato, firma de pago (`JTVR8HASG7`) y TestFlight, sustituir
  `admiranext-player-ios`, sonido por defecto, AV1/H.264, nombre, órdenes del mando en la v2.

## EN · summary

8–9 Oct 2026 changelog. admira.tv: playlist phase-1 fixes (#54), "what each screen plays" page and API (#55), kiosk
`-tema` publisher key (#56), unified playlist model E1–E7 with the production D1 (#57–#62; shadow mode and double write
switched on by Carlos, engine off), no more reload loop on gated pages with the `AdmiraTvAuth.ready()/expired()`
contract (#64), and the grid on iPad (#65–#67). Related repos: omnipublicity-api #34, pixeria #86–#88, pixer-worker #8,
xpaceos #100, Pixeria's "Programar players" for the 18 Altadis BCN test screens, and the new native iPad player.
