Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: CI

env:
FULLBLEED_CI_VERSION: "2.5.6"
FULLBLEED_CI_VERSION: "2.5.7"
RUST_MIN_STACK: "4194304"

on:
Expand Down Expand Up @@ -157,6 +157,19 @@ jobs:
path: target/text-extraction
if-no-files-found: warn

- name: Verify compact font subsets with independent font and PDF readers
run: |
python -m pip install pypdf==6.19.0 pypdfium2==5.14.0 fonttools==4.65.0 pillow==12.3.0
python -I tools/smoke_font_subsets.py --out target/font-subsets

- name: Retain compact font subset PDFs and preview evidence
if: always()
uses: actions/upload-artifact@v7
with:
name: font-subsets-${{ runner.os }}
path: target/font-subsets
if-no-files-found: warn

- name: Retain gradient PDFs and preview evidence
if: always()
uses: actions/upload-artifact@v7
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-crates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
description: "Annotated release tag whose exact source commit will be published"
required: true
type: string
default: "v2.5.6"
default: "v2.5.7"
publish:
description: "Publish after all validation gates pass"
required: true
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,19 @@ jobs:
crates/fullbleed_audit_contract/target/package/*.crate
if-no-files-found: error

- name: Verify compact font subsets with independent font and PDF readers
run: |
python -m pip install pypdf==6.19.0 pypdfium2==5.14.0 fonttools==4.65.0 pillow==12.3.0
python -I tools/smoke_font_subsets.py --out target/font-subsets

- name: Retain compact font subset PDFs and preview evidence
if: always()
uses: actions/upload-artifact@v7
with:
name: release-font-subsets
path: target/font-subsets
if-no-files-found: error

build-wheels:
name: Build wheel (${{ matrix.label }})
needs: validate
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "fullbleed"
version = "2.5.6"
version = "2.5.7"
edition = "2024"
rust-version = "1.85"
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ python -m pip install fullbleed
From a local wheel:

```bash
python -m pip install C:\path\to\fullbleed-2.5.6-cp310-abi3-win_amd64.whl
python -m pip install C:\path\to\fullbleed-2.5.7-cp310-abi3-win_amd64.whl
```

From a source checkout with Rust installed, no Python build package is needed:
Expand Down
20 changes: 20 additions & 0 deletions ReleaseNotes.MD
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# Fullbleed Release Notes - 2.5.7

Release date: October 5, 2026

## Smaller embedded TrueType subsets

TrueType subsets now omit unused character-map entries, glyph names, and metrics
while preserving the original glyph IDs, retained outlines and instructions,
composite dependencies, advances, and font notices. Horizontal-header extrema
are recalculated for the subset. Character-map formats other than 4 and 12 keep
their original bytes; an unsupported or larger map rewrite uses the source map.

The change adds no runtime dependency and does not change the rendering API.
PDF bytes and hashes change. Review stored PDF baselines before updating them.
Independent font, text, and pixel checks are described in the
[2.5.7 release runbook](docs/release/2.5.7-runbook.md). Claims remain limited to the
retained fixtures and validator reports.

---

# Fullbleed Release Notes - 2.5.6

Release date: October 3, 2026
Expand Down
2 changes: 1 addition & 1 deletion cli_schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!-- GENERATED FILE: DO NOT EDIT. Run `python tools/generate_agent_contract.py`. -->
# CLI and Agent JSON Contract

Generated from the installed Fullbleed **2.5.6** runtime. The canonical machine artifact is `fullbleed-agent-contract.json`.
Generated from the installed Fullbleed **2.5.7** runtime. The canonical machine artifact is `fullbleed-agent-contract.json`.

## Authority and invocation

Expand Down
63 changes: 63 additions & 0 deletions docs/release/2.5.7-runbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Fullbleed 2.5.7 release runbook

This patch compacts embedded TrueType metadata without renumbering retained
glyphs. Publish from a clean annotated `v2.5.7` tag after the checks below pass.

## Build and verify

Keep Cargo, Python, CI smoke metadata, release defaults, and generated agent
artifacts synchronized at 2.5.7. The optional MCP adapter stays at 0.1.1 and the
audit crate stays at 0.1.3. Historical example pins and measured comparisons keep
the versions they actually verified.

Build and install a wheel in an isolated environment. Generate agent artifacts
using `tools/generate_agent_contract.py --python PATH --json`, rebuild and install
the final wheel, then run the generator with `--check`. Build the sdist from that
same source. Do not hand-edit generated agent artifacts.

- Run the focused font-subset Rust tests, then the full Rust suite with default
and Python/SVG features and the packaged-crate MSRV check.
- Run focused installed-native font, text, preview, compiled-table and profile
Python tests, followed by the full suite with `FULLBLEED_TEST_INSTALLED_NATIVE=1`.
- Install test-only `pypdf==6.19.0`, `pypdfium2==5.14.0`, `fonttools==4.65.0`, and
`pillow==12.3.0`. Run `python -I tools/smoke_font_subsets.py --out TARGET`.
Retain all PDFs, source HTML/CSS, independent and native previews, table sizes,
versions and hashes. The check independently closes composite dependencies
and verifies glyph IDs, raw outlines/instructions, metrics, cmap mappings,
font notices, SFNT checksums and recalculated horizontal-header extrema.
- Record a public 2.5.6 baseline with `--allow-legacy-metadata`. Compare the
candidate using `--baseline BASELINE_DIRECTORY`. Identical inputs must retain
text, page count, PDFium pixels and native previews while reducing PDF bytes.
Running the normal check on 2.5.6 must reject its untrimmed metadata.
- Run the existing styled-text, gradient, template, compiled-binding and
reproducibility checks. Compare the three golden PDFs with public 2.5.6 using
an independent renderer before accepting changed PDF hashes; direct PNG
baselines must stay unchanged.
- Inspect representative invoice, ledger, multilingual, math, symbol and
non-BMP previews. The unshaped-text case exercises the exposed option too.
- Require Linux/Windows CI and print-profile gates. Retain raw external
validator reports. The optional dedicated PDF/VT validator remains
unconfigured; its skipped job is not independent conformance evidence.
- Run installed-package smoke, agent-contract checks, release metadata/license
checks, deterministic goldens, CSS status and bundled Skill validation.

## Publish and verify

Use the configured PyPI trusted publisher and crates.io workflow after the
final release gates pass. Retain the source tag, workflow conclusions and
artifact hashes. Install the public wheel in a fresh environment and repeat
the font-subset check before promoting the release. Optional bindings remain
independently versioned and require their own installed-package checks when
updating their pinned engine.

The earlier three-renderer comparison stays an immutable 2.5.6 measurement.
Size changes from this patch belong in a separately identified before/after
record; they must not replace its historical PDF artifacts or timing samples.
These checks do not establish general renderer parity, accessibility, print
device compatibility, or throughput.

The table handling follows the OpenType specifications for
[`cmap`](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap),
[`post`](https://learn.microsoft.com/en-us/typography/opentype/spec/post),
[`hmtx`](https://learn.microsoft.com/en-us/typography/opentype/spec/hmtx), and
[`hhea`](https://learn.microsoft.com/en-us/typography/opentype/spec/hhea).
5 changes: 5 additions & 0 deletions docs/release/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ This directory is the release-operations layer for Fullbleed. It is separate
from feature documentation so release decisions can be audited without reading
engine internals.

## 2.5.7 Documents

- `docs/release/2.5.7-runbook.md`: compact TrueType metadata and retained output checks.
- `tools/smoke_font_subsets.py`: independent font-program, text, and pixel comparisons.

## 2.5.6 Documents

- `docs/release/2.5.6-runbook.md`: single-copy synthesized-bold text, affine glyph previews, and retained extraction checks.
Expand Down
Binary file modified examples/acme_invoice/output/acme_sample_invoice.pdf
Binary file not shown.
Binary file modified examples/bank_statement/output/bank_statement.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion fullbleed-agent-contract.json
Original file line number Diff line number Diff line change
Expand Up @@ -4207,7 +4207,7 @@
"license": "MIT",
"name": "Fullbleed PDF Engine",
"python_package": "fullbleed",
"version": "2.5.6"
"version": "2.5.7"
},
"profiles": {
"pdf": {
Expand Down
12 changes: 6 additions & 6 deletions goldens/expected/golden_suite.expected.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"schema": "fullbleed.golden_suite.v1",
"generated_at_utc": "2026-10-03T15:49:04.157375+00:00",
"generated_at_utc": "2026-10-05T01:29:44.268281Z",
"cases": {
"acme_invoice": {
"case_id": "acme_invoice",
"report": "examples/acme_invoice/report.py",
"pdf": {
"path": "examples/acme_invoice/output/acme_sample_invoice.pdf",
"bytes": 133691,
"sha256": "f7f69432764aa811a53a3c83b9df08743fbf0ae5804d4686809f472b642690fb"
"bytes": 93250,
"sha256": "6199c7ec17f35f4592aa2eb972df169086b3974d25993417cdd40b8ef0d8c379"
},
"png": {
"count": 1,
Expand Down Expand Up @@ -36,8 +36,8 @@
"report": "examples/bank_statement/report.py",
"pdf": {
"path": "examples/bank_statement/output/bank_statement.pdf",
"bytes": 59765,
"sha256": "76b835ce61bc857feb807fdafadacab01a118e7e22abefd937091ae396f3f805"
"bytes": 19365,
"sha256": "2eb3c562674e5e0e7920e7bbb1ea306667c791904ebdcfabd3777e5db6cccb7a"
},
"png": {
"count": 2,
Expand Down Expand Up @@ -93,4 +93,4 @@
"css_layers": null
}
}
}
}
2 changes: 1 addition & 1 deletion llms.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Fullbleed PDF Engine

> Fullbleed 2.5.6 is a deterministic, self-contained document-generation runtime for Python and Rust. It turns structured data plus static HTML/CSS into validated PDF documents without a browser.
> Fullbleed 2.5.7 is a deterministic, self-contained document-generation runtime for Python and Rust. It turns structured data plus static HTML/CSS into validated PDF documents without a browser.

The installed runtime is authoritative. Do not infer its API from this file or from remembered release knowledge. Start with:

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ backend-path = ["build_backend"]

[project]
name = "fullbleed"
version = "2.5.6"
version = "2.5.7"
description = "Deterministic Python PDF engine for reports, invoices, accessible documents, print-ready output, and compiled VDP"
readme = "README.md"
requires-python = ">=3.10"
Expand Down
Loading
Loading