Search by

kraenzle-ritter / preservation-strategy

ottosmops

A machine-readable preservation strategy for archives: JSON Schema (Draft 2020-12), a framework-free validator and an export of its rules as PAR Business Rules.

Package info

github.com/kraenzle-ritter/preservation-strategy

pkg:composer/kraenzle-ritter/preservation-strategy

Statistics

Installs: 22

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-11-03 15:50 UTC

This package is auto-updated.

Last update: 2026-11-04 06:21:43 UTC


README

CI License PHP Version

An archive's digital preservation strategy, machine-readable: who is responsible for what, which measures may be taken without asking, what is excluded, which rules apply, and how it relates to the NDSA Levels and the DPC Rapid Assessment Model. A JSON Schema (Draft 2020-12), two examples, a framework-free PHP validator, and an export of the rules as PAR Business Rules.

Written for Anton, the archival information system of Kränzle & Ritter, where an archive gives a preservation mandate in one of two variants. It can be used without Anton.

Why

Format rules have registries: Archivematica's Format Policy Registry, the Preservation Action Registries (PAR), our own format-policy. They say which tool does what to which format. They do not say who decides, what may happen without asking, or what is left alone. That is what a preservation strategy has to say, and what this schema adds. Where a rule is concerned, it follows PAR.

The document

Field What it says
id, version, issued, validFrom, supersedes the strategy, its version (Fassung) and dates; id stays across versions
archive name, ISIL, tenant
variant kr: the provider carries digital preservation (package «Technische Betreuung»); own: the archive carries it, the provider migrates on its order
writtenBy provider under kr, archive under own
policy the preservation policy it rests on
responsibilities overall, digitalPreservation, logReview, formatRiskAssessment, formatList, formatRules, migration: a role each (archive, provider, shared), never a person
riskAssessment sources consulted (e.g. NARA), and whether they bind
measures lossyAllowed; consultation: ask for each measure, or only above the booked storage and for extraordinary effort
exclusions formats (PUIDs) and holdings (persistent addresses) no measure touches
ingest keep the delivered file when a conversion on ingest changes it; report or reject invalid files
findings days within which the provider reports a damaged or missing file
formatPolicy the catalogue the rule keys come from
businessRules the rules, shaped after the PAR Business Rule (below)
standards NDSA Levels (level per area, who carries which requirement) and DPC RAM (sections A–K)
extensions anything else, under keys starting with x-

The schema checks what follows from the variant: under own the archive writes the file, carries digital preservation and is asked for each measure; under kr the provider does, asks only about storage and effort, and names a format policy. The overall responsibility is always the archive's. Without lossyAllowed, every rule in phase preservation keeps the ingested file.

See examples/kr.json, the strategy Kränzle & Ritter writes for an archive with the package «Technische Betreuung», and examples/own.json, an archive's own. Names and numbers in them are examples.

Rules

Field PAR Business Rule
id id.name unique within the strategy; the strategy's id is the namespace
description, notes same
formats formats PUIDs instead of parIdentifier
formatFamilies formatFamilies labels
preservationActionTypes preservationActionTypes PREMIS event type codes (mig, nor, val, …), as PAR uses them
preservationActions preservationActions a formatPolicyRule key or a PAR action guid, with priority
phase – preingest (its result is the ingested file) or preservation
targetFormats – (openpreserve/par#38) formats a migration may produce
keepsOriginal – whether the file before the rule stays
inForce, decided – in force; decided by whom and when

Versions and confirmation

A changed strategy takes a new version. Whether a new version needs a new confirmation is the program's to decide. In Anton: under kr, a rule Kränzle & Ritter adds or changes gives a new version without a new confirmation; the archive confirms again when its own choices change (variant, lossyAllowed, exclusions, ingest, findings) or when the storage needed grows beyond what is booked.

Installation

composer require kraenzle-ritter/preservation-strategy

Usage

use KraenzleRitter\PreservationStrategy\Validator;

$result = (new Validator())->validate($json);   // string | array | stdClass

$result->valid;        // false as soon as one finding is an error
$result->errors;       // list<ValidationError>: path, keyword, message, warning
$result->warnings();   // the findings that leave it valid

Beyond the schema, the validator checks that every rule id occurs once, and warns when an excluded format is named by a rule in force (the exclusion wins). Given the catalogue the rule keys come from, it also checks that each key exists, is not retired, and converts into the formats the strategy says:

use KraenzleRitter\PreservationStrategy\ArrayFormatPolicyRules;

$catalogue = new ArrayFormatPolicyRules([
    'pdfx_pdfa2b' => ['target' => ['fmt/477']],
    'tiff_zip' => [],
]);
$result = (new Validator($catalogue))->validate($json);

Implement FormatPolicyRules to read the catalogue from elsewhere, e.g. from kraenzle-ritter/format-policy's repository.

Export to PAR

use KraenzleRitter\PreservationStrategy\ParExport;

$rules = (new ParExport())->businessRules($json);   // list of PAR Business Rules (v1.2.0)

Rules in force only. Formats are named in the PRONOM namespace, actions by their format-policy key; what PAR has no field for (phase, target formats, whether the original is kept) goes into notes. Each parIdentifier gets a UUID v5 as its guid: for the namespace url over the name, otherwise over the name within a UUID v5 of the namespace. The tests validate the export against the PAR schemas.

Sources

Testing

composer test       # PHPUnit
composer analyse    # PHPStan

License

MIT