---
title: "Architecture Decision Records"
manual: "Content Repurpose"
version: "0.13"
permalink: "https://docs.typo3.org/permalink/netresearch/nr-repurpose:architecture-decision-records@0.13"
source: "Adr/Index.rst"
rendered: "2026-11-02T05:37:21+00:00"
---

<a id="adr"></a>

# Architecture Decision Records {#architecture-decision-records}

This section documents the significant architectural decisions made while
building nr_repurpose. Each record captures the context, the decision, and its
consequences, in the format used across the Netresearch TYPO3 extensions.

## Decision records {#adr-decision-records}

**ADR-001: Asynchronous generation via Symfony Messenger**

Why job generation runs in a worker, and why the
handler swallows failures onto the job row.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-001@0.13)

**ADR-002: Node + Playwright renderer for image composition**

Why HTML-to-PNG and AI-background compositing run
through a bundled Node renderer driving system Chromium.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-002@0.13)

**ADR-003: Provider credentials delegated to nr-llm**

Why this extension owns no provider code and no API key,
and reaches every provider only through nr-llm.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-003@0.13)

**ADR-004: Text formats as schema-validated structured output**

Why the text formats ask nr-llm for schema-validated JSON and
enforce limits in the generator, not only in the prompt.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-004@0.13)

**ADR-005: AI label on every artifact, embedded at storage**

Why every file carries a machine-readable AI marker written in
PHP when it is stored, and which visible labels are optional.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-005@0.13)

**ADR-006: Document formats as HTML printed to PDF**

Why the slide deck and the handout are Fluid templates printed
by Chromium, and how the PDF carries the AI label.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-006@0.13)

**ADR-007: Approval step and publishing through a webhook**

Why every artifact has an approval state, and why approved
social posts leave through a webhook instead of network APIs.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-007@0.13)

**ADR-008: Capability permissions checked before spend**

Why the extension checks `generate_audio` and
`generate_vision` itself, for the job's creator, before the budget.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-008@0.13)

**ADR-009: Data class of the chat tool**

Why `start_repurpose_job` declares `editorContent`, so that
nr-llm's trust-zone gate offers it to runs against external providers.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-009@0.13)

**ADR-010: Page and file job sources**

Why the form uses the core element browser, why a page is read
through its public URL, and which pages a tree selects.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-010@0.13)

**ADR-011: What a failed job tells the editor**

Why a failure stores a reason, which texts an editor reads, and when a
failed job may run again.

[Read](https://docs.typo3.org/permalink/netresearch/nr-repurpose:adr-011@0.13)
