Skip to main content

Fullbleed

Deterministic, self-contained HTML/CSS-to-PDF generation in Rust, with a Python-first CLI and Python engine bindings.

License: MIT.

  • Install: pip install fullbleed
  • Try: fullbleed init . && python report.py
  • Outputs: output/report.pdf
  • Deterministic + reproducible (--repro-record / --repro-check)
  • Agent-safe JSON schemas (--json-only, --schema)

Positioning

Fullbleed is a deterministic, offline-first document rendering engine for transactional/VDP pipelines (not a browser, not a hosted web-to-print SaaS).

HTML and CSS are used as a familiar DSL for layout, styling, and data placement in transactional documents.

This README is the canonical usage guide for:

  • fullbleed CLI (human workflows + machine/agent automation)
  • fullbleed Python bindings (PdfEngine, AssetBundle, batch APIs)

Additional focused references are in docs/:

  • docs/install-non-technical.md (step-by-step setup for non-technical users)
  • docs/css-coverage.md (validated CSS coverage, parity status, and active gaps)
  • docs/README.md
  • docs/engine.md
  • docs/performance-architecture.md
  • docs/performance-pass-2026-08-04.md
  • docs/python-api.md
  • docs/ui-accessibility.md
  • docs/cli.md
  • docs/pdf-templates.md

What You Get

  • No headless browser requirement for PDF generation.
  • Deterministic render pipeline with optional SHA256 output hashing.
  • Reproducibility workflow via --repro-record and --repro-check.
  • PDF 1.7 as the production-stable default target.
  • Rust-native PDF template composition for VDP/transactional overlays.
  • Native Rust image emission for overlay and finalized compose outputs (--emit-image) without external PDF raster runtime dependencies.
  • Feature-driven page-to-template binding with per-page deterministic compose plans.
  • Structured JSON result schemas for CI and AI agents.
  • Offline-first asset model with explicit remote opt-in.
  • Remote project template registry workflows (new list, new search, new remote).
  • Python-first extension surface for hackability and custom workflows.
  • Python render calls release the GIL while Rust rendering executes.
  • Ordered standard-library worker pools for batch rendering and selected internal workloads.
  • A deliberately small, license-audited Rust dependency graph and no required third-party Python runtime or build packages.

Concurrency Model

  • Python binding render methods release the GIL during Rust execution through the Stable ABI bridge.
  • Parallel batch APIs use Fullbleed's ordered standard-library worker pool (render_pdf_batch_parallel(...) and parallel-to-file variants).
  • The same bounded worker implementation serves selected internal hotspots such as table layout and JIT paint paths.
  • Do not assume every single-document render path will fully saturate all cores end-to-end.

Performance in 2.2

Fullbleed 2.2 retains exact TrueType glyph subsetting and adds compiled fixed-geometry variable-data binding. Across the five independent benchmark fixtures, PDFs are 95.5-97.3% smaller and ordinary warm rendering is 2.90x faster by geometric mean than released 2.0.0.

The new compile-once API freezes an immutable Q32.32 display document and can link it repeatedly without rerunning HTML parsing, selector matching, layout, pagination, or command planning. For identical untagged copies in one ordered PDF, CompiledDocument.render_pdf_batch(...) shares each source page's content stream across the copied page dictionaries. The measured 20-copy lane is 200.7x faster per page by geometric mean than the released 2.0.0 warm renderer; a 1,000-page stress run sustained 304,479-666,622 pages/s.

The 2.2 compiler includes a genuine fixed-geometry variable-data lane. A compiled invoice with six bound fields rendered 100,000 distinct records in a five-run median of 283.807 ms to memory (352,352 pages/s) and 295.999 ms directly to a flushed 88.1 MB PDF (337,839 pages/s). Including the one-time 4.168 ms compile gives 333,147 direct-file pages/s. The harness verified all 100,000 unique invoice IDs in page order, exact page count, resolved markers, deterministic bytes, and equal buffer/file SHA-256. Reproduce it with:

python tools/benchmark_fullbleed_vdp.py --records 100000 --repeats 5

Fixed-geometry slots may remain inside immutable page-space transforms and clips. The compiler captures that active coordinate-state program once and replays it in each compact record overlay; it does not rerun layout or clone the complete page display list.

The fixed-copy result remains scoped to identical content; the variable-data result is scoped to paint-only text whose geometry does not reflow. Neither is a claim that arbitrary new HTML or size-changing records render 200x faster. See docs/performance-pass-2026-08-04.md for measurements and docs/performance-architecture.md for the packed vector IR, typed-binding, virtual-linker, and shader roadmap.

Fullbleed 2.2.5 hardens the third compiler lane introduced in 2.2.4 for size-changing records: CompiledDocument.render_pdf_reflow_bindings(...). It parses and recovers the template DOM once and compiles encountered structural flow variants into guarded fixed-point display programs. Matching records bind directly into those programs; workers execute pre-shaped text/TJ paint slots, cached static PDF page segments, page-local Deflate, and one ordered linker. Explicit trusted structural slots use data-fb-bind-html="slot". A value that no compiled variant can safely place runs ordinary fixed-point layout once to add another variant.

On the independent 1,000-distinct-record case study, the 29-sample hot direct-file median was 216.160 ms: 4,626 records/s and 8,096 pages/s. The 168.995 ms best sample reached 5,917 records/s and 10,355 pages/s. It produced the exact 1,750-page 500/300/150/50 reflow distribution and verified all 24,900 markers. The throughput-tuned 6,870,320-byte PDF was deterministic across all samples. With the compact compression setting, compiled output was also byte-for-byte identical to ordinary rendering: 5,298,961 bytes and SHA-256 bb3c441313a08fb00d3bd15f23a567981f3bbbd550908e3a9fe7a07ca5d7f138. This is a hot compiled-variant result, not a claim for previously unseen structure. The first variant-discovery render measured 0.509 s (3,437 pages/s), and the fully cold job including setup, bindings, compilation, discovery, and write measured 0.588 s (2,975 pages/s). The independently observed hot-median speedup over the ordinary path was 43.8x.

Install

New to Python or setting up on a fresh machine? Start with docs/install-non-technical.md.

python -m pip install fullbleed

From a local wheel:

python -m pip install C:\path\to\fullbleed-2.2.5-cp310-abi3-win_amd64.whl

From a source checkout with Rust installed, no Python build package is needed:

python -m pip install --no-build-isolation --no-deps --editable .

To create deterministic release artifacts directly:

python build_backend/fullbleed_build_backend.py wheel --out dist
python build_backend/fullbleed_build_backend.py sdist --out dist

Platform artifact policy:

  • Linux wheels cover manylinux2014 on x86-64, x86, ARM64, ARMv7, s390x, and ppc64le, plus musllinux_1_2 on x86-64, x86, ARM64, and ARMv7.
  • Windows wheels cover x86-64, x86, and ARM64; macOS wheels cover Intel and Apple silicon.
  • The CPython stable ABI allows each platform wheel to support Python 3.10 through 3.14.
  • CI installs and exercises every built wheel on its target architecture, using native runners or QEMU as appropriate. The x86-64 manylinux wheel is additionally tested on every supported Python version before publication.

Verify command surface:

fullbleed --help
fullbleed capabilities --json
fullbleed doctor --json

60-Second Quick Start (Project Happy Path)

Initialize project scaffold:

fullbleed init .

fullbleed init now vendors Bootstrap (5.0.0) into vendor/css/bootstrap.min.css, vendors Bootstrap Icons (1.11.3) into vendor/icons/bootstrap-icons.svg, vendors inter into vendor/fonts/Inter-Variable.ttf, writes license notices (vendor/css/LICENSE.bootstrap.txt, vendor/icons/LICENSE.bootstrap-icons.txt, vendor/fonts/LICENSE.inter.txt), and seeds assets.lock.json with pinned hashes. The scaffolded report.py also runs a component mount smoke validation before main render and writes output/component_mount_validation.json (fails fast on missing glyphs, actual pagination overflow, or CSS miss signals). On current engines, render-time pagination is authoritative for overflow; conservative JIT placement bounds remain the compatibility fallback for older engines. Scaffolded components now include components/primitives.py with reusable layout/content helpers (Stack, Row, Text, table/list helpers, key/value rows, etc.). Each scaffolded project also includes SCAFFOLDING.md, which should be your first read before restructuring components.

Install additional project assets (defaults to ./vendor/... in project context):

fullbleed assets install inter --json

Bootstrap baseline note:

  • We target Bootstrap (5.0.0) as the default styling baseline for project workflows.
  • Re-run fullbleed assets install bootstrap --json only if you want to explicitly refresh/bootstrap-manage outside init.

Render using the scaffolded component pipeline:

python report.py

Expected artifacts from scaffolded report.py:

  • output/report.pdf
  • output/report_page1.png (or equivalent page preview from engine image APIs)
  • output/component_mount_validation.json
  • output/css_layers.json

Canonical static PDF reference:

python examples/canonical_reference/report.py

examples/canonical_reference/ is the exhaustive scaffold-shaped reference for component composition, layered CSS, bundled fonts/SVG, inline SVG, raster data URIs, linked and standalone HTML artifacts, PDF output, PNG previews, and validation reports.

Project Bootstrap Templates (fullbleed new)

Use local starters:

fullbleed new local invoice ./my-invoice
fullbleed new local statement ./my-statement
fullbleed new local accessible ./my-accessible-doc
fullbleed new local reference ./my-reference-doc

Discover remote starters from registry:

fullbleed new list --json
fullbleed new search i9 --tag vdp --json
fullbleed new remote i9-stamped-vdp ./i9-job --json

fullbleed new local accessible is the verbose accessibility-first starter and demonstrates the fullbleed.accessibility runtime surface (engine verifier, PMR, PDF/UA-targeted seed checks, and non-visual trace artifacts). fullbleed new local reference vendors the canonical static PDF reference shape as a scaffolded project with component layers, assets, PDF/PNG outputs, page data, and validation reports.

Optional registry override (for private/canary registries):

fullbleed new list --registry https://example.com/manifest.json --json

or:

set FULLBLEED_TEMPLATE_REGISTRY=https://example.com/manifest.json
fullbleed new search statement --json

Scaffold-First Workflow (Recommended)

fullbleed init is designed for component-first authoring rather than a single large HTML template.

Typical scaffold layout:

.
|-- SCAFFOLDING.md
|-- COMPLIANCE.md
|-- report.py
|-- components/
|   |-- fb_ui.py
|   |-- primitives.py
|   |-- header.py
|   |-- body.py
|   |-- footer.py
|   `-- styles/
|       |-- primitives.css
|       |-- header.css
|       |-- body.css
|       `-- footer.css
|-- styles/
|   |-- tokens.css
|   `-- report.css
|-- vendor/
|   |-- css/
|   |-- fonts/
|   `-- icons/
`-- output/

Best-practice authoring model:

  1. Read SCAFFOLDING.md first for project conventions.
  2. Keep composition and data loading in report.py.
  3. Keep reusable component building blocks in components/primitives.py.
  4. Keep section markup in components/header.py, components/body.py, components/footer.py.
  5. Keep component-local styles in components/styles/*.css.
  6. Keep page tokens/composition styles in styles/tokens.css and styles/report.css.

Recommended CSS layer order:

  1. styles/tokens.css
  2. components/styles/primitives.css
  3. components/styles/header.css
  4. components/styles/body.css
  5. components/styles/footer.css
  6. styles/report.css

Recommended iteration loop:

  1. Edit data loading + component props in report.py.
  2. Edit component markup in components/*.py.
  3. Edit styles in components/styles/*.css and styles/*.css.
  4. Run python report.py.
  5. Review output/report_page1.png, output/component_mount_validation.json, and output/css_layers.json.

Optional scaffold diagnostics:

  • FULLBLEED_DEBUG=1 to emit JIT traces.
  • FULLBLEED_PERF=1 to emit perf traces.
  • FULLBLEED_EMIT_PAGE_DATA=1 to persist page data JSON.
  • FULLBLEED_IMAGE_DPI=144 (or higher) for preview resolution.
  • FULLBLEED_VALIDATE_STRICT=1 for stricter validation gates in CI.

One-off Quick Render (No Project Scaffold)

Render inline HTML/CSS with reproducibility artifacts:

fullbleed --json render \
  --html-str "<html><body><h1>Hello</h1></body></html>" \
  --css-str "body{font-family:sans-serif}" \
  --emit-manifest build/render.manifest.json \
  --emit-jit build/render.jit.jsonl \
  --emit-perf build/render.perf.jsonl \
  --deterministic-hash build/render.sha256 \
  --repro-record build/render.repro.json \
  --out output/hello.pdf

--deterministic-hash writes the output PDF SHA-256 by default; when --emit-image is enabled, it writes an artifact-set digest (fullbleed.artifact_digest.v1) over PDF SHA-256 plus ordered page-image SHA-256 hashes. JSON outputs expose outputs.deterministic_hash_mode (pdf_only or artifact_set_v1), with outputs.artifact_sha256 and outputs.image_sha256 when images are emitted.

Re-run and enforce reproducibility against a stored record:

fullbleed --json render \
  --html templates/report.html \
  --css templates/report.css \
  --repro-check build/render.repro.json \
  --out output/report.rerun.pdf

Generate PNG page artifacts from an existing validation render:

fullbleed --json verify \
  --html templates/report.html \
  --css templates/report.css \
  --emit-pdf output/report.verify.pdf \
  --emit-image output/report_verify_pages \
  --image-dpi 200

Compile-only plan (no render):

fullbleed --json plan \
  --html templates/report.html \
  --css templates/report.css

Template compose planning (no finalize write):

fullbleed --json plan \
  --html templates/overlay.html \
  --css templates/overlay.css \
  --template-binding config/template_binding.json \
  --templates config/template_catalog.json \
  --emit-compose-plan output/compose_plan.json

PDF Template Composition (VDP / Transactional)

When overlaying variable data onto a source PDF, use the built-in Rust template compose path.

Minimal CLI auto-compose flow:

fullbleed --json render \
  --html templates/overlay.html \
  --css templates/overlay.css \
  --asset templates/source.pdf --asset-kind pdf --asset-name source-template \
  --template-binding config/template_binding.json \
  --templates config/template_catalog.json \
  --out output/composed.pdf

Compose image semantics:

  • In template auto-compose mode, --emit-image PNGs are rasterized from finalized composed pages and report outputs.image_mode=composed_pdf.
  • In non-compose render/verify runs, --emit-image reports outputs.image_mode=overlay_document.

Minimal template_binding example:

{
  "default_template_id": "source-template",
  "feature_prefix": "fb.feature.",
  "by_feature": {
    "front": "source-template",
    "back_blank": "source-template"
  }
}

Python API compose flow:

import fullbleed

engine = fullbleed.PdfEngine(template_binding=binding_spec)
overlay_bytes, _page_data, _bindings = engine.render_pdf_with_page_data_and_template_bindings(html, css)
open("output/overlay.pdf", "wb").write(overlay_bytes)
plan_result = engine.plan_template_compose(
    html,
    css,
    [("source-template", "templates/source.pdf")],
    0.0,
    0.0,
)
plan = [
    (
        row["template_id"],
        row["template_page"],
        row["overlay_page"],
        row["dx"],
        row["dy"],
    )
    for row in plan_result["plan"]
]
fullbleed.finalize_compose_pdf(
    [("source-template", "templates/source.pdf")],
    plan,
    "output/overlay.pdf",
    "output/composed.pdf",
    annotation_mode="link_only",  # optional: link_only | none | carry_widgets
)

See docs/pdf-templates.md and examples/template-flagging-smoke/ for full production examples.

CLI Command Map

Command Purpose JSON Schema
render Render HTML/CSS to PDF with optional PNG page artifacts fullbleed.render_result.v1
verify Validation render path with optional PDF and PNG emits fullbleed.verify_result.v1
plan Compile/normalize inputs into manifest + warnings fullbleed.plan_result.v1
run Render using Python module/file engine factory fullbleed.run_result.v1
inspect pdf Inspect PDF metadata and composition compatibility fullbleed.inspect_pdf.v1
inspect pdf-batch Inspect multiple PDFs with per-file status fullbleed.inspect_pdf_batch.v1
inspect templates Inspect template catalog metadata/compatibility fullbleed.inspect_templates.v1
compliance License/compliance report for legal/procurement fullbleed.compliance.v1
debug-perf Summarize perf JSONL logs fullbleed.debug_perf.v1
debug-jit Filter/inspect JIT JSONL logs fullbleed.debug_jit.v1
doctor Runtime capability and health checks fullbleed.doctor.v1
capabilities Machine-readable command/engine capabilities fullbleed.capabilities.v1
assets list Installed and optional remote packages fullbleed.assets_list.v1
assets info Package details + hashes/sizes fullbleed.assets_info.v1
assets install Install builtin/remote package fullbleed.assets_install.v1
assets verify Validate package and optional lock constraints fullbleed.assets_verify.v1
assets lock Write/update assets.lock.json fullbleed.assets_lock.v1
cache dir Cache location fullbleed.cache_dir.v1
cache prune Remove old cached packages fullbleed.cache_prune.v1
init Initialize project scaffold fullbleed.init.v1
new Create starter template files or query/install remote templates fullbleed.new_template.v1, fullbleed.new_list.v1, fullbleed.new_search.v1, fullbleed.new_remote.v1

Schema discovery for any command/subcommand:

fullbleed --schema render
fullbleed --schema assets verify
fullbleed --schema inspect pdf
fullbleed --schema inspect templates

CLI Flags That Matter Most

Global machine flags:

  • --json: structured result payload to stdout
  • --json-only: implies --json and --no-prompts
  • --schema: emit schema definition and exit
  • --no-prompts: disable interactive prompts
  • --config: load defaults from a config file
  • --log-level error|warn|info|debug: control CLI log verbosity
  • --no-color: disable ANSI color output
  • --version: print CLI version and exit

Render/verify/plan key flags:

  • Inputs: --html, --html-str, --css, --css-str --html accepts .svg files for direct SVG-document rendering; --html-str accepts inline SVG markup.
  • Page setup: --page-size, --page-width, --page-height, --margin, --page-margins
  • Engine toggles: --reuse-xobjects, --svg-form-xobjects, --svg-raster-fallback, --shape-text, --unicode-support, --unicode-metrics
  • PDF/compliance: --pdf-version, --pdf-profile, --color-space, --document-lang, --document-title Stable default is --pdf-version 1.7 for shipping workflows. Profile targets: none, pdfa1a, pdfa1b, pdfa2a, pdfa2b, pdfa2u, pdfa3a, pdfa3b, pdfa3u, pdfa4, pdfa4e, pdfa4f, pdfx4, pdfua1, pdfua2, pdfvt1, wtpdf1r, wtpdf1a, tagged. Aliases: a, ua, vt, wt1r, wt1a, pdf/a, pdf/ua, pdf/vt. Output intent metadata (--output-intent-identifier|--output-intent-info|--output-intent-components) requires --output-intent-icc. Run python tools/validate_pdf_profiles.py --download-verapdf --install-pdf-oxide --strict-external to regenerate profile specimens, capture inspect/JIT evidence, replay deterministic hashes, validate PDF/A and PDF/UA with veraPDF, and validate PDF/X-4 with pdf_oxide. WTPDF profiles are validated with veraPDF wt1r/wt1a and include PDF Declaration evidence. pdfa4f emits and checks an associated EmbeddedFiles name tree. pdfvt1 also emits and checks a parsed DPart graph (DPartRoot, DPartRootNode, one-level NodeNameList, leaf page range, and page /DPart references), including a supplemental multipage specimen for /Start and /End, reported as granular booleans plus pdfvt_dpart_graph_valid; use a dedicated PDF/VT preflight tool for third-party PDF/VT certification, or wire one into the same harness with --pdfvt-cmd "tool --input {pdf}" --require-dedicated-pdfvt.
  • Watermarking: --watermark-text, --watermark-html, --watermark-image, --watermark-layer, --watermark-semantics, --watermark-opacity, --watermark-rotation
  • Artifacts: --emit-jit, --emit-perf, --emit-glyph-report, --emit-page-data, --emit-compose-plan, --emit-image, --image-dpi, --deterministic-hash
  • Assets: --asset, --asset-kind, --asset-name, --asset-trusted, --allow-remote-assets
  • Profiles: --profile dev|preflight|prod
  • Fail policy: --fail-on overflow|missing-glyphs|font-subst|budget
  • Fallback policy: --allow-fallbacks (keeps fallback diagnostics, but does not fail missing-glyphs / font-subst gates)
  • Reproducibility: --repro-record <path>, --repro-check <path>
  • Budget thresholds: --budget-max-pages, --budget-max-bytes, --budget-max-ms
  • Release gates: doctor --strict, compliance --strict --max-audit-age-days <n>

SVG Workflows

Fullbleed supports SVG in three practical CLI paths:

  • Direct SVG document render via --html <file.svg>
  • Inline SVG markup via --html-str "<svg ...>...</svg>"
  • Referenced SVG assets via --asset <file.svg> (kind auto-infers to svg)

Standalone SVG file to PDF:

fullbleed --json render \
  --html artwork/badge.svg \
  --out output/badge.pdf

Inline SVG markup to PDF:

fullbleed --json render \
  --html-str "<svg xmlns='http://www.w3.org/2000/svg' width='200' height='80'><rect width='200' height='80' fill='#0d6efd'/><text x='16' y='48' fill='white'>Hello SVG</text></svg>" \
  --out output/inline-svg.pdf

HTML template with explicit SVG asset registration:

fullbleed --json render \
  --html templates/report.html \
  --css templates/report.css \
  --asset assets/logo.svg \
  --asset-kind svg \
  --out output/report.pdf

SVG render behavior flags:

  • --svg-form-xobjects / --no-svg-form-xobjects
  • --svg-raster-fallback / --no-svg-raster-fallback

Distributed Python wheels enable the svg_raster engine feature, so --svg-raster-fallback can rasterize unsupported SVG constructs such as SVG text, filters, masks, and foreignObject into deterministic image content. Custom source builds must include --features python,svg_raster to advertise and use that fallback path.

Machine discovery:

fullbleed capabilities --json

Inspect the svg object in fullbleed.capabilities.v1 for SVG support metadata. The engine object also reports compiled-document/reflow availability and supported per-call compression modes. It reports the compiled svg_raster build feature plus a feature matrix for native-vector SVG, raster-fallback-required SVG, and unsupported/known-loss SVG features.

Image Support Matrix

Launch-safe image claims:

  • Supported direct raster inputs: PNG and JPEG.
  • SVG is handled by the SVG pipeline described above, with native-vector output where supported and raster fallback for fallback-only features when svg_raster is enabled.
  • Supported references include filesystem paths, registered bundle assets, file/data URIs, <img>, CSS background-image: url(...), list-style images, and watermark images.
  • Unsupported or not launch-claimed as direct inputs: WebP, GIF, TIFF, AVIF, BMP, animated images, <picture>, srcset, sizes, density descriptors, and browser-style responsive image selection.
  • For deterministic builds, prefer vendored local assets or registered AssetBundle inputs; remote assets must be explicitly allowed.

Per-Page Templates (page_1, page_2, page_n)

Fullbleed uses ordered page templates internally. In docs, this is easiest to think of as:

  • page_1: first page template
  • page_2: second page template
  • page_n: repeating template for later pages

Configuration mapping:

  • CLI --page-margins keys: 1, 2, ... and optional "n" (or "each" alias).
  • Python PdfEngine(page_margins=...): same key model.
  • Missing numeric pages fall back to the base margin.
  • The last configured template repeats for remaining pages.

Minimal CLI example:

{
  "1": {"top": "12mm", "right": "12mm", "bottom": "12mm", "left": "12mm"},
  "2": {"top": "24mm", "right": "12mm", "bottom": "12mm", "left": "12mm"},
  "n": {"top": "30mm", "right": "12mm", "bottom": "12mm", "left": "12mm"}
}
fullbleed --json render \
  --html templates/report.html \
  --css templates/report.css \
  --page-margins page_margins.json \
  --header-each "Statement continued - Page {page} of {pages}" \
  --out output/report.pdf

Minimal Python example:

import fullbleed

engine = fullbleed.PdfEngine(
    page_width="8.5in",
    page_height="11in",
    margin="12mm",
    page_margins={
        1: {"top": "12mm", "right": "12mm", "bottom": "12mm", "left": "12mm"},  # page_1
        2: {"top": "24mm", "right": "12mm", "bottom": "12mm", "left": "12mm"},  # page_2
        "n": {"top": "30mm", "right": "12mm", "bottom": "12mm", "left": "12mm"} # page_n
    },
    header_first="Account Statement",
    header_each="Statement continued - Page {page} of {pages}",
    footer_last="Final page",
)

Note:

  • CLI currently exposes --header-each / --footer-each (and --header-html-each / --footer-html-each).
  • For first/last header/footer variants (header_first, header_last, footer_first, footer_last), use the Python API.

Asset Workflow (CLI)

List installed + available packages:

fullbleed assets list --available --json

Install builtin assets:

fullbleed assets install bootstrap
fullbleed assets install bootstrap-icons
# `@bootstrap` / `@bootstrap-icons` are also supported aliases

PowerShell note:

  • Quote @ aliases (for example "@bootstrap") to avoid shell parsing surprises.

Install remote asset package:

fullbleed assets install inter

Install broad Unicode fallback package (larger font payload):

fullbleed assets install noto-sans

Install to a custom vendor directory:

fullbleed assets install bootstrap --vendor ./vendor

Install to global cache:

fullbleed assets install inter --global

Install common barcode fonts (license-safe defaults):

fullbleed assets install libre-barcode-128
fullbleed assets install libre-barcode-39
fullbleed assets install libre-barcode-ean13-text

Verify against lock file with strict failure:

fullbleed assets verify inter --lock --strict --json

Preview cache cleanup without deleting files:

fullbleed cache prune --max-age-days 30 --dry-run --json

Notes:

  • Builtin packages accept both plain and @ references (bootstrap == @bootstrap, bootstrap-icons == @bootstrap-icons, noto-sans == @noto-sans).
  • noto-sans is available as a builtin fallback package, but it is intentionally larger than inter; use it when your document requires broader glyph coverage.
  • Project installs default to ./vendor/ when project markers are present (assets.lock.json, report.py, or fullbleed.toml in CWD).
  • If no project markers are found, assets install defaults to global cache unless --vendor is explicitly set.
  • Do not hardcode cache paths like %LOCALAPPDATA%/fullbleed/cache/...; use assets install --json and consume installed_to.
  • Installed assets include license files in typed vendor directories (for example vendor/fonts/, vendor/css/).
  • assets lock --add is currently aimed at builtin package additions.
  • Barcode packages in the remote registry are currently OFL-1.1 families from Google Fonts (Libre Barcode).
  • USPS IMB fonts are not currently auto-installable via assets install; use local vetted font files and track licensing separately.

Bootstrap Vendoring

Bootstrap builtin package details:

  • Package: bootstrap (alias: @bootstrap)
  • Bundled version: 5.0.0
  • Asset kind: CSS (bootstrap.min.css)
  • Default install location: vendor/css/bootstrap.min.css (project mode)
  • License: MIT
  • License source: https://raw.githubusercontent.com/twbs/bootstrap/v5.0.0/LICENSE

Bootstrap Icons builtin package details:

  • Package: bootstrap-icons (alias: @bootstrap-icons)
  • Bundled version: 1.11.3
  • Asset kind: SVG sprite (bootstrap-icons.svg)
  • Default install location: vendor/icons/bootstrap-icons.svg (project mode)
  • License: MIT
  • License source: https://raw.githubusercontent.com/twbs/icons/v1.11.3/LICENSE

Bootstrap notes:

  • Bootstrap is vendored and installable through the asset pipeline.
  • Bootstrap CSS is consumed as an explicit local asset (--asset @bootstrap or AssetBundle); external HTML <link rel="stylesheet"> is not an execution path.
  • Bootstrap preflight examples remain useful smoke examples, but they are not the canonical source of CSS parity claims.

Validated CSS Coverage

For the full, maintained coverage statement, see docs/css-coverage.md.

Summary as of May 19, 2026:

  • Tracked CSS modules: 22
  • Module state: 22/22 in_progress
  • Full CSS fixture lane: 86/86 fixtures passing with 603 assertion/paint checks
  • Parity status check: green (tools/generate_css_parity_status.py --check --json)
  • Canonical validation artifact: _css_working/css_parity_status.json
  • Canonical validation artifact: _css_working/tmp/fixture_full_latest.json
  • Canonical validation artifact: _css_working/css_broad_coverage_sprint_s14.md

The complete pinned independent Wheel265 gate closed on August 9, 2026 with 1,642 PASS, 0 FAIL, and 20 REFERENCE-DISPUTED across 1,662 fixtures. That is strict 100% parity for every adjudicable fixture in this named corpus; disputed references remain visible and are not relabeled as implementation passes. Broader web-platform coverage remains bounded by the module and known-gap contract in docs/css-coverage.md.

Flow/reflow hardening validated on August 5, 2026 adds fixed-height block, one-column grid, and column-flex continuation slicing; avoids content duplication; retains empty styled captions inside avoided figures; preserves display: contents grid paint phase; and keeps positioned containing blocks atomic. The independent review's targeted 18-case regression cluster passes 18/18 (13 pixel-exact, maximum above-floor difference 0.97030199%). This targeted diagnostic does not replace the full external-corpus report.

Current validated behavior includes first-class parser -> evaluator -> calculator -> layout/paint coverage across broad static-document CSS domains (values math, layout primitives, pagination/fragmentation baselines, transforms phase-1, gradient/effects subsets including color-first and interleaved-color filter: drop-shadow(...) with computed lengths, modern rgb() shadow colors with mm lengths, duplicate drop-shadow(...) color rejection, empty optional filter-function defaults, explicit/currentColor backdrop-filter: drop-shadow(...) raster paint, strict box-shadow length/color grammar with modern rgb() plus mm paint coverage, softened blurred inset edge paint, and directional inset offset edge paint, overflow-gated text-overflow: ellipsis, physical min/max box constraints, horizontal-tb RTL direction inline inset/margin/padding/border mapping, vertical writing-mode direction: rtl inline inset remapping, vertical-rl logical sizing/insets/margin/padding/border/min-max constraints, vertical-lr logical sizing/min-max/insets/margin/padding/border remapping, basic vertical text columns with vertical-rl leftward and vertical-lr rightward line progression, and deterministic diagnostics).

Known gap categories are explicitly tracked for the final parity push:

  • remaining filter/backdrop-filter function breadth beyond current subset, including SVG url() filters, advanced drop-shadow() forms beyond the current flexible-color-order foreground and baseline backdrop coverage, and PDF-native foreground filters
  • advanced clip-path grammar beyond the current basic-shape subset, including SVG clip sources, SVG-specific geometry boxes, and deeper edge grammar
  • plus-lighter PDF-native parity and deeper nested compositing/isolation breadth
  • deeper blurred inset shadow edge fidelity
  • remaining multi-layer background image edge semantics beyond the current sized gradient-layer repeat-x/space/round and PNG url(...) explicit-size/auto-auto-intrinsic/negative-size-invalid/contain/cover/auto-dimension-size/single-value-size/alpha-stack/default-repeat-repeat/repeat-y/repeat/repeat-no-repeat/no-repeat-repeat/space-space/round-round/round-space/space-round/round-repeat/round-no-repeat/no-repeat-round/no-repeat-space/space-no-repeat/repeat-space/repeat-round/space-repeat/logical-repeat-aliases/multi-layer-repeat-axis/background-list-repetition/percentage-position/edge-offset-position/logical-position-aliases/shorthand-position-size-repeat/content-box-origin-clip/multi-layer-origin-clip/background-blend-normal/background-blend-multiply/screen-mode/overlay-mode/exclusion-mode/hard-light-mode/darken-mode/lighten-mode/color-dodge-mode/color-burn-mode/soft-light-mode/hue-mode/saturation-mode/color-mode/luminosity-mode/plus-lighter-mode/list-repetition/truncation/raster-blend/raster-layer-mapping/mixed-raster-gradient-mapping/mixed-gradient-raster-mapping subset, including broader mixed raster stack combinations
  • table layout edge semantics hardening beyond the current fixed-layout width-hint, auto-width, caption-side placement, and invalid caption-side inheritance lanes
  • full vertical text/layout flow beyond the current vertical static-layout and basic wrapped text-column baseline

run Command (Python Factory Interop)

run lets the CLI use a Python-created engine instance.

report.py:

import fullbleed

def create_engine():
    return fullbleed.PdfEngine(page_width="8.5in", page_height="11in", margin="0.5in")

CLI invocation:

fullbleed --json run report:create_engine \
  --html-str "<h1>From run</h1>" \
  --css templates/report.css \
  --out output/report.pdf

Entrypoint formats:

  • module_name:factory_or_engine
  • path/to/file.py:factory_or_engine

Python API Quick Start

import fullbleed

engine = fullbleed.PdfEngine(
    page_width="8.5in",
    page_height="11in",
    margin="0.5in",
    pdf_version="1.7",
    pdf_profile="none",
    color_space="rgb",
)

html = "<html><body><h1>Invoice</h1><p>Hello.</p></body></html>"
css = "body { font-family: sans-serif; }"

bytes_written = engine.render_pdf_to_file(html, css, "output/invoice.pdf")
print(bytes_written)

Register local assets with AssetBundle:

import fullbleed

bundle = fullbleed.AssetBundle()
bundle.add_file("vendor/css/bootstrap.min.css", "css", name="bootstrap")
bundle.add_file("vendor/fonts/Inter-Variable.ttf", "font", name="inter")

engine = fullbleed.PdfEngine(page_width="8.5in", page_height="11in")
engine.register_bundle(bundle)
engine.render_pdf_to_file("<h1>Styled</h1>", "", "output/styled.pdf")

Python API Signatures (Runtime-Verified)

These signatures are verified from the installed package via inspect.signature(...).

PdfEngine constructor:

PdfEngine(
    page_width=None,
    page_height=None,
    margin=None,
    page_margins=None,
    font_dirs=None,
    font_files=None,
    reuse_xobjects=True,
    svg_form_xobjects=False,
    svg_raster_fallback=False,
    unicode_support=True,
    shape_text=True,
    unicode_metrics=True,
    pdf_version=None,
    pdf_profile=None,
    output_intent_icc=None,
    output_intent_identifier=None,
    output_intent_info=None,
    output_intent_components=None,
    color_space=None,
    document_lang=None,
    document_title=None,
    header_first=None,
    header_each=None,
    header_last=None,
    header_x=None,
    header_y_from_top=None,
    header_font_name=None,
    header_font_size=None,
    header_color=None,
    header_html_first=None,
    header_html_each=None,
    header_html_last=None,
    header_html_x=None,
    header_html_y_from_top=None,
    header_html_width=None,
    header_html_height=None,
    footer_first=None,
    footer_each=None,
    footer_last=None,
    footer_x=None,
    footer_y_from_bottom=None,
    footer_font_name=None,
    footer_font_size=None,
    footer_color=None,
    watermark=None,
    watermark_text=None,
    watermark_html=None,
    watermark_image=None,
    watermark_layer="overlay",
    watermark_semantics="artifact",
    watermark_opacity=0.15,
    watermark_rotation=0.0,
    watermark_font_name=None,
    watermark_font_size=None,
    watermark_color=None,
    paginated_context=None,
    jit_mode=None,
    debug=False,
    debug_out=None,
    perf=False,
    perf_out=None,
)

Module exports:

  • PdfEngine
  • CompiledDocument
  • CompiledFlowCompression
  • AssetBundle
  • Asset
  • AssetKind
  • WatermarkSpec(kind, value, layer='overlay', semantics=None, opacity=0.15, rotation_deg=0.0, font_name=None, font_size=None, color=None)
  • concat_css(parts)
  • vendored_asset(source, kind, name=None, trusted=False, remote=False)
  • inspect_pdf(path)
  • inspect_template_catalog(templates)
  • finalize_stamp_pdf(template, overlay, out, page_map=None, dx=0.0, dy=0.0)
  • finalize_compose_pdf(templates, plan, overlay, out, annotation_mode='link_only')
  • fetch_asset(url)

PdfEngine methods:

Method Return shape
register_bundle(bundle) None
compile_pdf(html, css) CompiledDocument
render_pdf(html, css, deterministic_hash=None) bytes
render_pdf_to_file(html, css, path, deterministic_hash=None) int (bytes written)
render_image_pages(html, css, dpi=150) list[bytes]
render_image_pages_to_dir(html, css, out_dir, dpi=150, stem=None) list[str]
render_finalized_pdf_image_pages(pdf_path, dpi=150) list[bytes]
render_finalized_pdf_image_pages_to_dir(pdf_path, out_dir, dpi=150, stem=None) list[str]
render_pdf_with_glyph_report(html, css) (bytes, list)
render_pdf_with_page_data(html, css) (bytes, page_data_or_none)
render_pdf_with_page_data_and_glyph_report(html, css) (bytes, page_data_or_none, glyph_report_list)
render_pdf_with_page_data_and_template_bindings(html, css) (bytes, page_data_or_none, template_bindings_or_none)
render_pdf_with_page_data_and_template_bindings_and_glyph_report(html, css) (bytes, page_data_or_none, template_bindings_or_none, glyph_report_list)
plan_template_compose(html, css, templates, dx=0.0, dy=0.0) dict
render_pdf_batch(html_list, css, deterministic_hash=None) bytes
render_pdf_batch_parallel(html_list, css, deterministic_hash=None) bytes
render_pdf_batch_to_file(html_list, css, path, deterministic_hash=None) int
render_pdf_batch_to_file_parallel(html_list, css, path, deterministic_hash=None) int
render_pdf_batch_to_file_parallel_with_page_data(html_list, css, path, deterministic_hash=None) (bytes_written, page_data_list)
render_pdf_batch_with_css(jobs, deterministic_hash=None) bytes
render_pdf_batch_with_css_to_file(jobs, path, deterministic_hash=None) int

CompiledDocument methods:

Method Return shape
stats() dict
render_pdf(deterministic_hash=None) bytes
render_pdf_to_file(path, deterministic_hash=None) int
render_pdf_batch(copies, deterministic_hash=None) bytes
render_pdf_bindings(bindings, deterministic_hash=None) bytes
render_pdf_bindings_to_file(bindings, path, deterministic_hash=None) int
render_pdf_reflow_bindings(bindings, deterministic_hash=None, *, compression="throughput") bytes
render_pdf_reflow_bindings_to_file(bindings, path, deterministic_hash=None, *, compression="throughput") int

The compiled lane runs parsing/layout once. render_pdf_batch virtualizes identical untagged page content. The fixed binding methods accept columnar dict[str, list[str]] data and emit distinct fixed-geometry text overlays per record while sharing static paint. They require exact slot keys, equal non-zero column lengths, page-local WinAnsi-compatible text, and an untagged profile; bound values do not trigger reflow.

The reflow binding methods use the same exact-column contract but execute the compiled parsed-DOM program. {{slot}} values are literal text and may reshape, wrap, resize blocks, and change page counts. Empty elements can opt into trusted generated markup with data-fb-bind-html="slot"; those values replace the element's children. One DOM is reused per native worker and record output is linked in input order through a bounded queue. Structural slot values are parsed as trusted markup: sanitize untrusted input or use scalar {{slot}} bindings, which remain literal text. Choose CompiledFlowCompression.Throughput (default) or CompiledFlowCompression.Compact per render; modes can be mixed safely in one process. See docs/python-api.md for the trust boundary and current limitations.

When deterministic_hash is set, engine writes PDF SHA-256 to the provided file path.

AssetBundle methods:

  • add_file(path, kind, name=None, trusted=False, remote=False)
  • add(asset)
  • assets_info()
  • css()

Python Examples (Smoke-Checked)

Canonical scaffold reference:

python examples/canonical_reference/report.py

Text watermark + diagnostics:

import fullbleed

engine = fullbleed.PdfEngine(
    page_width="8.5in",
    page_height="11in",
    margin="0.5in",
    pdf_version="1.7",
    watermark_text="INTERNAL",
    watermark_layer="overlay",
    watermark_semantics="artifact",
    watermark_opacity=0.12,
    watermark_rotation=-32.0,
    debug=True,
    debug_out="build/invoice.jit.jsonl",
    perf=True,
    perf_out="build/invoice.perf.jsonl",
)

html = "<h1>Invoice</h1><p>Status: Ready</p>"
css = "h1{margin:0 0 8px 0} p{margin:0}"

written = engine.render_pdf_to_file(html, css, "output/invoice_watermarked.pdf")
print("bytes:", written)

Batch render + glyph/page-data checks:

import fullbleed

engine = fullbleed.PdfEngine(page_width="8.5in", page_height="11in", margin="0.5in")

jobs = [
    ("<h1>Batch A</h1><p>Alpha</p>", "h1{color:#0d6efd}"),
    ("<h1>Batch B</h1><p>Beta</p>", "h1{color:#198754}"),
]

written = engine.render_pdf_batch_with_css_to_file(jobs, "output/batch.pdf")
print("batch bytes:", written)

pdf_bytes, glyph_report = engine.render_pdf_with_glyph_report("<p>Hello</p>", "")
print("glyph entries:", len(glyph_report))

pdf_bytes, page_data = engine.render_pdf_with_page_data("<p>Hello</p>", "")
print("page data available:", page_data is not None)

Transactional Header/Footer + Totals

Minimal, self-contained Python example (no external template files) showing:

  • Continued headers on page 2+.
  • Per-page subtotal footer expansion via {sum:items.amount}.
  • Final-page grand total footer expansion via {total:items.amount}.
  • Structured page_data totals for automation and reconciliation checks.
from pathlib import Path
import fullbleed

rows = []
for i in range(1, 121):  # enough rows to force multiple pages
    amount = 10.00 + ((i * 7) % 23) + 0.25
    rows.append(
        f'<tr data-fb="items.amount={amount:.2f}">'
        f"<td>2026-01-{(i % 28) + 1:02d}</td>"
        f"<td>Txn {i:03d}</td>"
        f'<td class="num">${amount:.2f}</td>'
        "</tr>"
    )

html = f"""<!doctype html>
<html>
<body>
  <h1>Monthly Statement</h1>
  <table>
    <thead>
      <tr><th>Date</th><th>Description</th><th class="num">Amount</th></tr>
    </thead>
    <tbody>
      {''.join(rows)}
    </tbody>
  </table>
</body>
</html>
"""

css = """
body { font-family: sans-serif; font-size: 10pt; color: #111; }
h1 { margin: 0 0 8pt 0; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 4pt; border-bottom: 1pt solid #e1e1e1; }
thead th { background: #f3f6fa; text-transform: uppercase; font-size: 9pt; }
.num { text-align: right; }
"""

engine = fullbleed.PdfEngine(
    page_width="8.5in",
    page_height="11in",
    margin="12mm",
    page_margins={
        1: {"top": "12mm", "right": "12mm", "bottom": "12mm", "left": "12mm"},
        2: {"top": "28mm", "right": "12mm", "bottom": "12mm", "left": "12mm"},
        "n": {"top": "28mm", "right": "12mm", "bottom": "12mm", "left": "12mm"},
    },
    header_html_each=(
        '<div style="display:flex;justify-content:space-between;border-bottom:1pt solid #d9d9d9;">'
        '<div style="font-weight:bold;">Acme Ledger</div>'
        '<div style="font-size:9pt;color:#444;">Statement Continued - Page {page} of {pages}</div>'
        "</div>"
    ),
    header_html_x="12mm",
    header_html_y_from_top="6mm",
    header_html_width="186mm",
    header_html_height="10mm",
    paginated_context={"items.amount": "sum"},
    footer_each="Subtotal (Page {page}): ${sum:items.amount}",
    footer_last="Grand Total: ${total:items.amount}",
    footer_x="12mm",
    footer_y_from_bottom="8mm",
)

pdf_bytes, page_data = engine.render_pdf_with_page_data(html, css)
Path("output_transactional_minimal.pdf").write_bytes(pdf_bytes)

assert page_data["page_count"] >= 2
assert page_data["totals"]["items.amount"]["value"] == sum(
    p["items.amount"]["value"] for p in page_data["pages"]
)
print("Wrote output_transactional_minimal.pdf")
print("Page count:", page_data["page_count"])
print("Grand total:", page_data["totals"]["items.amount"]["formatted"])

API note:

  • For transactional running totals (paginated_context) and HTML header/footer placement (header_html_*, footer_html_*), use the Python PdfEngine API path.
  • The CLI currently exposes direct text header/footer flags (--header-each, --footer-each) for simpler cases.

CLI watermark parity example:

fullbleed --json render \
  --html-str "<h1>Watermark probe</h1><p>hello</p>" \
  --css-str "body{font-family:sans-serif}" \
  --watermark-text "INTERNAL" \
  --watermark-layer overlay \
  --watermark-opacity 0.12 \
  --watermark-rotation -32 \
  --out output/watermark_probe.pdf

Reference-Image Parity Workflow (Practical)

When targeting a design reference image (for example reference image exports), this loop has worked well:

  1. Start from fullbleed init so CSS/font/icon baselines are vendored and pinned.
  2. For scaffolded projects, run python report.py and set FULLBLEED_IMAGE_DPI as needed for sharper previews.
  3. For direct CLI template rendering, register assets through the CLI (--asset ...) or AssetBundle.
  4. Iterate with image artifacts enabled:
fullbleed --json render \
  --profile preflight \
  --html templates/invoice.html \
  --css templates/invoice.css \
  --asset vendor/css/bootstrap.min.css --asset-kind css --asset-name bootstrap \
  --asset vendor/icons/bootstrap-icons.svg --asset-kind svg --asset-name bootstrap-icons \
  --asset vendor/fonts/Inter-Variable.ttf --asset-kind font --asset-name inter \
  --emit-image output/pages_png \
  --emit-jit output/render.jit.jsonl \
  --emit-perf output/render.perf.jsonl \
  --out output/render.pdf
  1. Use --repro-record / --repro-check once your layout stabilizes.

Practical tips:

  • Compare against full-page exports when available.
  • Keep a fixed preview DPI (for example 144 or 200) across iterations.
  • Commit PNG baselines for repeatable visual checks.

Public Golden Regression Suite

Launch-grade render regression coverage is available under goldens/ with three fixtures:

  • invoice
  • statement
  • menu

Golden contract assets:

  • Expected hashes: goldens/expected/golden_suite.expected.json
  • Expected PNG baselines: goldens/expected/png/<case>/<case>_page1.png

Run against committed expectations:

python goldens/run_golden_suite.py verify

Refresh baselines intentionally:

python goldens/run_golden_suite.py generate

Human + AI Operating Mode

Recommended automation defaults:

fullbleed --json-only render ...

Why this is agent-safe:

  • For command-execution JSON payloads, schema is always present.
  • Parser usage errors (exit=2) are emitted by argparse as usage text, not JSON payloads.
  • ok indicates success/failure without parsing text.
  • Optional artifacts are explicitly named in outputs.
  • Schema introspection is available at runtime (--schema).

Example parse loop:

import json, subprocess

proc = subprocess.run(
    [
        "fullbleed", "--json-only", "render",
        "--html", "templates/report.html",
        "--css", "templates/report.css",
        "--out", "output/report.pdf",
    ],
    capture_output=True,
    text=True,
    check=False,
)

payload = json.loads(proc.stdout)
assert payload["schema"] == "fullbleed.render_result.v1"
assert payload["ok"] is True
print(payload["outputs"]["pdf"])

MACHINE_CONTRACT.v1

{
  "schema": "fullbleed.readme_contract.v1",
  "package": "fullbleed",
  "cli_entrypoint": "fullbleed",
  "dev_cli_entrypoint": "python -m fullbleed_cli.cli",
  "python_module": "fullbleed",
  "json_discriminator": "schema",
  "core_commands": [
    "render",
    "verify",
    "plan",
    "debug-perf",
    "debug-jit",
    "run",
    "finalize",
    "inspect",
    "compliance",
    "doctor",
    "capabilities",
    "assets",
    "cache",
    "init",
    "new"
  ],
  "result_schemas": [
    "fullbleed.render_result.v1",
    "fullbleed.verify_result.v1",
    "fullbleed.plan_result.v1",
    "fullbleed.run_result.v1",
    "fullbleed.inspect_pdf.v1",
    "fullbleed.inspect_pdf_batch.v1",
    "fullbleed.inspect_templates.v1",
    "fullbleed.compose_plan.v1",
    "fullbleed.compliance.v1",
    "fullbleed.capabilities.v1",
    "fullbleed.doctor.v1",
    "fullbleed.assets_list.v1",
    "fullbleed.assets_info.v1",
    "fullbleed.assets_install.v1",
    "fullbleed.assets_verify.v1",
    "fullbleed.assets_lock.v1",
    "fullbleed.cache_dir.v1",
    "fullbleed.cache_prune.v1",
    "fullbleed.init.v1",
    "fullbleed.new_template.v1",
    "fullbleed.new_list.v1",
    "fullbleed.new_search.v1",
    "fullbleed.new_remote.v1",
    "fullbleed.debug_perf.v1",
    "fullbleed.debug_jit.v1",
    "fullbleed.repro_record.v1",
    "fullbleed.error.v1"
  ],
  "artifact_flags": [
    "--emit-manifest",
    "--emit-jit",
    "--emit-perf",
    "--emit-glyph-report",
    "--emit-page-data",
    "--emit-compose-plan",
    "--emit-image",
    "--image-dpi",
    "--deterministic-hash",
    "--repro-record",
    "--repro-check"
  ],
  "fail_on": ["overflow", "missing-glyphs", "font-subst", "budget"],
  "budget_flags": ["--budget-max-pages", "--budget-max-bytes", "--budget-max-ms"],
  "profiles": ["dev", "preflight", "prod"],
  "pdf_version_default": "1.7",
  "known_exit_codes": {
    "0": "success",
    "1": "command-level validation/operational failure",
    "2": "argparse usage error",
    "3": "CLI runtime/input error wrapper"
  }
}

Important Behavior Notes

  • render --json cannot be combined with --out - (stdout PDF bytes).
  • verify defaults to stdout PDF unless --emit-pdf is provided; for machine mode, use --emit-pdf <path>.
  • --emit-image <dir> writes per-page PNGs as <stem>_pageN.png (stem comes from --out/--emit-pdf, or render when streaming PDF to stdout).
  • In template auto-compose runs, --emit-image artifacts are rasterized from finalized composed pages and report outputs.image_mode=composed_pdf; otherwise image_mode=overlay_document.
  • outputs.deterministic_hash_mode is pdf_only by default and artifact_set_v1 when image artifacts are emitted.
  • If both --emit-page-data and --emit-glyph-report are set, current engines use a combined API and render once; older engines without that API fall back to a double render.
  • Production target is PDF 1.7.
  • run accepts --html-str without requiring --html.
  • init now scaffolds COMPLIANCE.md for project-level release review.
  • compliance --json emits machine-readable legal/procurement diagnostics.
  • --watermark-layer underlay is accepted as a legacy alias and normalized to background.
  • --emit-manifest includes a watermark object with text|html|image|layer|semantics|opacity|rotation|enabled.
  • --fail-on overflow is enforced from placement data and may auto-enable internal JIT planning.
  • --fail-on font-subst is enforced using missing glyph and fallback diagnostics.
  • --allow-fallbacks allows fallback diagnostics to remain informational for missing-glyphs / font-subst gates while still reporting them in JSON output.
  • --fail-on budget requires at least one budget threshold flag.
  • --repro-check fails on input/hash drift and lock hash mismatches when lock data is available.
  • PDF/A and PDF/X/VT profiles require output intent metadata; pdfa4, pdfa4e, and pdfa4f emit PDF 2.0 automatically. PDF/A, PDF/X/VT, PDF/UA, and WTPDF text output enforces embedded-font constraints, and CLI errors include an actionable hint to add an embeddable font asset.
  • --pdf-profile pdfua1 enables tagged output and PDF/UA-1 identification metadata. Treat verifier/seed traces as machine evidence before making external conformance claims.
  • argparse usage errors exit with code 2 and emit usage text (not JSON), even when --json is present.

Related Docs

  • Agent workflow guide: llm.txt
  • CLI JSON contract quick reference: cli_schema.md
  • CLI epoch/spec: CLI_EPOCH.md
  • PDF template/XObject composition guide: docs/pdf-templates.md
  • Licensing guide: LICENSING.md
  • Third-party notices: THIRD_PARTY_LICENSES.md
  • Living docs example project: examples/living_docs_atlas/README.md
  • Roofing invoice parity example: examples/roofing_invoice/README.md
  • Iconography smoke example: examples/iconography_test/README.md
  • Public golden regression suite: goldens/README.md

License

Fullbleed is licensed under the MIT License (MIT). Commercial use, modification, distribution, and use in proprietary software are permitted subject to the notice-preservation requirement in LICENSE.

Cargo and PyPI metadata both declare MIT.

  • Copyright notice: COPYRIGHT
  • Third-party notices: THIRD_PARTY_LICENSES.md
  • Practical licensing guide: LICENSING.md

For license information, please visit fullbleed.dev or email info@fullbleed.dev.

License integrity gate (CI-friendly, no build required):

python tools/check_license_integrity.py --json

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fullbleed-2.2.5.tar.gz (4.1 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fullbleed-2.2.5-cp310-abi3-win_arm64.whl (6.7 MB view details)

Uploaded CPython 3.10+Windows ARM64

fullbleed-2.2.5-cp310-abi3-win_amd64.whl (7.1 MB view details)

Uploaded CPython 3.10+Windows x86-64

fullbleed-2.2.5-cp310-abi3-win32.whl (8.7 MB view details)

Uploaded CPython 3.10+Windows x86

fullbleed-2.2.5-cp310-abi3-musllinux_1_2_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

fullbleed-2.2.5-cp310-abi3-musllinux_1_2_i686.whl (9.1 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ i686

fullbleed-2.2.5-cp310-abi3-musllinux_1_2_armv7l.whl (8.5 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARMv7l

fullbleed-2.2.5-cp310-abi3-musllinux_1_2_aarch64.whl (6.6 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

fullbleed-2.2.5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

fullbleed-2.2.5-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl (7.4 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ s390x

fullbleed-2.2.5-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (7.4 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ppc64le

fullbleed-2.2.5-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl (9.5 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ i686

fullbleed-2.2.5-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (8.5 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARMv7l

fullbleed-2.2.5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (6.6 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

fullbleed-2.2.5-cp310-abi3-macosx_11_0_arm64.whl (6.5 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

fullbleed-2.2.5-cp310-abi3-macosx_10_12_x86_64.whl (6.8 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file fullbleed-2.2.5.tar.gz.

File metadata

  • Download URL: fullbleed-2.2.5.tar.gz
  • Upload date:
  • Size: 4.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.8

File hashes

Hashes for fullbleed-2.2.5.tar.gz
Algorithm Hash digest
SHA256 60b01945f3601d55764468f9404878ef25ed99f041f9d28174df16ae8e2641c5
MD5 e29bde44315735364b23bb71a69e36d6
BLAKE2b-256 55c15353f7f173513fa957f7fbb6b6034c8def21dc3b376b6c4944e5e932c82a

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-win_arm64.whl.

File metadata

  • Download URL: fullbleed-2.2.5-cp310-abi3-win_arm64.whl
  • Upload date:
  • Size: 6.7 MB
  • Tags: CPython 3.10+, Windows ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.8

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 37a14679471bf9b1601cb895616b259da95cafadfa71eeca0f385e12db002b64
MD5 c2d83d009b61e77c04551c0bb25bb88a
BLAKE2b-256 a40e7cc1615eb18c5c0dfd55b4391eb0d68876c84eb824ac227b0a890088925f

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: fullbleed-2.2.5-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 7.1 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.8

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 60a0e1ff70dcf3cf7117547e9fe92079c6cc539fff4350fb284c4bb2f9c81841
MD5 57f30bd10b233ff7aa0383873bda0099
BLAKE2b-256 932f09cdb7e19f343fffea4e06220ffae99a35791bf3b1e519a91553e049ce97

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-win32.whl.

File metadata

  • Download URL: fullbleed-2.2.5-cp310-abi3-win32.whl
  • Upload date:
  • Size: 8.7 MB
  • Tags: CPython 3.10+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.8

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-win32.whl
Algorithm Hash digest
SHA256 5f9f60f07f14870db0361327025267c9e1a349bdfe1f8edc4d8274a8035a6f7f
MD5 ea856352e277626714d8a8e4d8930ba3
BLAKE2b-256 267af60e238d3e567cb9e1c9715037a7053b8cc2d286a72ccf1b4bc1c62deb03

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 6ab0840eefbe08874e70dec530d3a1add49239ec126bae43454d4ed1296b2e34
MD5 019ff3b863731a84a1c08f5a93da5eba
BLAKE2b-256 8ecda392242e3df2f70bacf5496f61f6529dfe2b4846b5658235ccf54959881c

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 45513e78fa41d9009fb835f2050ca5eb61d9bb35ad64511818e2f16503a64b93
MD5 162f191f15602e8000af2b5e252b3f36
BLAKE2b-256 4f17fdc0e5cad63ad0513b33b901682a446def25b2493b576e39d355d0b77238

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 2459132fa09c7a60eb5dd5196d4407496598714ea6579442455866329d7e10ef
MD5 121234a4d793736c11082f3d08179eeb
BLAKE2b-256 26eeee6abd904669a76b0ad2569f3f44baaeb09f461ed1661c986b03547aad40

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 d9f371edf2d105ea5a5e13571def114bd0b9e22e7b7bef52a45f11397e6d304d
MD5 da03d16be45a7a1d9c07eef09ac4a519
BLAKE2b-256 8930c0ecad2a8cdb3bcc3deff3604eb8fef56d5afb1552899e069afa77f93256

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4a30c3a38682cae33017dc2407f90226d77776bf2056d99d949453d308e20490
MD5 01390ed89541b83f688cb3e3ff50f927
BLAKE2b-256 45722d34f262cde32cde44a9fb8abcfa5f52a766abf9c7be5b1e09d81347ab30

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 fdab6ef3ab6cd4341ba01519955bf49af6a53e7be93edcae7d96ac0fc815377d
MD5 ddc90f6e56e3c268b76cdf6048ff8fc7
BLAKE2b-256 04ce2023dbf1191565753a62799825a550dd37a907bbab63ba230eac9872720e

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 38a1a6527e8d0e25ca6fce90de545a61151877dc65d9968dc704d0887fda807e
MD5 10f383ab7fbe620d894d1f87f4dcf7c7
BLAKE2b-256 b3b5b2a1cafd84bb86180f9f58c423a02757b7cbfd8ad6b176786d0f530efad7

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 f96dcba50856ec7363c8b1abaf06fc8de4055343373303c5c0ac16cef3b97133
MD5 9a5e667e66c17cfa541ef4421e187781
BLAKE2b-256 ec8e005107f2e94ae14838bf820ea3ede0e30db2ba484db5c09b12ba08e899f6

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 46d68ebd6bf5e84e885861f4e6d976b6c27913a2cad809f6d830de277feb85ff
MD5 1ff8f23de128a152a9d8e7c819d8a082
BLAKE2b-256 606493f1f3226a6c1d15b09f2b9fca9f5ee6b1dc302d5389bac7f8388713496f

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b75bbb8df1b040f24756c7acaac8d184803c0e60e79d13f5294a490578015147
MD5 0db82111f047a8e79d51e090c5c9bf54
BLAKE2b-256 cd77671ce560a573ce771fe56ea07b22b6994d51b973c3b5d2dd28619d1547b3

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1768da784e0c5ad197de80b87d594c5caebfa821c95da89c529ed41172127c84
MD5 45e22027ed598419cf06d7df1982616d
BLAKE2b-256 658c6ab3219a470a17bc2be4dda2d20c4358ced88c114338b8c2c7d997c80a79

See more details on using hashes here.

File details

Details for the file fullbleed-2.2.5-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for fullbleed-2.2.5-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 cccfeebd61bee2ee191f084c001a9063e58e27fdac517157b0a3ea1872aa5628
MD5 123ea8a620503e8b9ac299aa98f0304b
BLAKE2b-256 6aa6a4abd60df77d891cd11a8d8c988d7dd87b0faabdfee0b8d173ba5b88c6ae

See more details on using hashes here.

Release history Release notifications | RSS feed

2.3.1

16 files

2.3.0

16 files

This release

2.2.5 This release

16 files

2.2.4

16 files

2.2.3

16 files

2.2.2

16 files

2.2.0

16 files

2.1.0

16 files

2.0.0

16 files

1.6.2

16 files

1.6.1

16 files

1.6.0

7 files

1.0.0

2 files

0.6.15

3 files

0.6.12

3 files

0.6.11

3 files

0.6.9

3 files

0.6.8

3 files

0.6.5

3 files

0.6.0

3 files

0.5.0

4 files

0.2.7

4 files

0.2.6

3 files

0.2.5

3 files

0.2.0

3 files

0.1.12

3 files

0.1.6

3 files

0.1.0

3 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page