| name | pdfium-agents-validator |
| description | 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
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires pdfium-render 0.8,0.9. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
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
- Read the code and the version line it targets (default: 0.9.x).
- Apply rule sets A, B, C, and D below, in order.
- Record every finding with the output format at the end of this file.
- If any check FAILS, return the corrected code with each fix applied.
- 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.