Architecture & design¶
This page describes cuere's components, the actors that interact with it, and the data flow and trust boundaries between them. It is the design documentation backing OSPS-SA-01.01 and the companion to the threat model.
What cuere is¶
cuere is a pure-Python library (plus a thin CLI) that turns a payload into a QR code rendered for a terminal — Unicode half-blocks by default — or exported to SVG/PNG. It performs no network I/O at runtime and executes none of its input: a payload is data that gets encoded into a QR matrix, never code that runs.
Actors¶
| Actor | Role | Boundary |
|---|---|---|
| Calling application / user | Supplies the payload and options through the Python API or the cuere CLI |
Untrusted input crosses into the library |
| Terminal / output sink | Receives rendered text, or a file/bytes sink receives SVG/PNG | cuere writes here |
| segno | The QR/Micro-QR encoder (the only runtime dependency) | Trusted, pinned dependency |
| Optional extras | rich (renderable), typer (CLI), Pillow (PNG) — loaded on demand |
Trusted, pinned, optional |
| Build & release pipeline | GitHub Actions builds, signs, and publishes releases | Trusted CI, see the threat model |
| PyPI | Distribution channel for released wheels/sdists | Trusted distribution point |
Components¶
The package is split so that the core import stays light (no rich, typer, or
Pillow pulled in by import cuere):
| Module | Owns |
|---|---|
matrix |
The segno-wrapping encoder (QRMatrix, ECLevel); the only module that imports segno |
render |
Pure-stdlib glyph and SVG renderers; the Color model and ANSI/SVG constants — no terminal interaction |
terminal |
The high-level API (render, show, fits); terminal-size and NO_COLOR/tty logic |
output |
Output-format dispatch (render_bytes, save); the only module that imports Pillow (lazily, for the cuere[image] PNG extra) |
wallet |
Crypto-URI builders (BIP-21, BOLT11/LNURL/BOLT12, EIP-681) and the QR-alphanumeric optimize_uri |
rich |
The Rich renderable QRCode (imports rich; on demand) |
cli / __main__ |
The typer CLI (imports typer; on demand) |
errors |
The CuereError exception hierarchy |
Data flow¶
payload (str/bytes) ──► matrix.encode ──► QRMatrix (frozen, immutable)
(CLI/API input) (via segno) │
├─► render_matrix ──► terminal glyphs ──► stdout / str
├─► render_svg ──► SVG text ──► file / bytes
└─► render_bytes ──► PNG (Pillow) ──► file / bytes
- A payload and options enter through
terminal.render/show/fits, thecuere.rich.QRCoderenderable, or thecuereCLI. matrix.encodehands the payload to segno and wraps the result in a frozenQRMatrix(an immutable grid of booleans).- A renderer maps the matrix to terminal glyphs, an SVG, or — through the optional Pillow path — a PNG.
- The result is returned as a string/bytes, or written to a sink (stdout, a file, or a caller-provided writer).
Trust boundaries¶
- Input is data, not code. The payload is encoded into the QR matrix; cuere
never
evals, imports, or executes it. - The terminal boundary is explicit. Only the renderers emit characters to a
terminal. In
half/blockmodes the output is QR glyphs and spaces. Inansimode the only escape sequences are SGR color codes derived from the validateddark/lightcolor options — never from the payload — so a crafted payload cannot inject terminal escape sequences. See the threat model for the analysis. - No ambient authority. At runtime cuere opens no network connections and
reads no files except when the CLI is explicitly given
--input <file>. - Optional dependencies stay optional.
rich,typer, andPilloware imported lazily so the attack surface of a plainimport cuereis just the standard library plus segno.