---
title: How media generation works
description: Per-section infographic-or-illustration decisions, a zero-cost deterministic chart renderer beside a generative model, and an image registry that makes storage cleanup safe.
locale: en
version: 0.2.0
canonical: https://enterium-developer-docs.pages.dev/developers/how-it-works/media-generation/
---

> Documentation index: https://enterium-developer-docs.pages.dev/developers/llms.txt — every page of this portal has a Markdown twin at <route>.md; the frozen API contract is at https://enterium-developer-docs.pages.dev/developers/api/openapi.json.

**The problem:** article images are where cost, quality and storage rot
collide — generative images cost money per picture, orphaned files
accumulate forever, and a naive cleanup that guesses wrong deletes
images off live pages.

## Layer 1 — infographic or illustration, decided per section

The media step doesn't decorate the whole article uniformly. Each content
section is classified by a ~10-signal heuristic (density of numbers,
comparisons, list shapes…): data-heavy sections get an **infographic** —
a chart spec rendered deterministically in a headless browser, costing
effectively zero per image — narrative sections get a **generative
illustration** from an image model, costing fractions of a cent. The
platform's own bias shows here: where the content is numeric,
deterministic beats generative on both truth and price.

```mermaid
flowchart TB
    SEC[Article section] --> C{Classifier<br/>~10 signals}
    C -- data-heavy --> IG[Infographic<br/>chart spec → headless render<br/>deterministic]
    C -- narrative --> IL[Illustration<br/>image model]
    IG --> ST[(Object storage)]
    IL --> ST
    ST --> ART[Rendered into the article]
```

The media service itself is a small vendored cloud function — stateless,
storage-backed, with usage stats in memory; the platform calls it through
a typed adapter like any other integration.

## Layer 2 — quota safety

Generative quota exhaustion once looked like a mysterious 500-storm. Now
the adapter surfaces the provider's retry-after hint, applies a cooldown
floor, and a **quota breaker** trips after consecutive refusals — the
run fails fast with an explicit quota verdict instead of burning minutes
in retries.

## Layer 3 — the image registry: cleanup without fear

Every stored image is tracked in a registry with an explicit lifecycle:

```mermaid
stateDiagram-v2
    [*] --> generated: created
    generated --> in_use: referenced by an article
    generated --> orphan_candidate: unreferenced past grace
    orphan_candidate --> in_use: reference appears
    orphan_candidate --> trashed: cleanup pass
    trashed --> [*]: storage lifecycle deletes after retention
    in_use --> orphan_candidate: references removed
```

The load-bearing decisions:

- **References are reconciled from the real render.** The platform
  reports which images its articles actually reference — including a scan
  of the final HTML, added after the field-level extractor was measured
  to miss the vast majority of real references. The registry believes the
  rendered truth, not the metadata.
- **There is no hard delete.** Cleanup can only *trash* — a retention
  window in object storage does the physical deletion later. A wrong
  orphan verdict is recoverable for weeks; a live cleanup pass once
  reclaimed most of the bucket with zero lost live images.

## Trade-offs

Two storages exist by design — object storage for pipeline-generated
media, the site hosts' filesystem for site chrome (avatars, hero images
filled by a separate path) — and the registry governs only the former;
unifying hero-image handling is a known open edge. The per-section
classifier is heuristic: a borderline section can get a chart where an
illustration would read better, a price accepted for determinism.

## See it in two minutes

Any article's image plan and generated assets are visible in its
telemetry; the registry's reference snapshot endpoint shows exactly what
the platform currently claims to use.
