Accessibility-first publishing engine — PDF/UA-2 + WTPDF + PDF/A-4f, C2PA + PAdES + SLSA provenance, multi-format emission, MCP server.
Project description
Inclusio
Publishing that includes everyone.
Accessibility-first publishing engine for LaTeX, packaged as a Python CLI. PDF/UA-2 + WTPDF + PDF/A-4f triple-conformance, C2PA + PAdES + SLSA provenance, multi-format emission (HTML5 / JATS / EPUB3), LLM-augmented judges, and an MCP server for agent integration.
Contents
- Install —
pip, optional extras, source - Quick Start — first tagged PDF in 60 seconds
- Features — what the engine ships
- Usage — common Python + CLI recipes
- Architecture — the engine's package layout
- Examples — six runnable scenarios
- Documentation — quickstart, tutorials, reference
- Publishing against an external content tree
- Development — local validation gate
- Security — signed commits, provenance, audit
- License
Install
pip install inclusio # engine + CLI
pip install 'inclusio[mcp]' # + FastMCP server
pip install 'inclusio[provenance]' # + pyhanko (PAdES)
pip install 'inclusio[dev]' # + pytest, ruff, sphinx, interrogate
Requires Python ≥ 3.11 and a LuaLaTeX toolchain on PATH. Linux, macOS, and WSL are supported (native Windows works for the Python surface; the LaTeX gate needs WSL or a TeX Live install).
| Optional tool | Adds | Install |
|---|---|---|
verapdf |
The strict EAA / accessibility audit gate | verapdf.org/install |
pandoc (≥ 3.0) |
HTML5 / JATS XML / EPUB3 multi-format emission | brew install pandoc · apt install pandoc |
c2patool |
C2PA Content Credentials | contentauth/c2patool releases |
pyhanko (via [provenance]) |
PAdES B-T / B-LT / B-LTA signing | Pulled by the extra |
Build from source
git clone https://github.com/sebastienrousseau/inclusio.git
cd inclusio
./bin/setup # check toolchain + install dev extras
make test # smoke suite
make coverage # full suite (gate: 97 %)
Quick Start
A complete worked example you can paste into a fresh directory:
pip install inclusio
# Grab the minimal example, build + audit + emit + judge:
git clone --depth=1 https://github.com/sebastienrousseau/inclusio
cd inclusio/examples/01-hello-world && make
That single make produces build/hello.pdf (PDF/UA-2 + WTPDF +
PDF/A-4f triple-conformance), runs veraPDF over it, and exits
non-zero if any flavour fails.
Drive the same surface from Python:
# quickstart.py
import subprocess
from pathlib import Path
# 1. Render + build the bundled "hello" fixture — the CLI is the
# canonical entry point for the LaTeX step.
subprocess.run(
["python", "-m", "inclusio.cli.build", "build", "--doc", "hello"],
cwd="examples/01-hello-world",
check=True,
)
# 2. Audit the produced PDF in-process — pure-Python, no subprocess.
from inclusio.cli import audit
pdfs = audit.collect_pdfs(
target=Path("examples/01-hello-world/build"),
build_dir=Path("examples/01-hello-world/build"),
registry_stems={"hello"},
)
report = audit.audit(pdfs)
assert report["summary"]["fail"] == 0, "veraPDF reported a failure"
print(f' PASS {report["summary"]["pdfs"]} PDF(s), '
f'{report["summary"]["pass"]}/{report["summary"]["total"]} checks')
# → PASS 1 PDF(s), 3/3 checks
Features
- Tagged PDF, by default. Every build emits a PDF/UA-2 +
WTPDF + PDF/A-4f triple-conforming artefact via the LaTeX
kernel's
tagpdfintegration. The veraPDF audit gate is wired into CI and exits non-zero on any FAIL. - Multi-format emission. The same LaTeX source produces HTML5 (WCAG-clean), JATS XML (1.3, JATS4R-ready), and EPUB3 via Pandoc.
- LLM-augmented judges. ATS (Workday / Greenhouse / Lever
heuristic), citation grounding, and JD-to-CV fit — local
llama.cppor BYO-key cloud (Anthropic / OpenAI), with heuristic-only fallback when the LLM is unreachable. - Content provenance. C2PA Content Credentials (via
c2patool), PAdES B-T / B-LT / B-LTA signatures (viapyhanko), and SLSA L3 build attestation (viaactions/attest-build-provenance). - MCP server.
inclusio-mcpexposeslist_docs,audit_pdf,render, anddoc_countso Claude Code, Cursor, Continue, or any other MCP client can drive the engine. - JSON Resume importer.
inclusio import-resumeconverts a jsonresume.org v1 document into the engine's CV YAML schema. - Brief-driven CV tailoring. ATS-clean variants tailored against a job description with British-English cleanup and consistency lint.
Usage
Build, audit, judge a registered document
inclusio build --doc cv --mode draft # → build/cv.pdf
inclusio audit --strict # → veraPDF, non-zero on FAIL
inclusio judge --doc cv --judge ats # → grade + findings
Score a CV against a job description
# score_cv.py — fully runnable: drop into a directory with brief.txt + cv.txt
from pathlib import Path
from inclusio.judge import jd_fit
jd_text = Path("brief.txt").read_text(encoding="utf-8")
cv_text = Path("cv.txt").read_text(encoding="utf-8")
report = jd_fit.score_jd_fit(jd_text, cv_text)
print(f"score: {report.score}/100 grade: {report.grade}")
print(f"missing: {sorted(report.metrics['missing_required'])[:5]}")
# → score: 78/100 grade: B
# → missing: ['opentelemetry', 'rust']
Drive the engine over MCP
inclusio-mcp # stdio (Claude Code default)
inclusio-mcp --http --port 8765 # Streamable HTTP
Wire into Claude Code via ~/.claude/claude_desktop_config.json:
{
"mcpServers": {
"inclusio": {
"command": "inclusio-mcp",
"env": { "INCLUSIO_CONTENT_DIR": "/absolute/path/to/content" }
}
}
}
Embed C2PA Content Credentials
inclusio provenance --doc cv \
--cert /path/to/cert.pem \
--key /path/to/key.pem \
--output build/cv.c2pa.pdf
Architecture
inclusio/ # Python package
cli/ # build · audit · render · tailor · judge · emit · provenance · …
judge/ # ats · citations · jd_fit · local_llm · cloud_llm
emit/ # pandoc (HTML5 / JATS XML / EPUB3)
provenance/ # c2pa (c2patool) · pades (pyhanko)
mcp/ # FastMCP server
tools/ # fix_semantic · stamp_pdfs · overlay
core/ # LaTeX classes (.cls) and styles (.sty)
templates/ # Jinja2 templates for the template-driven docs
benches/ # pytest-benchmark micro-benchmarks
examples/ # Six self-contained runnable scenarios
docs/ # Sphinx documentation
External consumers supply their own content tree (LaTeX sources,
YAML metadata, brand assets) and point the engine at it through
INCLUSIO_CONTENT_DIR or --content-dir. The repo's own src/
and data/ directories double as the public-engine self-test
fixtures.
Examples
| # | Folder | What it teaches |
|---|---|---|
| 1 | 01-hello-world/ |
Tagged-PDF build with the audit gate |
| 2 | 02-cv-from-jsonresume/ |
JSON Resume → CV → ATS + JD-fit scoring |
| 3 | 03-paper-with-citations/ |
Paper → PDF + HTML + JATS + EPUB + citation judge |
| 4 | 04-mcp-agent/ |
inclusio-mcp + Claude Code skill |
| 5 | 05-c2pa-sign/ |
C2PA Content Credentials |
| 6 | 06-pades-sign/ |
PAdES B-T eIDAS signature |
Each folder has its own Makefile (make help lists targets) and
a README.md with the why + the how.
Documentation
- Quickstart — five-minute walkthrough.
- Tutorials — four end-to-end walkthroughs paired 1 : 1 with the examples.
- Architecture — public-engine vs content-repo boundary, sprint history, decision log.
- Tagged PDF — the conformance stack.
- Multi-format — HTML / JATS / EPUB.
- Judges — ATS, citations, JD-fit, LLM rerank contract.
- Provenance — C2PA, PAdES, SLSA.
- MCP server — tool + resource surface.
Publishing against an external content tree
make publish CONTENT_DIR=/absolute/path/to/your-content-repo
The content repo supplies its own data/meta.yaml (document
registry) and src/**.tex (LaTeX sources). The engine reads no
state from outside INCLUSIO_CONTENT_DIR once it's set.
Development
make test # smoke (≤ 20 s)
make coverage # full suite + 97 % gate (~3 min)
make docstrings # 100 % interrogate gate
make benchmark # pytest-benchmark micro-budgets
make audit-strict # veraPDF, exits non-zero on any FAIL
make docs # Sphinx
All commits to main are squash-merged via PR. Branch protection
requires Lint (ruff) + Public Engine Checks (py3.11 / 3.12 / 3.13) + the Signed-commit gate to pass. See
CONTRIBUTING.md.
Security
- SSH-signed commits. Every commit on
mainis GitHub-verified. - Signed tags. Release tags are ED25519-signed.
- SLSA L3 build provenance (gated on the repo being public or on a paid GitHub plan).
- PyPI Trusted Publishing wiring (
pypa/gh-action-pypi-publish) inrelease.yml; flipvars.PYPI_TRUSTED_PUBLISHING=trueonce the PyPI publisher is configured. - Cloud LLM keys are env-var only —
inclusionever auto- discovers credentials from disk.
Report vulnerabilities per SECURITY.md.
License
MIT. © 2026 Sebastien Rousseau.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file inclusio-0.0.4.tar.gz.
File metadata
- Download URL: inclusio-0.0.4.tar.gz
- Upload date:
- Size: 186.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b91f67e56353406b6074de054462e4062b2613ae00f2c0be0ae2dcb6c52c4cd
|
|
| MD5 |
ea92c10226098f9501191cafd36af941
|
|
| BLAKE2b-256 |
15f99246aebe02808da8edba85b39311f9607b46719d2813caecff0a7c3d849b
|
File details
Details for the file inclusio-0.0.4-py3-none-any.whl.
File metadata
- Download URL: inclusio-0.0.4-py3-none-any.whl
- Upload date:
- Size: 105.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8e3db15a63f7d7bae1869e09bb3f43a12bad14d88b3df6748c373f37afdc7f3
|
|
| MD5 |
13fc4bef6bd5de4e713477c65d13ea4c
|
|
| BLAKE2b-256 |
b67f43d15ef7e271d16aaa41fee629405082e34d16ce24667d4091b77dccf1d7
|