Skip to content

Rules

wacz-validator runs a fixed set of rules over an archive and reports one issue per violation. The table is generated from the rule definitions themselves, so it cannot fall behind the code: name, severity, conformance level, per-profile overrides and spec links all come out of packages/core/src/validate/.

Conformance is what the spec demands — MUST, SHOULD, MAY, MUST NOT. Severity is what wacz-validator does about a violation.

Severity takes one of three values. Only error decides the verdict — an archive is usable exactly when summary.failed (the error count) is zero, and no number of warnings or infos overturns that.

Severity Meaning summary.failed
error the archive cannot be used — replay breaks, or the check cannot be made incremented
warning worth fixing, but not broken on its own unaffected
info an observation, carrying no judgement unaffected

Severity is decided by one thing only: whether the archive is usable. So datapackage/resources-complete is a MUST reported as a warning — an incomplete resources[] does not by itself break replay.

When you want the conformance view, read the conformance column. Handling the two axes separately is covered in JSON report.

A rule can report at different severities depending on what it finds. When it does, the severity column lists every value it can emit.

datapackage/digest reads warning / error: a missing digest file only falls short of a SHOULD, so it is a warning; a file that is present but whose hash does not match may mean the archive was altered, so that is an error. Same rule, different finding, different treatment.

Any rule whose severity column lists more than one value is like this.

MUST, MUST NOT, SHOULD, SHOULD NOT and MAY carry their RFC 2119 meanings. The conformance column is copied from the specification, not wacz-validator’s own grading of how much a rule matters.

The severity column carries the per-profile values

Section titled “The severity column carries the per-profile values”

The first line of the severity column is the default (--profile spec); the smaller lines under it are the per-profile overrides. A rule with nothing underneath reports the first line everywhere.

Not every finding from a rule necessarily moves, so a count is shown when more than one does. A line like browserhive: >=1.11.0 is a producer version range: name a version outside it (--profile browserhive@1.10.0) and the rule does not run, which the report records under skipped. Conformance never moves with the profile — it is what the spec says. See Profiles.

Rule / specSeverity (per profile)Conformance
browserhive/axtree-shapeBrowserHive WACZ Profile §accessibilityerrorbrowserhive: >=3.8.0MUST
browserhive/behaviors-shapeBrowserHive WACZ Profile §behaviorserrorbrowserhive: >=8.6.0MUST
browserhive/deny-enforcedBrowserHive WACZ Profile §urlPolicieserrorMUST
browserhive/dismissal-shapeBrowserHive WACZ Profile §dismissalerrorbrowserhive: >=8.5.0MUST
browserhive/document-withheldBrowserHive WACZ Profile §documenterror / warningbrowserhive: >=13.0.0MUST
browserhive/policy-not-truncatedBrowserHive WACZ Profile §completenesserrorbrowserhive: >=12.2.0MUST
browserhive/settings-shapeBrowserHive WACZ Profile §settingserrorbrowserhive: >=8.0.0MUST
browserhive/settle-deadlineBrowserHive WACZ Profile §settlewarningbrowserhive: >=10.3.0MAY
browserhive/settle-shapeBrowserHive WACZ Profile §settleerrorbrowserhive: >=10.3.0MUST
browserhive/storage-inventoryBrowserHive WACZ Profile §storageerrorbrowserhive: >=6.0.0MUST
browserhive/storage-shapeBrowserHive WACZ Profile §storage directoryerrorbrowserhive: >=6.0.0MUST
browserhive/tls-chainBrowserHive WACZ Profile §tlserror / infoMUST
browserhive/tls-sanBrowserHive WACZ Profile §tlserrorbrowserhive: >=3.7.0MUST
browserhive/url-policiesBrowserHive WACZ Profile §URL and media type policieserrorbrowserhive: >=8.0.0MUST
browserhive/window-shapeBrowserHive WACZ Profile §windowserrorMUST
cdxj/filename-archive-relativeWACZ §indexeserrorlenient: warning (2 件)MUST
cdxj/index-not-gzippedWACZ §indexeswarningbrowserhive: error (2 件)lenient: info (2 件)MAY
cdxj/index-recognised-by-wabacWACZ §indexeserror / warningMUST
cdxj/index-valid-dataWACZ §indexeserrorMUST
cdxj/pages-mainpageWACZ §pageswarninglenient: info (2 件)SHOULD
cdxj/warc-offsetsWACZ §indexeserrorlenient: warning (3 件)MUST
datapackage/digestWACZ §datapackage-digest.jsonwarning / errorlenient: infoSHOULD
datapackage/frictionless-schemaFrictionless Data PackagewarningSHOULD
datapackage/frictionless-structureFrictionless Data Package §requiredFrictionless Data ResourceerrorMUST
datapackage/profile-requiredWACZ §datapackage.jsonFrictionless Data PackageerrorMUST
datapackage/resource-hashesWACZ §datapackage.jsonFrictionless Data ResourceerrorMUST
datapackage/resources-completeWACZ §datapackage.jsonwarninglenient: infoMUST
datapackage/wacz-version-requiredWACZ §datapackage.jsonerror / warninglenient: warning (2 件)MUST
pages/page-schemaWACZ §pageswarninglenient: info (2 件)MUST
wacz-auth/signaturewacz-auth 0.1.0 §Domain-Ownership Identityerror / infoMUST
wacz/required-filesWACZ §directories-and-fileserrorMUST
wacz/reserved-dirs-cleanWACZ §directories-and-fileswarninglenient: infoMUST NOT
warc/extension-gzip-matchWACZ §archivewarninglenient: info (2 件)MUST
warc/members-independentWARC 1.1errorMUST
warc/payload-digestWARC 1.1info / warningSHOULD
warc/recording-completeWARC 1.1 metadata recordwarning / infobrowserhive: >=1.11.0MAY
warc/storage-storeWACZ §archivewarninglenient: infoSHOULD

Rules fall into groups by the layer they inspect:

  • wacz/* — the ZIP layout itself: which files and directories must exist, and what must not be in the reserved ones.
  • datapackage/* — datapackage.json: the Frictionless structure, the declared profile, the WACZ version, and whether the hashes match what is actually in the archive.
  • cdxj/* — the index: whether wabac.js can load it, whether its offsets point at real WARC records, and whether the filenames are archive-relative.
  • warc/* — inside the WARC: independently-decodable gzip members, payload digests, and whether the recording is complete.
  • pages/* — pages/pages.jsonl against its schema.

Two rules can look at the same file for different reasons, and that is deliberate. wacz/required-files asserts that an index simply exists; cdxj/index-recognised-by-wabac asserts that wabac.js can actually load it. An archive can pass the first and fail the second, and the distinction is what tells a producer where the problem is.

Likewise wacz/required-files owns the “is datapackage.json there at all” question, so datapackage/profile-required can concentrate on the value of profile without reporting the same absence twice.

A rule is a file under packages/core/src/validate/rules/ and an entry in that directory’s index.ts. Both steps are required: an unregistered rule never runs. The docs build counts the two and fails if they disagree, so a forgotten registration cannot ship quietly.