Metadata-Version: 2.4
Name: vdi2770-validate
Version: 0.5.0
Summary: Offline conformance checker for VDI 2770 containers — every finding comes with a remedy
Author: Wooyong Lee
License: Apache-2.0
Keywords: vdi2770,technical documentation,conformance,validation,industry 4.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Manufacturing
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
License-File: THIRD_PARTY.md
Requires-Dist: vdi2770~=0.3.0
Requires-Dist: xmlschema==4.2.0
Provides-Extra: dev
Requires-Dist: pytest==8.3.4; extra == "dev"
Requires-Dist: ruff==0.16.3; extra == "dev"
Dynamic: license-file

# vdi2770-validate

Point it at a VDI 2770 container and it tells you, offline, whether the archive is
one — and if something is wrong, what to do about it.

VDI 2770 is how manufacturers hand over technical documentation in the process
industry: PDFs bundled into ZIP "document containers" with an XML metadata file,
those bundled into a "documentation container". Operators in the process industry
increasingly ask for it in purchase orders, and a container rejected on intake holds
up a delivery. The reference implementation is a Java library and web service; this
is a small offline CLI you can drop into a CI job.

**Unofficial.** Not affiliated with VDI, the Digital Data Chain Consortium, or IDTA.
Names are used descriptively.

```
$ vdi2770-validate check corpus/examples/missingdocuments/folders.zip
  error  F1  A file named in the metadata is not in the container
         at folders.zip!/VDI2770_Main.xml:56:2
         'VDI2770_Main.pdf' is declared but not in the archive
         -> Add the missing file to the container, or remove its DigitalFile entry from the metadata. The two must agree.
  error  Z7  The documentation container has no VDI2770_Main.pdf
         at folders.zip
         -> Add the main document as VDI2770_Main.pdf at the root of the documentation container, next to VDI2770_Main.xml.
  warn   F2  A file in the container is not named in the metadata
         at folders.zip!/456-29201/VDI2770_Metadata.xml
         -> Declare the file as a DigitalFile in the metadata, or remove it from the container. An undeclared file is invisible to the recipient's system.
  warn   F2  A file in the container is not named in the metadata
         at folders.zip!/456-29201/demo.pdf
         -> Declare the file as a DigitalFile in the metadata, or remove it from the container. An undeclared file is invisible to the recipient's system.
  warn   F2  A file in the container is not named in the metadata
         at folders.zip!/456-29201/demo.xlsx
         -> Declare the file as a DigitalFile in the metadata, or remove it from the container. An undeclared file is invisible to the recipient's system.
  warn   F2  A file in the container is not named in the metadata

  … 6 more warnings of the same kind
```

That is real output on a container that ships with this repository, so the same command works after cloning.

## What it will not tell you

**Whether a PDF really is PDF/A.** That needs a full PDF/A validator such as
veraPDF. This tool reports what a file *claims*, which catches the common failure:
files that never claimed at all. It says so on every line where it matters, and the
JSON output carries `"pdfaVerified": false` on every path. The rest of the refusals
are in [docs/scope.md](docs/scope.md).

## How it is built

- **Offline by design.** No network at runtime, proven by a test that makes sockets
  raise. Nothing is extracted to disk; a supplier archive does not get to pick a
  path on your filesystem or expand an XML entity.
- **Rules are data.** [`rules.json`](src/vdi2770_validate/data/rules.json) — each
  rule carries where its requirement comes from, a remedy sentence, and — where the
  reference implementation checks the same thing — the message keys it uses.
- **23 of 34 rules have a minimal fixture pair** — a container that violates the rule
  and a conforming one differing in as little as a single member. The rest are exercised
  by the vendored corpus. A rule that fires nowhere fails the build.
- **Rules cannot reach the parser.** A test fails if a rule module imports `zipfile`
  or an XML library, so a rule cannot accidentally check how a document was spelled
  instead of what it says. Rules may read the readers' constants — the reserved file names, the container kinds — but not call a parser.

## Two packages

The reader lives in [`vdi2770`](https://pypi.org/project/vdi2770/), a separate
package with no dependencies: it opens a container, refuses what it should refuse,
and hands back a typed model with a line number on every node. It decides nothing.

This package is that library plus a rule set. The split is not cosmetic — a test
fails if the reader can so much as import the rules — and it exists because a rule
set is an opinion. If your customer's supplement disagrees with ours, or you want
the parsed model for something other than a verdict, take the reader and leave the
opinion behind:

```bash
pip install vdi2770
```

## The classification table, and a disagreement

VDI 2770 defines twelve document classes. Two sources publish that table for free —
IDTA 02004 v2.0.1 Table 1, and the MIT reference implementation. Both renderings of
every name are stored, so you can check rather than trust: **they agree on all twelve
German names and disagree on five English ones** (02-03, 02-04, 03-01, 03-04,
04-01). So matching here is keyed on the class id and the German name, and an
English name never fails a document — it produces a note that shows both renderings.

```
$ vdi2770-validate classes
02-03  Bauteile    Assemblies   [sources disagree]
      IDTA 02004: 'Assemblies'   reference impl: 'Components'
```

Details in [docs/divergences.md](docs/divergences.md).

## Licensing

Apache-2.0. The VDI 2770 guideline text is sold by DIN Media and was **not** read,
quoted, or paraphrased. Every rule names its source in `rules.json` instead: the schema
VDI publishes free, a freely published table, ZIP and XML mechanics, the MIT reference
implementation (observed there, not verified against the standard), or a judgement of
our own that has to explain itself.
See [docs/licensing.md](docs/licensing.md) and [NOTICE](NOTICE).

Contributions take a `Signed-off-by` line (DCO).

## Related

[iirds-validate](https://github.com/dev365code/iirds-validate) — the same idea for
iiRDS. [standards-watch](https://github.com/dev365code/standards-watch) — a daily
watch on these standards.
