Spec canónica de protocols/session-ipc/messages/ingest.md, copiada sin reescribir.
protocols/session-ipc/messages/ingest.mdPágina generada desde
protocols/session-ipc/messages/ingest.md. No se edita a mano:bun run docs:genla regenera ybun run docs:checkfalla si difiere.
cmd.media.openIngest, cmd.media.pollIngestEvents, cmd.media.closeIngestSubida de ficheros a un nodo con el wire de conduit (dec-0121). Bun decide quién sube
(playback-svc, tras resolver el access token del usuario), el daemon ejecuta: liga una sesión de
ingesta en la autoridad de capabilities (spire.cap) y reporta las subidas terminadas. Los bytes
nunca pasan por este socket: el cliente sube al IngestSink del daemon con la SCT ingest de la
sesión.
Contratos: packages/api-contracts/src/bus/media-daemon.ts (MediaOpenIngest,
MediaPollIngestEvents, MediaCloseIngest), validados por spire a los dos lados. Emisores
admitidos (BUS_ROUTES): playback-svc y styx-ops; cualquier otro, status = denied.
cmd.media.openIngest{ "capActor": "<32 hex: actorOf(actorId)>", "capResource": "<64 hex: Resource.ingestRoot(rootId)>" }Liga ing_<32 hex> (16 bytes aleatorios) al actor y a la raíz de ingesta del daemon. La SCT de
scope ingest de esa sesión (sid = esos 16 bytes, resource = la raíz, rango bytes [0, max)
= tope del fichero) es lo único que el sink acepta.
{ "result": { "sessionId": "ing_…", "endpoint": "https://node/api/upload", "rootId": "ingest" } }error.code | Cuándo |
|---|---|
INGEST_UNAVAILABLE | el daemon no tiene ingesta (STYX_INGEST_ROOT sin definir) o autoridad |
INGEST_RESOURCE_MISMATCH | capResource no es la raíz de este daemon (no se liga nada) |
CAPABILITY_BINDING_INVALID | digests mal formados |
TOO_MANY_SESSIONS | la tabla de sesiones de la autoridad está llena (recoverable: true) |
CAPABILITY_BIND_FAILED | el id ya estaba ligado |
Si la respuesta no se puede sellar, spire deshace el binding (onReplyFailure): nadie tendría el
id para cerrarla.
cmd.media.pollIngestEvents{ "ackSeq": 0 }Confirma (y olvida) todo evento con seq <= ackSeq y devuelve los más antiguos sin confirmar,
como mucho 32:
{
"events": [
{
"seq": 1,
"sessionId": "ing_…",
"actorDigest": "<32 hex>",
"uploadId": "<32 hex>",
"sizeBytes": 1234,
"blake3": "<64 hex: raíz BLAKE3 del fichero, lo que imprime b3sum>",
"rootId": "ingest",
"key": "<64 hex: nombre bajo la raíz = blake3>",
"filename": "nombre del cliente (metadata)"
}
]
}Versión 2 del contrato (la 1 llevaba sha256 y se rechaza): la ingesta habla conduit wire v2
(sólo v2, dec-0121), así que la raíz que el daemon verificó al recibir es la BLAKE3 en árbol de
conduit (dec-0129), la misma que imprime b3sum. Es la identidad de los bytes transferidos, no la
del asset (dec-0127 deriva AssetId de la huella del payload).
Un evento sólo sale de la cola cuando se confirma: entrega al menos una vez. Con la cola llena,
el complete del cliente responde 500 y se reintenta. playback-svc confirma un evento cuando
catalog lo registró (cmd.catalog.registerIngested) o lo rechazó para siempre. Sin ingesta:
{ "error": { "code": "INGEST_UNAVAILABLE", … } }.
cmd.media.closeIngest{ "sessionId": "ing_…" }Desliga la sesión en la autoridad: todo token suyo deja de pasar en la siguiente petición al sink
(revocación). Después el sink olvida el token de la sesión y aborta sus subidas sin terminar: el
hueco del actor, la reserva de staging y el .part vuelven en el acto (una que ya renombra su
fichero termina y se retira después). Idempotente: { "closed": false } si ya no estaba ligada;
lo que quedara de la sesión en el sink se aborta igual.