Vista generada de dec-0130: Modo público y Styx como plataforma: registro abierto o con aprobación, roles atados al registro, entrega por biblioteca, moderación y retirada, superficie pública publicable y frontend plantilla
docs/decisions/dec-0130-modo-publico-y-styx-como-plataforma.mdVista generada desde
docs/decisions/dec-0130-modo-publico-y-styx-como-plataforma.md. No se edita a mano:bun run docs:genla regenera ybun run docs:checkfalla si difiere. El estado aquí es el del model: si discrepa con otra página, manda el model.
| Campo | Valor |
|---|---|
| Estado | PROPOSED |
| Fecha | 2026-10-01 |
| Fichero | docs/decisions/dec-0130-modo-publico-y-styx-como-plataforma.md |
Por qué importa (del frontmatter del ADR):
Fija dos cosas que waxin pidió juntas el 2026-10-01 (N8). (1) El modo público: un perfil de despliegue aditivo sobre las capas de cuentas (dec-0125), autorización (dec-0118), catálogo, ingesta (dec-0121) y entrega, con política de registro (cerrado, invitación, aprobación, abierto), principal anónimo opcional, roles de ver, descargar, subir, editar y moderar como niveles de concesión de biblioteca atados a la vía de registro, entrega por biblioteca (stream, descarga o ambos), moderación, aviso y retirada (DMCA, DSA, TCO) y cuotas para un servidor con usuarios no confiables. (2) Styx como plataforma: qué paquetes y componentes se publican, con qué etiquetas de estabilidad y con qué reglas de versionado (sobre dec-0123), docs (dec-0124) y un frontend plantilla que sólo consume la superficie pública. Sin este ADR cada pieza pública nacería con su propia idea de estabilidad, el SDK público heredaría la excepción r52 (tipos importados de un servicio) y el primer despliegue abierto llegaría sin cuotas para anónimos, sin moderación y sin canal de retirada.
Nodos del roadmap que lo citan en refs: ninguno.
Páginas de la documentación que lo citan: Modo público y Styx como plataforma (especificado)
Leído de docs/decisions/dec-0130-modo-publico-y-styx-como-plataforma.md, el fichero canónico.
AskUserQuestion, con las
preguntas de §15 resueltas o diferidas de forma explícita. Mientras no se lockee no se
implementa nada: este ADR describe el sistema objetivo para que la doc (dec-0124 §6) lo
especifique y los contratos se diseñen antes que el código.alpha.1, dec-0133) el modo público se valora bien y el ADR se re-lockea
(diferido d19). Si hace falta algo de contratos antes, se hace. El modo público queda fuera de
los alfas (excludes de alpha.1).w10/adr-publico, desde w10/vision). Nodos
track/platform y track/public-mode: alta propuesta queued en el model, pendiente de ratificar en P10 (§15).docs/overview/vision-ledger.yml): V-N08 (modo público),
V-BIZ-01 (base para construir encima), V-BIZ-02 (aditivo sobre capas existentes),
V-BIZ-03 (motivación: mercado nuevo a coste bajo), V-BIZ-04 (stream, descarga o ambos;
frontend como plantilla; sólo la API). Toca de lado V-N02 (el player como componente
público) y V-N07 (descargas, cuyo diseño es de dec-0129).sesion:resp#9, literal con sus erratas):
r16: frontier salvo blocker. Y su «Productización diferida: "si sale bien"» (línea 31),
con el que este ADR choca a medias (§11.2).r17: un contenedor por authority. El modo público no añade servicios (§11).r20 §2.3 / dec-0116: contract-first TypeBox. El SDK público sale del contrato, no de los
tipos de un servicio (§8.3).r28: cada pieza termina en un consumidor real. El frontend plantilla es el consumidor de
la superficie pública (§9).r48: track/plugins-sdk = SDK público de plugins post-F1, trust levels y manifest
versionado. Este ADR lo enmarca dentro de la superficie pública, no lo redecide.r52: @styx/clients importa el tipo App de catalog-svc. Válido dentro del monorepo;
no publicable (§8.3).r53 / dec-0063: player web propio. N2 ordena: primero los vendorizados, luego el propio.dec-0112 §1: ningún claim comparativo contra Jellyfin sin la suite WC-JF12, tampoco en
la doc pública ni en el README de un paquete.dec-0117: data plane Zig, escritura fd-relativa (las subidas públicas no cambian eso).dec-0118 (LOCKED): BFF sin tokens en el navegador, roles owner/admin/member/restricted,
can(), audit, rate-limit por unidad de cliente. Se respeta entero; una enmienda acotada
(§11.1, principal anónimo).dec-0119 / dec-0120: los eventos nuevos van por spire (BUS_ROUTES).dec-0121: ingesta con conduit, SCT ingest, cuotas por fichero, por actor y de raíz. El
modo público las reutiliza y las escalona por nivel (§7.3).dec-0123 (PROPOSED, w7/release-eng): tren + SemVer por componente, detectores de
interfaz, canales. En su tabla de descartes dice «Publicar packages/* en npm — Son
internos (private). Si algún día se publica plugin-sdk o source-sdk, se promueve a
componente con su tag.» Este ADR es ese «algún día» y fija cómo (§8.4).dec-0124 (PROPOSED): doc como contrato, registro de operaciones (§6.1), estados
especificado|implementado|verificado. La superficie pública es la parte que se documenta
para terceros.dec-0125 (PROPOSED): cuentas, identidades, hogares, perfiles, concesiones de biblioteca,
invitaciones, API keys, device grant. El modo público es configuración de ese modelo
más tres añadidos (§4).dec-0126 (PROPOSED): metadatos en el fichero. Lo que se descarga de un servidor público
lleva sus metadatos y nada del usuario.dec-0127 (modelo de datos), dec-0128
(dispositivos), dec-0129 (transferencias: descarga reanudable y generación al vuelo) y
dec-0131 (federación). Este ADR depende de dec-0129 para el detalle de la descarga y no
lo redecide.Verificado sobre el árbol de w10/vision (base w9/docs).
| Pieza | Estado | Dónde |
|---|---|---|
Roles de instalación restricted < member < admin < owner, permisos <recurso>:<acción> con alcance own/shared/any | existe | packages/authz/src/policy.ts (dec-0118 §4, TS4-P2-02) |
Permisos que hoy existen: asset:play, asset:scan, ingest-session:*, playback-session:close, sesiones y actor | existe | RESOURCE_ACTIONS en policy.ts |
| Rate-limit y agregación de audit por unidad de cliente (IPv6 por su /64) | existe | @styx/observability/client-unit (TS10-P2-01), dec-0118 §9 |
Ingesta con SCT ingest, tope por fichero, cuota por actor (STYX_INGEST_QUOTA_PER_ACTOR_MIB), tope de raíz, sesiones por actor | existe | dec-0121, daemon IngestSink, playback-svc IngestHandler |
| SCT por sesión de reproducción, deny-by-default en el daemon | existe | dec-0117, spire.cap |
| Cuentas, hogares, perfiles, concesiones de biblioteca, invitaciones, API keys, device grant | PROPOSED | dec-0125 |
Registro de operaciones, SDK por operación, CLI styx, MCP | PROPOSED | dec-0124 §6.1 |
| SemVer por componente, detectores de interfaz, manifiesto firmado | PROPOSED | dec-0123 (w7/release-eng) |
Todos los package.json de packages/* y apps/*: private: true, versión 0.0.1/0.1.0 | existe | árbol |
| Licencia del repo: MPL-2.0 | existe | LICENSE |
| spire y conduit: SDKs en sus propios repos, fijados por URL publicada y hash | existe | native/zig/build.zig.zon, @spire/bus en los package.json |
Player: vidstack (dependencia) y limeplay (vendorizado en apps/web/src/engines/limeplay/) | existe | apps/web |
UI: TIER 2 compositional en @styx/ui (packages/ui/src/composite/) | existe | apps/web/CLAUDE.md §TIER |
| Principal anónimo, política de registro, nivel de concesión, visibilidad y entrega por biblioteca, moderación, aviso y retirada | nuevo | este ADR |
| Etiquetas de estabilidad de API pública, informe de API, publicación de paquetes, frontend plantilla | nuevo | este ADR |
Hoy Styx asume que todo usuario es de confianza: alguien que el owner metió a mano. El modo público rompe esa suposición, y por eso lo que falta no es una pantalla sino tres cosas que un servidor privado no necesita: un principal sin cuenta, una forma de dar permisos por la vía de entrada, y moderación.
| Referencia | Qué hace | Qué se toma / qué no |
|---|---|---|
| PeerTube (vídeo público federado) | Registro cerrado, abierto o con aprobación (el solicitante escribe un motivo, admin y moderadores aceptan o rechazan). Cuota diaria y total por usuario. Cualquiera, local o remoto, puede denunciar un vídeo; cola de denuncias con aceptar/rechazar y aviso al denunciante. Recomienda cuota baja o cuarentena automática de lo nuevo. | Las tres políticas de registro con motivo (§5), cuota diaria + total (§7.3), cuarentena de lo subido por cuentas nuevas (§7.2), cola de denuncias con resolución notificada (§7.4). La federación es de dec-0131. |
| Mastodon (registro de instancia) | Registro «cualquiera», «con aprobación» o «nadie», más enlaces de invitación que saltan la aprobación. | Misma tabla, y que una invitación (dec-0125 §7) siempre salta la política de registro. |
| Jellyfin | Servidor privado. Sin registro público, sin subida de ficheros, sin moderación. | Nada que tomar: es el hueco. No se escribe como claim comparativo en la doc pública sin WC-JF12 (dec-0112). |
| DSA (Reglamento UE 2022/2065) | Arts. 16–18 aplican a todo servicio de alojamiento, también a las pequeñas empresas: mecanismo de aviso y acción, exposición de motivos de cada restricción, aviso de sospecha de delito. Los arts. 19–28 (plataformas) no aplican a micro y pequeñas empresas salvo el 24(3). | Canal de aviso estructurado, exposición de motivos por cada acción de moderación y registro de ambos (§7.4). Styx da el mecanismo; el cumplimiento es del operador. |
| TCO / TERREG (Reglamento UE 2021/784) | Una orden de retirada de contenido terrorista se cumple en una hora en toda la UE. Lo retirado se conserva un tiempo. | La retirada tiene que ser una operación de un paso, alcanzable por API y CLI, que corte también las sesiones en curso, y con retención configurable de lo retirado (§7.4). |
| DMCA §512 (EE. UU.) | Puerto seguro si hay agente designado (registro en la Copyright Office, se renueva cada tres años), aviso y retirada, contraaviso, y política de reincidentes aplicada. | Plantilla de aviso, contraaviso y contador de reincidencia por cuenta, con umbral configurable (§7.4). El agente designado es del operador; Styx sólo muestra el contacto. |
| npm trusted publishing (GA 2025-07-31) | Publicar desde GitHub Actions con OIDC, sin token de larga vida, con atestación de procedencia por defecto (npm CLI ≥ 11.5.1). | Canal de publicación de los paquetes públicos (§8.5), coherente con cosign keyless de dec-0123 D3. |
| API Extractor (etiquetas de release de TSDoc) | @public = contrato soportado, no cambia sin MAJOR; @beta = vista previa; @alpha = temprano, no usar; @internal = sólo paquetes del mismo mantenedor. Informe de API versionado en el repo. | Las cuatro etiquetas y el informe de API por paquete como detector de interfaz (§8.4). La herramienta concreta la elige el ticket (TypeDoc ya está en dec-0124). |
Fuentes al final del documento.
STYX_MODE=private|public es un preset de
valores por defecto sobre cinco ajustes independientes (registro, anónimo, visibilidad y
entrega por biblioteca, moderación). private es lo de hoy y sigue siendo el default (§4).closed | invite | approval | open. Una invitación de dec-0125 salta
siempre la política. Sin registro ≠ sin acceso: el acceso sin cuenta es el principal
anónimo, aparte (§5).anonymous: off | browse | play | download), nunca un
actor en la base: no tiene sesión de identity, sus límites cuelgan de la unidad de cliente y
sólo ve bibliotecas concedidas a @anyone (§5.3).view < download < upload < edit < moderate, sobre las concesiones de dec-0125. La política de registro dice qué
concesión recibe la cuenta al nacer. Los roles de servidor de dec-0118 no cambian (§6).delivery: stream | download | both y visibility: private | unlisted | public, aplicados por playback-svc al emitir la SCT (§6.4).@public/@beta/@alpha/@internal, informe de API, SemVer de componente
(dec-0123) y referencia generada (dec-0124). Lo demás sigue private (§8).templates/public-catalog: una app que sólo puede importar la
superficie pública. Es su consumidor real y el test de que se puede construir encima sin
fricción (§9).| Ajuste | Valores | Dónde vive | private (default) | public (preset) |
|---|---|---|---|---|
registration | closed, invite, approval, open | identity-svc, config de servidor | invite | approval |
anonymous | off, browse, play, download | identity-svc + @styx/authz | off | browse |
library.visibility | private, unlisted, public | catalog-svc, por biblioteca | private | private (el owner publica a mano) |
library.delivery | stream, download, both | catalog-svc, por biblioteca | both | stream |
moderation | off, on | catalog-svc + identity-svc | off | on (no se puede apagar en público) |
registration.defaultGrant | nivel de concesión por vía (§6.2) | identity-svc | — | tabla de §6.2 |
registration: open o anonymous ≠ off exigen moderation: on, un contacto de abuso
configurado (STYX_ABUSE_CONTACT) y las cuotas de §7.3. Sin ellos el servicio no arranca
(fail-closed, como el resto de dec-0118).anonymous: download exige que la biblioteca tenga delivery con descarga y que el
servidor tenga STYX_ANON_EGRESS_* (§7.3).STYX_MODE no es un modo de compilación ni de imagen: es el mismo artefacto (dec-0123).dec-0131.Work → Edition → MediaAsset → SourceBinding (r08) ni el de cuentas
(dec-0125). Añade estado de moderación y dos campos de biblioteca.| Política | Quién puede crear cuenta | Qué pasa al pedirla |
|---|---|---|
closed | Sólo el owner/admin, a mano. | No hay formulario. |
invite | Quien tenga una invitación (dec-0125 §7). | Lo de dec-0125. |
approval | Cualquiera pide; un admin o moderador aprueba. | Se crea una solicitud (identidad OIDC ya verificada + motivo + aceptación de normas). Sin cuenta hasta aprobarla. |
open | Cualquiera. | La cuenta nace al volver del OP, con la concesión de la vía open (§6.2) y en periodo de prueba (§7.2). |
dec-0125 §8). En open y approval el OP
tiene que permitir alta pública (Pocket ID ALLOW_USER_SIGNUPS=open) o Styx le pide un token
de registro de un uso por solicitud, el mismo port de aprovisionamiento de dec-0125 §8.2.
El password local opt-in de dec-0125 §8.3 no cambia y no se recomienda en público.approval guarda lo mínimo (sujeto OIDC, email si el OP lo da, motivo,
fecha) y caduca (STYX_REGISTRATION_REQUEST_TTL). Rechazarla la borra; aprobarla crea la
cuenta con la concesión de la vía approval. Las dos acciones se auditan.open y en el formulario de approval, un reto de prueba de trabajo sin
terceros ni cookies de rastreo (ALTCHA, MIT, o uno propio sobre el mismo esquema) más el
rate-limit por unidad de cliente. CAPTCHAs de terceros no: ponen a un tercero delante del
registro y filtran datos (P5).dec-0125 salta cualquier política, incluso closed. Es la forma de
dar upload o edit a gente concreta en un servidor abierto.waxin pidió «registros abiettos, registros con approval de admin, o sin registro». "Sin registro" se lee de dos formas y las dos caben:
registration: closed.anonymous ≠ off, combinable con cualquier política. Un
catálogo público de sólo lectura es registration: closed + anonymous: play. Uno con
comunidad es approval + anonymous: browse.Separarlos evita la trampa de PeerTube y Mastodon, donde "abierto" mezcla quién entra con qué ve el que no ha entrado.
@styx/authz gana un tipo de principal anonymous además del actor. No tiene id
persistente, ni sesión de identity, ni perfil, ni historial: el estado por perfil de
dec-0125 no existe para él. Si se quiere «seguir viendo» sin cuenta, vive en el navegador
(localStorage), nunca en el servidor.anonymous (§4.1) intersecado con las bibliotecas concedidas al
grantee especial @anyone (§6.3). Nunca recibe upload, edit ni moderate, ni ningún
permiso de los recursos de sesión o actor.clientUnitKey, IPv6 por su /64), la misma
clave del rate-limit y del audit (TS10-P2-01).dec-0118 §2.1): el BFF emite la SCT de reproducción o descarga
para el anónimo con TTL corto y ligada a la unidad de cliente. En el daemon no cambia nada:
una SCT es una SCT.dec-0118 fija cuatro roles de servidor y está LOCKED. Lo que waxin pide («quien puede subir
ver editar») no es un rango sobre todo el servidor: es qué hace cada uno con cada
biblioteca. dec-0125 ya tiene la pieza, la concesión de biblioteca a una cuenta o un hogar.
Se le añade un nivel:
| Nivel | Permite | Permisos nuevos en RESOURCE_ACTIONS |
|---|---|---|
view | Ver el catálogo y reproducir (si delivery lo permite). | library:browse (asset:play ya existe) |
download | Lo anterior + descargar (si delivery lo permite; el cómo es de dec-0129). | asset:download |
upload | Lo anterior + subir a esa biblioteca (sesión de ingesta con destino = la biblioteca). | ingest-session:create con alcance de biblioteca |
edit | Lo anterior + editar metadatos y artwork de lo que hay en ella. | metadata:edit |
moderate | Lo anterior + resolver denuncias, ocultar, retirar y suspender en esa biblioteca. | report:resolve, asset:moderate, registration:approve |
dec-0125 §5.1; no la cambia).download (equivale a
lo de hoy: member ve y reproduce lo shared) y la subida sigue saliendo del rol, como en
dec-0121. Nadie pierde ni gana nada al migrar.upload por concesión acota la subida: hoy member sube con alcance own a la raíz de
ingesta; con niveles, sube a la biblioteca concedida y sólo a ella.edit cubre la edición manual de metadatos. Cómo se reescribe el fichero cuando el metadato
vive en él (N1, dec-0127/dec-0126) no es de este ADR; aquí sólo quién puede pedirlo.| Vía | Concesión inicial (recomendada; configurable) | Estado inicial |
|---|---|---|
| anónimo | @anyone: según anonymous (browse = view sin asset:play) | — |
open | @registered (§6.3) a view | prueba (§7.2) |
approval | @registered a view; el que aprueba puede subir el nivel | normal |
invitación (dec-0125 §7) | la que diga la invitación (puede ser upload, edit, moderate) | normal |
| creada por admin | la que fije el admin | normal |
Ninguna vía automática da upload o más: subir, editar y moderar en un servidor abierto se
concede a personas concretas (invitación o admin). Si waxin quiere un servidor de subida
abierta («cualquiera sube»), es @registered a upload con cuarentena obligatoria (P3).
dec-0125 concede a cuenta u hogar. Se añaden dos grantees sin fila propia:
@anyone: cualquier principal, incluido el anónimo. Una biblioteca concedida a @anyone
es visibility: public.@registered: cualquier cuenta activa del servidor.visibility es una vista de las concesiones, no un segundo sistema: public ⇔ hay
concesión a @anyone; unlisted ⇔ concesión a @anyone sólo por enlace directo (no aparece
en listados ni en búsqueda, el id no es adivinable); private ⇔ ninguna. Así sólo hay una
fuente de verdad del acceso.
delivery: stream | download | both es un campo de la biblioteca. playback-svc lo
comprueba al emitir la SCT: no emite scope de descarga si la biblioteca es stream, ni de
reproducción si es download.STYX_ANON_ONTHEFLY=off por defecto);dec-0129.| Amenaza | Mitigación |
|---|---|
| Altas masivas de bots | approval por defecto; prueba de trabajo; rate-limit por unidad de cliente; solicitudes con TTL y tope global. |
| Subida de contenido ilegal o ajeno | Nadie sube sin concesión explícita (§6.2); cuarentena de lo nuevo (§7.2); denuncias y retirada (§7.4); lista de bloqueo por huella (§7.5). |
| Agotar disco | Cuotas de dec-0121 (fichero, actor, raíz) más cuota diaria (§7.3). |
| Agotar CPU con generación al vuelo | Anónimo sin generación al vuelo; cuota de cómputo por cuenta; cola con prioridad a reproducción sobre descarga. |
| Agotar ancho de banda (hotlinking, descargas en bucle) | SCT corta ligada a unidad de cliente; tope de egress por unidad de cliente y global para anónimos; sin URLs de media estables. |
| Enumeración y scraping del catálogo | Listados paginados con tope; unlisted con ids no adivinables; rate-limit de library:browse anónimo. |
| Abuso del canal de denuncias (denuncias falsas masivas) | Prueba de trabajo; rate-limit; denuncias agregadas por objeto; una denuncia no oculta nada por sí sola salvo umbral configurable (P6). |
| Moderador que abusa | moderate sólo por biblioteca; toda acción con motivo y en el audit append-only; el owner revierte; el afectado ve la exposición de motivos. |
| Datos personales en lo subido (metadatos del fichero) | La ingesta no publica los tags originales sin revisar; dec-0126 ya prohíbe datos de usuario en lo que Styx escribe. |
moderation.quarantineUploads: true, entra con estado quarantined: existe, lo ve quien lo
subió y los moderadores, no aparece para nadie más. Un moderador lo publica.open termina por tiempo o por aprobación manual
(configurable); mientras dura, cuotas reducidas.Se reutiliza el ledger por actor de dec-0121 (TS5-P2-01) y se añade:
STYX_ANON_EGRESS_*), medido en el
daemon, que es quien sirve los bytes.report:create): cualquiera, anónimo incluido, contra un asset, una obra, un
comentario futuro o una cuenta. Categoría (derechos de autor, ilegal, spam, otro), texto,
contacto opcional. Para derechos de autor, los campos del aviso DMCA/DSA (titular, obra
original, declaración de buena fe) para que el aviso esté completo.asset:moderate): ocultar, retirar (el objeto deja de servirse), restaurar,
suspender cuenta, bloquear unidad de cliente. Cada acción lleva exposición de motivos
(DSA art. 17: qué, por qué, base, cómo recurrir) que el afectado ve, y va al audit.asset.takedown deja de servir el objeto en todos los caminos
(catálogo, reproducción, descarga, federación), revoca las SCT vivas de ese asset (la
revocación de flujos largos ya existe) y avisa al owner. Por API, por CLI (styx moderation takedown <id> --reason …) y desde la web. Es lo que hace posible cumplir una orden de una
hora (TCO).STYX_TAKEDOWN_RETENTION (TCO pide conservarlo), y después se purga. El operador decide el
plazo.STYX_ABUSE_CONTACT obligatorio en público, mostrado en el pie y en
una ruta de aviso legal (no en security.txt, que es para vulnerabilidades). El agente designado, las normas
de la comunidad y el texto legal son del operador; Styx da el hueco y una plantilla.dec-0114 SC1): si lo subido coincide con
algo retirado antes, entra en cuarentena con la denuncia previa enlazada.moderation (r48 trust levels), porque
dependen de servicios y licencias externas (PhotoDNA no es abierto). El núcleo no lleva
ninguno (P7).| Pieza | Forma | De dónde sale hoy | Estabilidad inicial |
|---|---|---|---|
| API HTTP pública + OpenAPI | rutas del registro de operaciones marcadas public | dec-0124 §6.1, @styx/api-contracts | @beta |
@styx/sdk (TS) | cliente tipado por operación, generado del contrato | evolución de @styx/clients (§8.3) | @beta |
@styx/plugin-sdk + @styx/source-sdk | manifest, kinds, contexto, trust levels | packages/plugin-sdk, packages/source-sdk, r48 | @alpha |
@styx/player (web) | adaptadores para players de terceros + luego el motor propio | apps/web/src/engines/*, r53, N2 | @alpha |
@styx/ui | componentes TIER 2 sin dominio | packages/ui/src/composite/ | @alpha |
CLI styx | binario, --json y exit codes estables | dec-0123 D6, dec-0124 §6.1 | @beta |
| conduit (cliente de subida/descarga) | SDK propio en su repo | repo conduit, dec-0121 | lo fija su repo |
| spire | SDK propio en su repo | repo spire, dec-0119/dec-0120 | lo fija su repo |
| MCP | herramientas = operaciones agentSafe | dec-0124 §6.1 (propuesta) | @alpha |
apps/*-svc), el daemon y sus protocolos internos
(session-ipc), @styx/bus, @styx/authz, @styx/service-http, @styx/observability,
@styx/domain entero. Lo que un tercero necesite de @styx/domain sale por los tipos del
contrato.@styx/player publica los adaptadores
(sesión de Styx → vidstack/limeplay/<video>). El motor propio entra en el mismo paquete
cuando exista, como otro adaptador, sin romper la API de sesión.Cada símbolo exportado por un paquete público lleva una etiqueta TSDoc:
@public: contrato. No cambia de forma incompatible sin subir MAJOR (o MINOR en 0.x,
dec-0123 D1). Documentado al completo.@beta: estable en intención, puede cambiar con aviso en el changelog del componente.@alpha: se puede usar para probar; cambia sin aviso.@internal: sólo para paquetes de Styx; no aparece en la doc pública.Las operaciones HTTP llevan la misma etiqueta en el registro de operaciones, que pasa a la
OpenAPI (x-styx-stability). La doc de referencia pinta la etiqueta.
@styx/clients toma el tipo App de @styx/catalog-svc (excepción r52, type-only). Dentro
del monorepo vale; publicado, arrastraría los tipos internos de un servicio y su dependencia
de Elysia a cada consumidor, y cualquier refactor del servicio sería un breaking change
público. Por eso:
@styx/sdk se genera del registro de operaciones y de los esquemas TypeBox de
@styx/api-contracts (contract-first, r20 §2.3, dec-0116), no de App.dec-0124 §6.1 ya prevé) y r52 queda sin
consumidores: entonces se borra la excepción (DELETE > @deprecated). Eso lo decide waxin
(P8); este ADR sólo fija que lo publicado no depende de App.dec-0123)release/components.yml con su SemVer,
como dec-0123 prevé para plugin-sdk/source-sdk. Se quita private: true sólo en esos.@public
y @beta), versionado en el repo. Un cambio en el informe sin bump es rojo; un cambio
incompatible en @public sin MAJOR (MINOR en 0.x) es rojo. Se engancha a
check:interfaces de dec-0123 D2, que ya trata los detectores como no bajables.@public se marca @deprecated con el reemplazo y vive al menos
una versión MINOR (0.x) o una MAJOR (≥1) antes de borrarse. Una operación HTTP deprecada
responde con la cabecera Deprecation (RFC 9745) y Sunset (RFC 8594).1.0.0 del tren.@styx puede no estar libre) con trusted
publishing por OIDC desde el workflow de release de dec-0123 y procedencia por defecto.
Nunca desde una máquina local.stable de dec-0123 D5 y con dist-tag next desde nightly.publint y la comprobación de tipos para ESM y Node/Bun
(lo concreto lo fija el ticket).dec-0124)@public y @beta tiene doc; TypeDoc con notDocumented como error (dec-0124 §7)
se aplica a estos paquetes primero.desarrollador.dec-0112), tampoco en READMEs de
paquete.templates/public-catalog/: app TanStack Start (el stack de apps/web) que sólo puede
importar paquetes de §8.1, por su nombre publicado. Un guard (extensión de
test/no-apps-imports.test.ts) prohíbe importar apps/*, @internal o paquetes no
públicos. Si la plantilla necesita algo que no está en la superficie pública, falta en la
superficie, no se importa por la puerta de atrás.delivery, registro según la política, subida para quien tenga upload, cola de
moderación para quien tenga moderate. Más sencilla que la web de Styx; mismo BFF
(dec-0118), mismas cookies, sin tokens en el navegador.STYX_MODE=public usando sólo paquetes públicos, se puede construir encima.templates/ es un top-level nuevo) son pregunta (P4).dec-0124 §6.1)Operaciones nuevas (ids estables, sin implementar), cada una con ruta, permiso, método de SDK,
comando de CLI y marca agentSafe:
| Operación | Permiso | CLI | agentSafe |
|---|---|---|---|
server.mode.get / .set | server:configure | styx server mode [public|private] | get sí, set no |
registration.request.create | (anónimo con reto) | — | no |
registration.request.list | registration:approve | styx registration list | sí |
registration.request.approve / .reject | registration:approve | styx registration approve|reject <id> | no (--yes) |
library.access.set | library:configure | styx library access <id> --visibility … --delivery … | no |
library.grant.set | library:configure | styx library grant <id> <grantee> <nivel> | no |
report.create | report:create | styx report create | sí |
report.list / .resolve | report:resolve | styx moderation reports / resolve | list sí, resolve no |
asset.moderate (ocultar, restaurar) | asset:moderate | styx moderation hide|restore <id> | no |
asset.takedown | asset:moderate | styx moderation takedown <id> --reason … | no (--yes) |
account.suspend / .reinstate | account:moderate | styx moderation suspend|reinstate <cuenta> | no |
Los nombres finales los fija el registro de operaciones.
| Capa | Qué cambia | ¿Rompe un contrato? |
|---|---|---|
| Modelo de catálogo (r08) | Nada en Work/Edition/MediaAsset/SourceBinding. Estado de moderación como proyección sobre el asset. | No. |
Cuentas (dec-0125) | Nivel en la concesión, grantees @anyone/@registered, solicitudes de registro, periodo de prueba. | No: campos y filas nuevas; las concesiones existentes migran a download. |
@styx/authz | Permisos nuevos en RESOURCE_ACTIONS; principal anonymous. | Enmienda acotada a dec-0118 §4: un tipo de principal sin actor. Los cuatro roles no cambian. |
| identity-svc | Política de registro, reto, solicitudes. | No. |
| catalog-svc | visibility/delivery como vista y campo de biblioteca, denuncias, acciones, cuarentena, retención. | No. |
| playback-svc | Comprueba delivery y nivel al emitir SCT; SCT para anónimo; cuota de cómputo. | No: la SCT y el daemon no cambian. |
| Daemon Zig | Contador de egress por unidad de cliente si se exige en el daemon. | No: métrica y tope nuevos. |
| Bus | evt.moderation.*, evt.identity.registration*, qry.catalog.libraryAccess en BUS_ROUTES. | No: subjects nuevos. |
| Web de Styx | Pantallas de moderación y de solicitudes. | No. |
Release (dec-0123) | Paquetes públicos como componentes, detector de informe de API. | Enmienda a su tabla de descartes: «Publicar packages/*» pasa a «se publican los de dec-0130 §8.1». |
@styx/clients (r52) | @styx/sdk generado del contrato. | No publica r52; retirar la excepción es una decisión aparte (P8). |
Ningún servicio nuevo (r17): todo cae en identity, catalog y playback. Un nodo de producto nuevo sí (P10).
r16 «Productización diferida» y product-horizon §8 «Productización para terceros»
fuera hasta Personal Alpha. El modo público y la superficie pública son productización
para terceros. waxin lo pide ahora; el choque se resuelve en el lock (P1), no aquí. Lo que
este ADR propone para no adelantar trabajo: diseñar ya los contratos (para no cerrar puertas)
y construir después de outcome/first-vertical.dec-0126 P1 recomienda catálogo autoritativo contra N1; no afecta a este ADR más que
en que la descarga pública lleva el metadato del fichero (lo que N1 quiere).@styx/api-contracts: ServerModeConfig, RegistrationPolicy, RegistrationRequest,
LibraryAccess { visibility, delivery }, LibraryGrant { grantee, level } (extiende
dec-0125), Report, ModerationAction { kind, reason, basis, appeal },
TakedownNotice, ModerationState del asset. Errores IDENTITY_REGISTRATION_*,
CATALOG_MODERATION_*, PLAYBACK_DELIVERY_NOT_ALLOWED.BUS_ROUTES: los subjects de §11.1 con su contrato versionado.STYX_MODE, STYX_REGISTRATION, STYX_ANONYMOUS, STYX_ABUSE_CONTACT,
STYX_ANON_EGRESS_*, STYX_ANON_ONTHEFLY, STYX_TAKEDOWN_RETENTION,
STYX_REGISTRATION_REQUEST_TTL, en el esquema único de config (dec-0124 §7).stability por operación.| Pieza | Consumidor |
|---|---|
| Política de registro, principal anónimo | La plantilla en STYX_MODE=public y su e2e. |
| Niveles de concesión | La plantilla (subida, edición) y la web de Styx (migración download). |
| Moderación y retirada | Cola de moderación de la plantilla y de la web; CLI. |
@styx/sdk y el resto de §8.1 | La plantilla (sólo paquetes públicos) y la web (server functions). |
| Informe de API y estabilidad | check:interfaces de dec-0123. |
Nada de esto se construye sin la plantilla o sin un despliegue público real detrás (P2).
@public es una promesa. Mitigación: empezar
todo en @alpha/@beta y promover sólo lo que la plantilla usa de verdad.public, y el arranque falla sin ello.outcome/first-vertical
(recomendado), o meter el modo público antes. Y si esto enmienda r16/product-horizon §8
(«productización diferida») o convive con ellos como excepción.upload a cualquier registrado
(con cuarentena obligatoria), o la subida en público es siempre por invitación o admin
(recomendado)?templates/public-catalog como top-level nuevo (recomendado, deja claro
que no es apps/web), o apps/public-web. ¿Se publica también como plantilla de
create-…?moderation fuera del núcleo (recomendado), o algo
dentro (lista por huella ya está en §7.5).@styx/sdk, ¿la web pasa a usarlo y se borra la excepción r52
(recomendado), o conviven?@styx está libre? si no, cuál), o
JSR, o GitHub Packages. Y si los paquetes públicos pasan a un repo propio o se publican
desde este monorepo (recomendado: desde aquí, como componentes de dec-0123).track/platform — superficie pública: etiquetas, informes de API, @styx/sdk generado,
publicación, docs «construir sobre Styx», plantilla. Depende de track/docs y de
track/release-engineering (w7).track/public-mode — registro, anónimo, niveles de concesión, entrega por biblioteca,
moderación y retirada. Depende de los milestones de cuentas de dec-0125 P9.track/identity y track/plugins-sdk. Los gate items los
redacta el ticket, con author ≠ verifier y mutantes.public: ¿approval + anonymous: browse + delivery: stream
(recomendado, lo más conservador), u otro?dec-0118 no cambian; que visibility
es una vista de las concesiones; que moderation: on y el contacto de abuso son obligatorios
en público y el arranque falla sin ellos; que la retirada es de un paso y revoca sesiones;
que lo publicado lleva etiqueta de estabilidad, informe de API y SemVer de componente, y no
depende de tipos de un servicio; que la plantilla sólo importa la superficie pública.@styx/authz deja de suponer que todo principal es un actor. Toda función que reciba un
principal tiene que tratar el anónimo (el tipo lo obliga).dec-0123 gana componentes publicados y un detector; su canal stable pasa a publicar en un
registro público además de OCI.dec-0124 gana una audiencia externa real: la referencia de los paquetes públicos deja de
ser «para nosotros».@styx/sdk (P8).dec-0129), la
federación entre servidores (dec-0131), dónde vive el metadato (dec-0127/dec-0126),
dispositivos y cast (dec-0128), el diseño del motor de player propio (N2, posterior).V-N08, V-BIZ-01, V-BIZ-02, V-BIZ-03, V-BIZ-04 pasan a mapear
este ADR (sus GAPs siguen abiertos por nodo y lock).dec-0118 y dec-0123 recibirán un banner de enmienda en el lock, no antes.dec-0125 §5.1 (permiso efectivo) y §4.1 (concesión) son los puntos que este ADR extiende.dec-0129
Vista generada de dec-0129: Transferencias como columna vertebral: subidas, descargas, offline, p2p y adquisición en un solo plano
dec-0131
Vista generada de dec-0131: Federación entre servidores: pares emparejados, concesiones acotadas que se canjean por SCT, contenido remoto como `SourceBinding` y Jellyfin como importación y sincronización