Files
magnus919_agent-skills/documents/references/output-quality.md
T
Magnus HedemarkGitHubfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
c49666e29a feat(skill): add documents family skill (PDF / Word / Excel / PowerPoint) (#262)
* feat(skill): add documents family skill (PDF / Word / Excel / PowerPoint)

One family skill for PDF, Word (.docx), Excel (.xlsx), and PowerPoint
(.pptx) per the family-skill rule (epub precedent): shared workflow in
SKILL.md (scope, content model, template, render, validate, deliver) with
per-format load-on-demand references, generation templates per format, a
stdlib validation script (--json, structural sanity + render check with
graceful degradation), one fixture per format, a unittest suite, six
output-quality eval cases spanning all four formats, a human README, the
README.md index entry, and regenerated catalogs.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>

* fix(skill): dispatch PDF renderer args per binary in documents validation

The render check passed pdftoppm-only flags (-png/-r/-f/-l) to mutool and
ghostscript, which reject them, so a machine with only mutool or gs would
false-FAIL valid PDFs. Dispatch per-renderer argument sets (pdftoppm -png;
mutool draw -o; gs -sDEVICE=png16m) and cover the dispatch with a unit test.
Also: count PDF pages via the /Count page-tree fallback (page objects can
hide in compressed ObjStm streams), drop the stale "unsupported input" exit-2
claim from the docstring, and stop labeling skipped files with a FAIL check.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>

* style(skill): drop redundant local tempfile import in renderer dispatch test

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>

---------

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-08-03 17:36:00 -04:00

107 lines
4.5 KiB
Markdown

# Output-Quality Validation — All Four Formats
> **Last Updated:** 2026-08-03
Load this reference when you need to **verify a produced document before
delivery**, regardless of format. It is step 5 (validate) of the shared
workflow in `SKILL.md`, expanded into a checklist that applies to PDF, Word,
Excel, and PowerPoint alike, plus the exact behavior of the validation script.
## Why validate at all
The most common document defects are structural, not typographical: a file
that opens in one application and corrupts in another, a spreadsheet whose
cells are invisible to formulas, a deck whose slides do not render. Structural
validation catches these before delivery, cheaply and deterministically, and a
render check catches the next class (layout, fonts, overflow) whenever a
renderer is available.
## Two layers of checking
### 1. Structural sanity (always available, stdlib only)
The validation script checks properties that any reader depends on:
| Format | Checks |
|--------|--------|
| PDF | `%PDF-` header, `%%EOF` trailer, at least one page object |
| Word (.docx) | ZIP container, `[Content_Types].xml`, `word/document.xml` well-formed |
| Excel (.xlsx) | ZIP container, `[Content_Types].xml`, `xl/workbook.xml` + worksheet parts well-formed |
| PowerPoint (.pptx) | ZIP container, `[Content_Types].xml`, `ppt/presentation.xml` + slide parts well-formed |
These checks need no third-party packages, so validation always runs.
### 2. Render check (best effort, graceful)
When an external renderer is installed, the script additionally **renders the
file** — `pdftoppm`/`mutool`/`gs` rasterize PDF page 1; LibreOffice converts
Office formats to PDF. When no renderer is available for a format, the render
check reports `unavailable` in the JSON and exits 0: a missing renderer is an
environment fact, not a document defect. Never block delivery on a render
check you could not run; say so in the provenance instead.
## Running the validation script
```bash
python3 scripts/validate-documents.py report.pdf brief.docx data.xlsx deck.pptx
python3 scripts/validate-documents.py --render-check --json report.pdf data.xlsx
```
Exit codes:
- **0** — every file passes structural validation (and any attempted render
succeeded, or no renderer was available).
- **1** — at least one file fails structure or an attempted render failed.
- **2** — usage/I/O error (missing or unreadable path).
JSON report (`--json`): top-level `status` is `ok`, `fail`, `unavailable`, or
`error`; each file carries per-check results and a `render` object. The
`summary` block gives the pass/fail/skip/error counts.
## Content-completeness checks
Structure passing does not mean the content is right. Before delivery, confirm
the artifact matches the agreed scope:
- **Expected sections present** — the scope's headings/slides/sheets all exist.
- **No placeholder remnants** — no unresolved `[fill: ...]` markers, `TODO`
text, or lorem ipsum from the template.
- **Data intact** — for Excel, spot-check cell values against the source data;
for prose, check a few paragraphs verbatim.
- **Metadata set** — title/author where the reader displays it.
## Visual and layout quality
Renderer-dependent, so verify when a renderer is available or by opening the
artifact:
- **No overflow** — text fits boxes/cells/slides; no clipped content.
- **No missing glyphs** — fonts embedded (PDF) or available (Office); no
`tofu` boxes.
- **Consistent styling** — headings use styles; decks use one layout family.
- **Page/slide count matches the scope** — no blank trailing pages/slides.
## Accessibility basics
Accessibility is part of output quality, not a separate concern:
- **PDF** — tagged PDFs with real text (not scans) and a reading order.
- **Word** — heading styles (they become the navigation/outline), alt text on
images, real tables with header rows.
- **Excel** — header rows on row 1, no blank separator rows inside tables,
meaningful sheet names.
- **PowerPoint** — alt text on images, sensible shape reading order, notes.
## The deliverable gate
A document is ready to deliver when:
1. `scripts/validate-documents.py` exits 0 on it (structure passed).
2. The render check is `ok` (renders) **or** honestly reported as
`unavailable` (no renderer present).
3. Content-completeness and visual checks pass against the scope.
4. The provenance records the content model, template version, and validation
result, so the artifact can be regenerated and re-verified.
Anything less is a known deviation — record it rather than hiding it.