Skip to content

pdf-trust — Incoming Audit

A Skill that audits whether an incoming PDF (contract, invoice, medical document, government filing, …) is genuine, trustworthy, and untampered, and returns a Trust Report with an explicit recommendation.

Principles

  1. Never judge the truth of the content — only authenticity (originality and integrity)
  2. Return verification results as technical facts; the final decision belongs to the user
  3. Always name the grounds for the verdict (which tool, which result)
  4. The judge is code, the narrative is the LLM — the 4-value verdict is decided by pdf-verify's evaluate_policy. The Skill's job is explaining firedRules, recommending actions and citing legal grounds — never overriding the verdict

The 4-value verdict

VerdictMeaning
trust_and_useUsable as-is
use_with_cautionUsable with noted caveats
human_review_requiredNeeds human review
rejectNot acceptable

Required MCPs

MCPRequired / optionalRole
pdf-verify (v0.7.0+, v0.21.0+ recommended)Requiredevaluate_policy, signature verification, tamper detection, PAdES, PDF/A (v0.11.0+ adds PDF/A-4: pdfa-4 / pdfa-4e / pdfa-4fpdfa-4b does not exist)
pdf-readerOptionalObserving signature-field structure, tags, metadata
pdf-specOptionalCiting ISO 32000 grounds for deviations
houki-egov / houki-nta / tax-law / labor-lawOptionalStatutory grounds required by the chosen profile

v0.7.0 is the floor because that is where evaluate_policy arrives at all; v0.21.0+ is what the Skill recommends, because that release moved the top level of verify_signatures / detect_pades_level JSON from an array to an object ({ scope, signatures: [...] } / { scope, levels: [...] }) — reading only the list leaves you unable to notice that the list is incomplete.

How an audit flows (Phases)

PhaseWhat happens
0Confirm the purpose, choose a profile
1Batch verdict over every file with evaluate_policy (4 values)
2Interpret the fired rules, dig deeper
2.5Identify the post-signing changes — lowering "N bytes were added" to "what was written, on which page, where"
3Profile-specific checks (PDF/A, PDF/UA, long-term preservation, …)
4Fetch statutory grounds (when the profile requires them)
5Produce the Trust Report

References like "Phase 2.5" in this site point at this table.

Profiles

ProfileIntended documentsBehaviour
contractContracts, NDAs, purchase ordersSignature required; unsigned → human_review_required
financialInvoices, financial statements, tax filingsLong-term-preservation checks included
legalLitigation materials, legal documentsRequires the full post-signing change history
medicalReferral letters, test reportsMost conservative; caution escalates to review
governmentGovernment documents, public noticesLong-term checks included; unsigned tolerated
generalEverything elseNo extra checks

Measured examples — all 4 verdicts (2026-08-11, real specimens)

SpecimenProfileVerdictFired rules
Self-made CA signature + CRL embedded in the DSS, trust anchor suppliedgeneraltrust_and_useNone (valid + trusted + revocation good)
Japanese official gazette, 2026-08-10 issue (Cabinet Office signature + AMANO timestamp)governmentuse_with_cautionTRUST-NOT-EVALUATED / REVOCATION-UNKNOWN
Same self-made specimen without the CRLgeneraluse_with_cautionREVOCATION-UNKNOWN
Unsigned invoice PDFcontracthuman_review_requiredUNSIGNED-REQUIRED (an image of a signature is not an electronic signature)
Specimen with one byte flipped inside the signed rangegeneralrejectPOL-REJECT-INVALID (digest mismatch)

Rows 1 and 3 differ only in the presence of a CRL (both had the trust anchor supplied). Supplying a trust anchor is not enough — the best verdict is reached only once revocation is confirmed good. With the CRL covering the signer, the PAdES structural observation also rises from B-T to B-LTA (the specimen carries a document timestamp from the start, so satisfying the B-LT condition with the CRL completes the B-LTA structure at the same time): one pair of specimens shows how the verdict and LTV relate.

Trust Report excerpt (from the gazette audit)

Beyond the verdict, Phase 2.5 (verify_integrity + locate_objects) identifies what the "+9,938 bytes after signing" actually are:

ObjectChangeRolePage / rect
64addedform field widgetp.1 / 0,0,0,0 (invisible)
65added/DocTimeStamp signature dictionarynot referenced by any page
54modifiedAcroForm dictionary

→ The post-signing change is the application of the AMANO document timestamp itself (incremental updates are legal — ISO 32000-2 §7.5.6). Phase 2.5's job is lowering "N bytes were added" to "this is what was added". The same audit also recorded: veraPDF judged PDF/UA NOT COMPLIANT (236 untagged content items, 10 rules), and the reference PDF/A measurement was recorded as "not performed" because veraPDF returns no result for the encrypted document — an unmeasured check is never reported as passed.

Installation

sh
/plugin marketplace add shuji-bonji/claude-plugins
/plugin install pdf-verify-mcp@shuji-bonji   # required foundation
/plugin install pdf-trust@shuji-bonji
# optional: pdf-reader-mcp (locations), pdf-spec-mcp (clause citations), houki family (statutory grounds)

Repository: shuji-bonji/pdf-trust-skill (SKILL.md itself and the profile definitions)

Degraded operation

  • pdf-verify not connected → the audit cannot proceed; the Skill says so and stops
  • Old verify (before v0.7.0, no evaluate_policy) → falls back to the manual verdict table and labels the report "manual verdict"
  • Optional MCP missing → the item is recorded as "not performed (tool not connected)" — silently dropping it would read as "checked, no findings"
  • A check that could not be measured (e.g. veraPDF cannot score an encrypted PDF for PDF/A) → recorded as not performed. Undecided is not innocent

MIT Licensed