# Pdfium Agents Validator

> Use when reviewing or validating generated pdfium-render code before accepting it: checking for removed 0.8.x API names, binding mistakes, byte-order bugs, lifetime errors, and version inconsistency. Prevents shipping code that uses PdfBitmapConfig, get_bitmap, as_bytes or other removed names, binds the library per request, swaps red and blue channels, or mixes 0.8.x and 0.9.x names in one file. Covers the removed-name scan, binding correctness, API-usage correctness, cross-skill consistency, and a deterministic review output format. Keywords: pdfium-render code review, validate pdfium code, check pdfium-render code, PdfBitmapConfig removed, get_bitmap removed, as_bytes removed, load_pdf_from_bytes removed, 0.8 0.9 version trap, deprecated pdfium API, review checklist, BGRA RGBA swap, bind once, Pdfium::default panic, lifetime error pdfium, is this pdfium code correct, audit generated pdfium code

- Skill: `impertio-studio/pdfium-agents-validator` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add impertio-studio/pdfium-agents-validator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/impertio-studio/pdfium-agents-validator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- License: MIT
- Author: Impertio-Studio (https://skillmd.com/u/impertio-studio)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/impertio-studio/pdfium-agents-validator

---


# pdfium-agents-validator

A deterministic code-review checklist for generated pdfium-render code. Run it
over any pdfium-render snippet BEFORE accepting it. Each check has an explicit
FAIL condition; a snippet passes only when every check passes.

Scope: reviewing code, not writing it. The validator references the other 25
skills in this package and names the one that governs each correct API. For
orchestrating skill use during generation see `pdfium-agents-orchestrator`.

Default API surface is 0.9.x. The single largest source of failures is code
written against removed 0.8.x names.

## How to run the review

1. Read the code and the version line it targets (default: 0.9.x).
2. Apply rule sets A, B, C, and D below, in order.
3. Record every finding with the output format at the end of this file.
4. If any check FAILS, return the corrected code with each fix applied.
5. The review passes only with zero FAIL findings.

Worked review sessions are in `references/examples.md`. The full rule reference
is in `references/methods.md`.

## Rule set A: removed 0.8.x name scan

FAIL when any of these names appears. Each was removed in the 0.9.0 cleanup
release. Replace with the 0.9.x name.

| Removed name (FAIL) | 0.9.x replacement |
|---------------------|-------------------|
| `PdfBitmapConfig` | `PdfRenderConfig` |
| `PdfPage::get_bitmap()` | `render()` |
| `PdfPage::get_bitmap_with_config()` | `render_with_config()` |
| `PdfBitmap::as_bytes()` | `as_raw_bytes()` or `as_rgba_bytes()` |
| `PdfBitmapRotation` | `PdfPageRenderRotation` |
| `set_matrix()` / `set_matrix_with_clip()` | `apply_matrix()` / `apply_matrix_with_clip()` |
| `load_pdf_from_bytes()` | `load_pdf_from_byte_slice()` / `load_pdf_from_byte_vec()` |
| `PdfFont` direct constructors | `PdfFonts` collection constructors |
| `Pdfium::get_bindings()` | `bindings()` |
| `PdfColor::SOLID_*` constants | the renamed `PdfColor` constants |
| `PdfPageGroupObject::copy_onto_new_page_*` | `copy_to_page()` |

Verified on docs.rs: `PdfBitmapConfig` and `PdfBitmapRotation` are ABSENT from
the 0.9.x prelude; `get_bitmap` / `get_bitmap_with_config` are ABSENT from
`PdfPage`. Their replacements are all PRESENT.

### A-extra: bounds() return type

FAIL when `PdfPageObject::bounds()` is used as a `PdfRect`. Since 0.8.28 it
returns `PdfQuadPoints`. `PdfRect` still exists, so this is a silent type
mismatch. Governing skill: `pdfium-core-coordinates`.

## Rule set B: binding correctness

| Check | FAIL condition |
|-------|----------------|
| B1 Bind once | A `bind_to_*` call or `Pdfium::default()` appears in a loop or request handler. |
| B2 Graceful binding | `Pdfium::default()` is used where a missing library must be reported. It returns `Self`, not `Result`, and panics when no library loads. |
| B3 API-version pin | No `pdfium_*` crate feature is pinned to the bound binary's Chromium build. |
| B4 Raw FFI safety | A raw `FPDF_*` call is not inside an `unsafe` block. All raw bindings are `unsafe` since 0.9.0. |

Governing skills: `pdfium-errors-binding`, `pdfium-impl-performance`,
`pdfium-core-bindings-setup`, `pdfium-core-raw-ffi`.

## Rule set C: API-usage correctness

| Check | FAIL condition |
|-------|----------------|
| C1 Password | A password is passed any way other than `Option<&str>` on a `load_pdf_from_*` call. There is no separate password function. |
| C2 Byte order | `as_raw_bytes()` output is fed to the `image` crate as RGBA. PDFium bitmaps are BGRA-family; use `as_rgba_bytes()`. |
| C3 Lifetimes | A struct stores a `Pdfium` or `PdfDocument` together with a borrowed child handle. |
| C4 Thread safety | PDFium handles are shared across threads expecting a speedup. The `thread_safe` feature serializes behind a mutex with no speedup. |
| C5 Object moves | Page objects cross documents via hand-rolled remove-then-insert instead of `copy_to_page()` / `move_to_page()`. |
| C6 Form render | A filled form is rendered without `render_form_data(true)`. |
| C7 Save after edit | An edit is made with no following `save_to_*` call. |
| C8 Flatten target | `flatten()` is used on a form document below pdfium-render 0.8.19. |
| C9 WASM build | A WASM target uses the non-growable bblanchon WASM build for multi-page documents. |

Governing skills: `pdfium-syntax-document-loading`,
`pdfium-impl-output-formats`, `pdfium-core-memory`,
`pdfium-core-architecture`, `pdfium-impl-page-objects-edit`,
`pdfium-impl-form-fields`, `pdfium-impl-saving`,
`pdfium-impl-page-manipulation`, `pdfium-impl-wasm`.

## Rule set D: cross-skill and version consistency

| Check | FAIL condition |
|-------|----------------|
| D1 Single version line | One file mixes a removed 0.8.x name with a 0.9.x name. |
| D2 Skill references | A cited skill name is not one of the 26 in the package inventory. |

The 26-skill inventory is listed in `references/methods.md`. A reference is
valid only when it names a skill in that list.

## Review decision tree

```
Any rule set A name present?        -> FAIL A. Replace, then re-scan.
Binding in a loop / handler?        -> FAIL B1. Bind once via OnceLock.
Pdfium::default() in library code?  -> FAIL B2. Use bind_to_* + Pdfium::new.
Raw FPDF_* call outside unsafe?     -> FAIL B4. Wrap in unsafe.
as_raw_bytes() into the image crate?-> FAIL C2. Use as_rgba_bytes().
Parent + child in one struct?       -> FAIL C3. Own the parent higher up.
Edit with no save_to_* after it?    -> FAIL C7. Add the save call.
0.8.x and 0.9.x names in one file?  -> FAIL D1. Pick one version line.
All checks pass?                    -> PASS. Accept the code.
```

## The review output format

Report every finding as one line:

```
[PASS|FAIL] <rule> : <file>:<line> : <description> -> <fix>
```

Example:

```
FAIL A : render.rs:7 : PdfBitmapConfig removed in 0.9.0 -> use PdfRenderConfig
FAIL C2 : render.rs:11 : as_raw_bytes into image crate -> use as_rgba_bytes
PASS B1 : binding is performed once at startup
```

A review with zero FAIL lines passes. A review with one or more FAIL lines does
not pass: return the corrected code with every fix applied, then re-run the
checklist on the corrected code.

## Common review mistakes

| Mistake | Correct approach |
|---------|------------------|
| Accepting `PdfBitmapConfig` because it reads plausibly | it was removed; only `PdfRenderConfig` exists in 0.9.x |
| Passing a removed name through because it "probably still works" | 0.9.0 removed it; the code will not compile |
| Treating a BGRA-versus-RGBA swap as a cosmetic detail | it is a real bug (#50); flag C2 as FAIL |
| Ignoring a mixed-version file because each name exists somewhere | D1 is FAIL: one file targets one version line |
| Citing a skill name not in the inventory | D2 is FAIL: verify against the 26-skill list |

## Reference files

- `references/methods.md`: the complete rule set and the 26-skill inventory.
- `references/examples.md`: worked review sessions with corrected code.
- `references/anti-patterns.md`: the anti-patterns the validator detects.

## Related skills

- `pdfium-agents-orchestrator`: drives skill selection during code generation.
- All 24 syntax, core, impl, and errors skills: each governs the correct API
  for one area; the validator names the governing skill in every finding.

