docs: producer & media ingest, ops changes, library updates (October 2026)

- engineering-guide §10: media attachments, alt-text delivery, producer,
  audio-less silence bed, chunked ingest, upload caps
- admin-guide §10: oCIS retired from the payload path, storage_key (041),
  publishing media resolver + dedupe origins, produce-worker, api restart
  rate-limit note; §6.3 marked legacy
- user-guide §9: 2 GiB Library uploads, compose attachments + alt text,
  producer, chunked large-video uploads
This commit is contained in:
glass beadian 2026-10-16 02:33:46 +00:00
parent 2d881f5e41
commit b3c2085436
3 changed files with 62 additions and 4 deletions

View file

@ -162,7 +162,35 @@ Shipped and wired end-to-end:
Still planned: media-engine graph rewiring beyond the current FFmpeg-normalize path, LLM video AI (design only), content search rollout.
## 10. Key file map
## 10. Producer & media ingest (October 2026)
### 10.1 Media attachments for publishing
- `POST /media` (multipart `file`); content type is **magic-byte sniffed** (jpeg/png/webp/mp4/webm) — the extension is never trusted.
- Caps: image **10 MiB**, video **64 MiB**, and at most **4 attachments per post** (`MAX_MEDIA_PER_POST`).
- Read back via `GET /media/:id` (auth-scoped). Bytes live in R2 object storage — SPENC1 envelope-encrypted, content-addressed `sha256` keys (§3.8 scheme).
### 10.2 Alt texts
- Drafts carry `altTexts` positionally aligned with `mediaAssetIds` (0–4 entries; `null` = no alt text for that slot).
- At publish, the scheduler maps them into `providerMetadata.altText` (asset-id keyed); Mastodon media uploads receive them as descriptions.
### 10.3 Video producer
- `POST /video/:id/produce` accepts `{ overlays?, voiceover?, outputLabel?, lane? }` — closed enums with a strict key allowlist; unknown keys are rejected. Overlay kinds: `lower_third | logo | clock`; overlay text runs through the filtergraph-metacharacter blocklist before it reaches an FFmpeg graph.
- Jobs execute in the **produce-worker** (its own container, `MEDIA_WORKER_LANE=local`): claim/lease via polling with `SKIP LOCKED`; stale leases are re-queued.
- The output is a **derived library asset** (`derived_from`), publishable like any other asset.
### 10.4 Audio-less sources
- The command-builder synthesizes an `anullsrc` silence bed — configured at the output preset's rate/layout — instead of emitting `[0:a]` maps that ffmpeg rejects.
### 10.5 Chunked video ingest
- `POST /video/upload/init` → `PUT /video/upload/:uploadId/chunk/:index` → `POST /video/upload/:uploadId/complete`.
- 10 MiB chunks (`CHUNK_SIZE_BYTES`) sidestep Cloudflare's ~100 MB proxy body cap. The server reassembles, seals, stores to R2, then runs the normal probe pipeline.
- Max chunked upload: **100 GiB** (`MAX_CHUNKED_UPLOAD_BYTES`).
### 10.6 Upload caps
- Whole-body video upload cap: **2 GiB** (`MAX_VIDEO_UPLOAD_BYTES`).
- Files group upload cap: **2 GiB** (was 20 MiB).
## 11. Key file map
| Concern | Path |
|---|---|