Vista generada de dec-0019: r23 — Canonical Media Factory (arquitectura codec-agnostic + pipeline)
docs/decisions/dec-0019-canonical-media-factory.mdVista generada desde
docs/decisions/dec-0019-canonical-media-factory.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 | LOCKED |
| Fecha | 2026-06-21 |
| Referencia legada | r23 |
| Fichero | docs/decisions/dec-0019-canonical-media-factory.md |
Nodos del roadmap que lo citan en refs: ninguno.
Páginas de la documentación que lo citan: ninguna todavía.
Leído de docs/decisions/dec-0019-canonical-media-factory.md, el fichero canónico.
Styx ingesta contenido vía ARR/torrent/IPTV/remote sources. r23 formaliza el modelo en el que el archivo descargado no es automáticamente la fuente permanente de verdad. Es un AcquisitionArtifact temporal que Styx convierte en una CanonicalRepresentation inmutable, enriquecida, verificada y versionada. Esta tesis fue validada por 6 pythia en research adversarial y por auditoría adversarial de ChatGPT (2026-06-21).
waxin lockeó las decisiones vía AskUserQuestion (sesión CMF, 2026-06-21):
La arquitectura de Styx NO acopla el modelo de dominio a codecs concretos. El codec es una policy versionada y reemplazable, no una categoría arquitectónica.
CanonicalRepresentation se modela con capabilities + descriptores, no con tipos de codec:
CanonicalRepresentation:
- id, edition_id, generation
- codec_descriptor (family, profile, level, tier)
- bit_depth, chroma_subsampling
- hdr_metadata (format, primaries, transfer, mastering display, CLL/FALL)
- random_access_characteristics (GOP structure, keyframe interval, seek points)
- quality_class (metrics snapshot)
- decoder_requirements (hw/sw, minimum profile, reference frames)
- storage_cost, processing_cost
- recipe_version
- lifecycle_state (candidate | active | retained | evicted | experimental)Los codecs tienen roles dinámicos, no Tiers rígidos:
frontier-preferred | canonical-active | production-fallback | compatibility | legacy | experimental
Una misma representación puede cambiar de rol cuando el ecosistema madure, sin migrar la arquitectura. Añadir AV3, VVC, un nuevo perfil AV2 o cualquier codec futuro no debe requerir cambiar el modelo de dominio ni el media graph: solo registrar capabilities, encoder/decoder adapters y una nueva policy/recipe.
| Rol | Codec | Nota |
|---|---|---|
frontier-preferred | AV2 | Objetivo real del máster canónico. Corpus piloto con recipe pinneada + known-issues matrix + decode validation + source retention. |
production-fallback | AV1 | Provisional operativo. NO es destino estratégico. Content-adaptive recipes, quality gates. |
compatibility | HEVC Main10 | Fallback de compatibilidad (modo Xtream legacy). No necesariamente permanente por asset. |
La promoción es por generaciones inmutables:
AV1 canonical generation actual
→ AV2 candidate generation (encode + QC)
→ AV2 promoted as active canonical (pointer swap)
→ AV1 retained temporarily or evicted by policyNO se fijan CRF, thresholds exactos, encoder flags ni fechas de maduración en esta decisión arquitectónica. Eso pertenece a recipes versionadas y al corpus piloto.
13 estados (ACQUIRED → ... → PROMOTED → ACQUISITION_RELEASED), cada uno idempotente,
resumible, cancelable, content-addressed.
Arquitectura de workflow:
cmd.*), events (evt.*), retries operacionalesOwnership por etapa:
| Etapa | Owner | Toca bytes? |
|---|---|---|
| ACQUIRED→IDENTIFIED | workers-svc (Bun) | No |
| IDENTIFIED→PROBED | styx-media-daemon (Zig, libav) | Sí (probe) |
| PROBED→REPAIRED | daemon Zig | Sí |
| REPAIRED→ENRICHED | workers-svc | No |
| ENRICHED→ENCODE_PLANNED | workers-svc (PlaybackPlanner) | No |
| ENCODE_PLANNED→VIDEO_ENCODED | daemon Zig (libav) | Sí |
| ENCODE_PLANNED→AUDIO_NORMALIZED | daemon Zig | Sí |
| ENCODE_PLANNED→SUBTITLES | workers-svc + daemon Zig | Mixto |
| →PACKAGED | daemon Zig | Sí |
| →VERIFIED | workers-svc + daemon Zig | Mixto |
| →PROMOTED | workers-svc (tx atómica) | No |
| →ACQUISITION_RELEASED | workers-svc (NATS evt) | No |
Principio: Bun orquesta y decide; Zig procesa bytes vía libav C ABI. Bytes de media NUNCA atraviesan JavaScript (r01, r22). Frontera Bun↔Zig = IPC Unix socket (r22).
El modelo lógico de CanonicalRepresentation es codec-agnostic (manifest versionado + generations inmutables + payload/track independence + materializaciones derivadas). El formato físico de payload es decisión de implementación, no arquitectónica.
Dirección bleeding-edge (waxin): full native manifest + packs content-addressed como source-of-truth universal. MKV/MP4 como materializaciones bajo demanda. Se exige prototype que confirme viabilidad adversarial: recovery, seek random, remote SFTP, GC, corrupción parcial, export, disaster recovery sin Postgres.
Mientras el prototype no esté validado, AV1 usa MKV portable (mkvmerge + mkclean) y AV2
usa elementary OBU stream + sidecar manifest. La arquitectura NO depende de esta provisionalidad.
Preservar (stream copy): lossless/immersivo del idioma principal + pistas marcadas como valiosas por el usuario. NO preservar: commentary, idiomas secundarios lossless, pistas duplicadas. Derivados: solo bajo demanda del cliente (E-AC-3 5.1 640kbps, Opus stereo 192kbps). Loudness: medir (EBU R128), NO normalizar destructivamente.
La policy es versionada y configurable (CanonicalAudioPolicy), no hardcodeada en la
arquitectura.
Postgres es la fuente de verdad. El manifest es provenance. Los tags de contenedor son proyección.
Los thresholds exactos (SSIMULACRA2 ≥90, VMAF ≥93, etc.) son hipótesis de corpus piloto, no criterios arquitectónicos. Lo que se lockea:
| Decisión | Efecto |
|---|---|
| r01 (Bun decide, Zig ejecuta) | REALIZA — pipeline completa con ownership por etapa |
| r08 (Work→Edition→MediaAsset→SourceBinding) | EXTIENDE — CanonicalRepresentation como modelo codec-agnostic |
| r09 (media graph adapters) | REFUERZA — añadir codec = solo adapters + policy, no toca modelo |
| r10 (delivery plane) | APLICA — negotiation order con direct canonical first |
| r11 (Storage Box) | APLICA — canonical storage + packfiles para cold storage del acquisition |
| r16 (lab bleeding-edge) | ENCARNA — AV2-first, native pack store, owned pipeline |
| r17 (microservicios) | REFUERZA — pipeline con ownership claro por servicio |
| r18 (NATS JetStream) | UTILIZA — task dispatch + events en el pipeline |
| r20 (PlaybackPlan composicional) | EXTIENDE — negotiation order + capabilities como selector de representation |
| r22 (Zig data plane) | REALIZA — daemon Zig como ejecutor byte-level de la pipeline |
| ID | Trade-off | Aceptado porque |
|---|---|---|
| T1 | AV2 es frontier con bugs conocidos, no production-ready → corpus piloto | waxin: bleeding-edge. AV2 es el norte estratégico. Source retention + gates mitigan. |
| T2 | Native pack store requiere construir tooling de filesystem propio → riesgo de scope | waxin: full bleeding-edge. Se exige prototype adversarial antes de lockear como universal. |
| T3 | Pipeline 13 estados con FSM en Postgres → complejidad de estado | workers-svc con SKIP LOCKED + LISTEN/NOTIFY + idempotencia. Patrón probado (DBOS, HotMesh). |
| T4 | Metadata 3-layer → sincronización entre capas | Postgres es la autoridad. Embedded y manifest son proyecciones derivadas, no independientes. |
docs/research/canonical-media-factory-2026-06-21/ (dossier completo, 6 pythia)docs/updates/styx-canonical-media-factory-research-brief.md (brief original ChatGPT)styx-cmf-adversarial-audit-2026-06-21.md (auditoría adversarial ChatGPT)docs/decisions/r22-...md (Zig data plane)dec-0018
Vista generada de dec-0018: Familia de runtimes nativos sobre contratos comunes (Apple/Android/Browser/Windows/Linux, decoder/render especializado por plataforma, protocolo/sesión/scheduling compartidos) — reabre F6 como North Star lockeada, ejecución diferida Browser→Apple→Android→Desktop.
dec-0020
Vista generada de dec-0020: NVMe como working set (30-80GB), no biblioteca; el streaming vive en Storage Box.