{"id":51557367,"url":"https://github.com/sebastienrousseau/inclusio","last_synced_at":"2026-07-10T06:31:45.836Z","repository":{"id":361654799,"uuid":"1161125776","full_name":"sebastienrousseau/inclusio","owner":"sebastienrousseau","description":"Accessibility-first publishing engine — PDF/UA-2 + WTPDF + PDF/A-4f, C2PA + PAdES + SLSA provenance, multi-format emission, MCP server.","archived":false,"fork":false,"pushed_at":"2026-07-06T18:41:11.000Z","size":750,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-06T19:17:17.732Z","etag":null,"topics":["accessibility","c2pa","eaa","epub","jats","latex","lualatex","mcp","model-context-protocol","pades","pdf-a","pdf-ua","pdf-ua-2","provenance","publishing","slsa","tagged-pdf","tagpdf","wcag","wtpdf"],"latest_commit_sha":null,"homepage":"https://github.com/sebastienrousseau/inclusio","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sebastienrousseau.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-18T19:03:26.000Z","updated_at":"2026-07-06T18:41:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sebastienrousseau/inclusio","commit_stats":null,"previous_names":["sebastienrousseau/inclusio"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/sebastienrousseau/inclusio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sebastienrousseau%2Finclusio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sebastienrousseau%2Finclusio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sebastienrousseau%2Finclusio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sebastienrousseau%2Finclusio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sebastienrousseau","download_url":"https://codeload.github.com/sebastienrousseau/inclusio/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sebastienrousseau%2Finclusio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35323809,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-10T02:00:06.465Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","c2pa","eaa","epub","jats","latex","lualatex","mcp","model-context-protocol","pades","pdf-a","pdf-ua","pdf-ua-2","provenance","publishing","slsa","tagged-pdf","tagpdf","wcag","wtpdf"],"created_at":"2026-07-10T06:31:45.037Z","updated_at":"2026-07-10T06:31:45.823Z","avatar_url":"https://github.com/sebastienrousseau.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://cloudcdn.pro/inclusio/v1/logos/inclusio.svg\" alt=\"Inclusio logo\" width=\"128\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eInclusio\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003ePublishing that includes everyone.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Accessibility-first publishing engine for LaTeX, packaged as a\n  Python CLI. PDF/UA-2 + WTPDF + PDF/A-4f triple-conformance,\n  C2PA + PAdES + SLSA provenance, multi-format emission\n  (HTML5 / JATS / EPUB3), LLM-augmented judges, and an MCP server\n  for agent integration.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/sebastienrousseau/inclusio/actions/workflows/engine-validation.yml\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/sebastienrousseau/inclusio/engine-validation.yml?style=for-the-badge\u0026logo=github\u0026label=CI\" alt=\"Engine Validation\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/sebastienrousseau/inclusio/actions/workflows/verapdf.yml\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/sebastienrousseau/inclusio/verapdf.yml?style=for-the-badge\u0026logo=github\u0026label=veraPDF\" alt=\"veraPDF Audit\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/sebastienrousseau/inclusio\"\u003e\u003cimg src=\"https://img.shields.io/badge/Python-%3E%3D3.11-3776AB?style=for-the-badge\u0026logo=python\u0026logoColor=white\" alt=\"Python \u0026gt;= 3.11\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/sebastienrousseau/inclusio\"\u003e\u003cimg src=\"https://img.shields.io/badge/PDF%2FUA--2%20%7C%20WTPDF%20%7C%20PDF%2FA--4f-blue?style=for-the-badge\" alt=\"PDF/UA-2 · WTPDF · PDF/A-4f\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/sebastienrousseau/inclusio/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-black?style=for-the-badge\" alt=\"MIT licence\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## Contents\n\n- [Install](#install) — `pip`, optional extras, source\n- [Quick Start](#quick-start) — first tagged PDF in 60 seconds\n- [Features](#features) — what the engine ships\n- [Usage](#usage) — common Python + CLI recipes\n- [Architecture](#architecture) — the engine's package layout\n- [Examples](#examples) — six runnable scenarios\n- [Documentation](#documentation) — quickstart, tutorials, reference\n- [Publishing against an external content tree](#publishing-against-an-external-content-tree)\n- [Development](#development) — local validation gate\n- [Security](#security) — signed commits, provenance, audit\n- [License](#license)\n\n---\n\n## Install\n\n```bash\npip install inclusio                       # engine + CLI\npip install 'inclusio[mcp]'                # + FastMCP server\npip install 'inclusio[provenance]'         # + pyhanko (PAdES)\npip install 'inclusio[dev]'                # + pytest, ruff, sphinx, interrogate\n```\n\n**Requires** Python ≥ 3.11 and a LuaLaTeX toolchain on PATH. Linux,\nmacOS, and WSL are supported (native Windows works for the Python\nsurface; the LaTeX gate needs WSL or a TeX Live install).\n\n| Optional tool | Adds | Install |\n|---|---|---|\n| `verapdf` | The strict EAA / accessibility audit gate | [verapdf.org/install](https://docs.verapdf.org/install/) |\n| `pandoc` (≥ 3.0) | HTML5 / JATS XML / EPUB3 multi-format emission | `brew install pandoc` · `apt install pandoc` |\n| `c2patool` | C2PA Content Credentials | [contentauth/c2patool releases](https://github.com/contentauth/c2patool/releases) |\n| `pyhanko` (via `[provenance]`) | PAdES B-T / B-LT / B-LTA signing | Pulled by the extra |\n\n### Build from source\n\n```bash\ngit clone https://github.com/sebastienrousseau/inclusio.git\ncd inclusio\n./bin/setup        # check toolchain + install dev extras\nmake test          # smoke suite\nmake coverage      # full suite (gate: 97 %)\n```\n\n---\n\n## Quick Start\n\nA complete worked example you can paste into a fresh directory:\n\n```bash\npip install inclusio\n\n# Grab the minimal example, build + audit + emit + judge:\ngit clone --depth=1 https://github.com/sebastienrousseau/inclusio\ncd inclusio/examples/01-hello-world \u0026\u0026 make\n```\n\nThat single `make` produces `build/hello.pdf` (PDF/UA-2 + WTPDF +\nPDF/A-4f triple-conformance), runs veraPDF over it, and exits\nnon-zero if any flavour fails.\n\nDrive the same surface from Python:\n\n```python\n# quickstart.py\nimport subprocess\nfrom pathlib import Path\n\n# 1. Render + build the bundled \"hello\" fixture — the CLI is the\n#    canonical entry point for the LaTeX step.\nsubprocess.run(\n    [\"python\", \"-m\", \"inclusio.cli.build\", \"build\", \"--doc\", \"hello\"],\n    cwd=\"examples/01-hello-world\",\n    check=True,\n)\n\n# 2. Audit the produced PDF in-process — pure-Python, no subprocess.\nfrom inclusio.cli import audit\n\npdfs = audit.collect_pdfs(\n    target=Path(\"examples/01-hello-world/build\"),\n    build_dir=Path(\"examples/01-hello-world/build\"),\n    registry_stems={\"hello\"},\n)\nreport = audit.audit(pdfs)\nassert report[\"summary\"][\"fail\"] == 0, \"veraPDF reported a failure\"\nprint(f'  PASS  {report[\"summary\"][\"pdfs\"]} PDF(s), '\n      f'{report[\"summary\"][\"pass\"]}/{report[\"summary\"][\"total\"]} checks')\n# →   PASS  1 PDF(s), 3/3 checks\n```\n\n---\n\n## Features\n\n- **Tagged PDF, by default.** Every build emits a PDF/UA-2 +\n  WTPDF + PDF/A-4f triple-conforming artefact via the LaTeX\n  kernel's `tagpdf` integration. The veraPDF audit gate is wired\n  into CI and exits non-zero on any FAIL.\n- **Multi-format emission.** The same LaTeX source produces HTML5\n  (WCAG-clean), JATS XML (1.3, JATS4R-ready), and EPUB3 via\n  Pandoc.\n- **LLM-augmented judges.** ATS (Workday / Greenhouse / Lever\n  heuristic), citation grounding, and JD-to-CV fit — local\n  `llama.cpp` or BYO-key cloud (Anthropic / OpenAI), with\n  heuristic-only fallback when the LLM is unreachable.\n- **Content provenance.** C2PA Content Credentials (via\n  `c2patool`), PAdES B-T / B-LT / B-LTA signatures (via\n  `pyhanko`), and SLSA L3 build attestation (via\n  `actions/attest-build-provenance`).\n- **MCP server.** `inclusio-mcp` exposes `list_docs`, `audit_pdf`,\n  `render`, and `doc_count` so Claude Code, Cursor, Continue, or\n  any other MCP client can drive the engine.\n- **JSON Resume importer.** `inclusio import-resume` converts a\n  jsonresume.org v1 document into the engine's CV YAML schema.\n- **Brief-driven CV tailoring.** ATS-clean variants tailored\n  against a job description with British-English cleanup and\n  consistency lint.\n\n## Usage\n\n### Build, audit, judge a registered document\n\n```bash\ninclusio build --doc cv --mode draft        # → build/cv.pdf\ninclusio audit --strict                     # → veraPDF, non-zero on FAIL\ninclusio judge --doc cv --judge ats         # → grade + findings\n```\n\n### Score a CV against a job description\n\n```python\n# score_cv.py — fully runnable: drop into a directory with brief.txt + cv.txt\nfrom pathlib import Path\nfrom inclusio.judge import jd_fit\n\njd_text = Path(\"brief.txt\").read_text(encoding=\"utf-8\")\ncv_text = Path(\"cv.txt\").read_text(encoding=\"utf-8\")\n\nreport = jd_fit.score_jd_fit(jd_text, cv_text)\nprint(f\"score:   {report.score}/100   grade: {report.grade}\")\nprint(f\"missing: {sorted(report.metrics['missing_required'])[:5]}\")\n# → score:   78/100   grade: B\n# → missing: ['opentelemetry', 'rust']\n```\n\n### Drive the engine over MCP\n\n```bash\ninclusio-mcp                          # stdio (Claude Code default)\ninclusio-mcp --http --port 8765       # Streamable HTTP\n```\n\nWire into Claude Code via `~/.claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"inclusio\": {\n      \"command\": \"inclusio-mcp\",\n      \"env\": { \"INCLUSIO_CONTENT_DIR\": \"/absolute/path/to/content\" }\n    }\n  }\n}\n```\n\n### Embed C2PA Content Credentials\n\n```bash\ninclusio provenance --doc cv \\\n  --cert /path/to/cert.pem \\\n  --key  /path/to/key.pem \\\n  --output build/cv.c2pa.pdf\n```\n\n---\n\n## Architecture\n\n```\ninclusio/                  # Python package\n  cli/                     # build · audit · render · tailor · judge · emit · provenance · …\n  judge/                   # ats · citations · jd_fit · local_llm · cloud_llm\n  emit/                    # pandoc (HTML5 / JATS XML / EPUB3)\n  provenance/              # c2pa (c2patool) · pades (pyhanko)\n  mcp/                     # FastMCP server\n  tools/                   # fix_semantic · stamp_pdfs · overlay\ncore/                      # LaTeX classes (.cls) and styles (.sty)\ntemplates/                 # Jinja2 templates for the template-driven docs\nbenches/                   # pytest-benchmark micro-benchmarks\nexamples/                  # Six self-contained runnable scenarios\ndocs/                      # Sphinx documentation\n```\n\nExternal consumers supply their own content tree (LaTeX sources,\nYAML metadata, brand assets) and point the engine at it through\n`INCLUSIO_CONTENT_DIR` or `--content-dir`. The repo's own `src/`\nand `data/` directories double as the public-engine self-test\nfixtures.\n\n## Examples\n\n| # | Folder | What it teaches |\n|---|---|---|\n| 1 | [`01-hello-world/`](./examples/01-hello-world/) | Tagged-PDF build with the audit gate |\n| 2 | [`02-cv-from-jsonresume/`](./examples/02-cv-from-jsonresume/) | JSON Resume → CV → ATS + JD-fit scoring |\n| 3 | [`03-paper-with-citations/`](./examples/03-paper-with-citations/) | Paper → PDF + HTML + JATS + EPUB + citation judge |\n| 4 | [`04-mcp-agent/`](./examples/04-mcp-agent/) | `inclusio-mcp` + Claude Code skill |\n| 5 | [`05-c2pa-sign/`](./examples/05-c2pa-sign/) | C2PA Content Credentials |\n| 6 | [`06-pades-sign/`](./examples/06-pades-sign/) | PAdES B-T eIDAS signature |\n\nEach folder has its own `Makefile` (`make help` lists targets) and\na `README.md` with the why + the how.\n\n## Documentation\n\n- **[Quickstart](./docs/quickstart.md)** — five-minute walkthrough.\n- **[Tutorials](./docs/tutorials/)** — four end-to-end walkthroughs\n  paired 1 : 1 with the examples.\n- **[Architecture](./docs/architecture.md)** — public-engine vs\n  content-repo boundary, sprint history, decision log.\n- **[Tagged PDF](./docs/tagged-pdf.md)** — the conformance stack.\n- **[Multi-format](./docs/multi-format.md)** — HTML / JATS / EPUB.\n- **[Judges](./docs/judges.md)** — ATS, citations, JD-fit, LLM\n  rerank contract.\n- **[Provenance](./docs/provenance.md)** — C2PA, PAdES, SLSA.\n- **[MCP server](./docs/mcp-server.md)** — tool + resource surface.\n\n## Publishing against an external content tree\n\n```bash\nmake publish CONTENT_DIR=/absolute/path/to/your-content-repo\n```\n\nThe content repo supplies its own `data/meta.yaml` (document\nregistry) and `src/**.tex` (LaTeX sources). The engine reads no\nstate from outside `INCLUSIO_CONTENT_DIR` once it's set.\n\n## Development\n\n```bash\nmake test          # smoke (≤ 20 s)\nmake coverage      # full suite + 97 % gate (~3 min)\nmake docstrings    # 100 % interrogate gate\nmake benchmark     # pytest-benchmark micro-budgets\nmake audit-strict  # veraPDF, exits non-zero on any FAIL\nmake docs          # Sphinx\n```\n\nAll commits to `main` are squash-merged via PR. Branch protection\nrequires `Lint (ruff)` + `Public Engine Checks (py3.11 / 3.12 /\n3.13)` + the `Signed-commit gate` to pass. See\n[`CONTRIBUTING.md`](./CONTRIBUTING.md).\n\n## Security\n\n- **SSH-signed commits.** Every commit on `main` is GitHub-verified.\n- **Signed tags.** Release tags are ED25519-signed.\n- **SLSA L3 build provenance** (gated on the repo being public or\n  on a paid GitHub plan).\n- **PyPI Trusted Publishing** wiring (`pypa/gh-action-pypi-publish`)\n  in `release.yml`; flip `vars.PYPI_TRUSTED_PUBLISHING=true` once\n  the PyPI publisher is configured.\n- **Cloud LLM keys are env-var only** — `inclusio` never auto-\n  discovers credentials from disk.\n\nReport vulnerabilities per [`SECURITY.md`](./SECURITY.md).\n\n## Related MCP Servers\n\nSibling MCP servers by the same author — each targets a different agent workflow:\n\n| Server | Purpose |\n|---|---|\n| [`noyalib-mcp`](https://github.com/sebastienrousseau/noyalib) | Lossless YAML 1.2 parsing, formatting \u0026 validation (Rust) |\n| [`rlg-mcp`](https://github.com/sebastienrousseau/rlg) | RustLogs log streams for on-call / SRE agent workflows |\n| [`pain001-mcp`](https://github.com/sebastienrousseau/pain001-mcp) | Generate \u0026 validate ISO 20022 pain.001 payment initiation files |\n| [`bankstatementparser-mcp`](https://github.com/sebastienrousseau/bankstatementparser-mcp) | Parse bank statements (BAI2, MT940/MT942, CAMT.053, OFX, CSV) |\n| [`camt053-mcp`](https://github.com/sebastienrousseau/camt053-mcp) | Parse \u0026 reconcile ISO 20022 camt.053 bank-to-customer statements |\n| [`acmt001-mcp`](https://github.com/sebastienrousseau/acmt001-mcp) | Generate \u0026 validate ISO 20022 acmt.001 account management messages |\n\n---\n\n## MCP Registry\n\n`mcp-name: io.github.sebastienrousseau/inclusio-mcp`\n\nInstall the MCP server with `pip install 'inclusio[mcp]'` (the `mcp` extra pulls in `mcp[cli]\u003e=1.27.0`). Run with `inclusio-mcp` — stdio transport, exposes accessibility-publishing tools to Claude Desktop, Cursor, and other MCP clients.\n\n---\n\n## License\n\n[MIT](./LICENSE). © 2026 Sebastien Rousseau.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsebastienrousseau%2Finclusio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsebastienrousseau%2Finclusio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsebastienrousseau%2Finclusio/lists"}