# Metadata Verifier

Check whether saved titles and descriptions exactly match intended changes. This standalone command-line tool uses **Python's standard library only** and works offline without accounts, API keys, or paid services.

## What it does and where to use it

Use it after updating records in a content management system, document repository, product catalog, learning library, or media archive. Export or prepare an observed snapshot, list your intended updates, and obtain a per-field verification report.

The tool compares **title and description only**. It does not change metadata, contact a publishing service, verify ownership, inspect underlying content, or prove that an exported snapshot is fresh. A match establishes agreement between the supplied files.

## Install

Install Python **3.11 or newer** and copy this folder, or clone the parent repository. There are no packages to install, and the other tool folders are not required.

```console
python --version
python tool.py --help
```

On Windows, `py -3` may be used in place of `python`.

## Quick start

From the **repository root**:

```console
python 03-metadata-verifier/tool.py --catalog 03-metadata-verifier/examples/catalog.json --snapshot 03-metadata-verifier/examples/snapshot.json --batch 03-metadata-verifier/examples/batch.json --output outputs/metadata-report.json
```

From **inside this folder**:

```console
python tool.py --catalog examples/catalog.json --snapshot examples/snapshot.json --batch examples/batch.json --output outputs/metadata-report.json
```

The example passes: its description differs only in Windows/Unix line endings. Open the output JSON to inspect expected and observed values for each field. Paths are relative to the terminal's current folder; missing output directories are created.

## Input format

Use UTF-8 JSON objects (UTF-8 BOM accepted). IDs are case-sensitive, nonempty strings and must be unique in each list. `catalog_id` must match in all inputs.

Catalog (`--catalog`):

```json
{"catalog_id":"my-library","scope_ids":["item-1"],"entries":[{"id":"item-1"}]}
```

Every entry must be included in `scope_ids` exactly once. Additional catalog fields are accepted. A Catalog Reconciler output can be used directly, but is not required.

Snapshot (`--snapshot`):

```json
{"catalog_id":"my-library","items":[{"id":"item-1","title":"Quick Start","description":"Step 1.\nStep 2."}]}
```

Batch (`--batch`):

```json
{"catalog_id":"my-library","batch_id":"change-001","updates":[{"id":"item-1","title":"Quick Start","description":"Step 1.\nStep 2."}]}
```

The batch must contain at least one update. Every update must be in the catalog's scope. Every snapshot/update entry must contain string `title` and `description` values; empty strings are allowed. Unrequested snapshot records are not compared, but their shape and duplicate IDs are still validated.

## Comparison rules

- CRLF (`\r\n`) and CR (`\r`) line endings are normalized to LF (`\n`) in both values before comparison.
- Every other character must match exactly: case, spaces, trailing whitespace, punctuation, and Unicode characters are significant.
- Missing snapshot records are reported as mismatches, with `observed: null`.
- Only the batch's records are checked. A passing batch does not certify the entire catalog.

## Output and operation

The JSON report contains `all_verified`, counts in `summary`, and per-record `results`. Each field includes its `expected` value, `observed` value, and `matches` flag. The original strings are preserved in the report so line-ending differences remain inspectable.

Exit codes are designed for scripts and automation:

| Code | Meaning |
| --- | --- |
| `0` | All requested titles and descriptions match; report written. |
| `1` | One or more mismatches or missing records; report written. |
| `2` | Invalid input, collection/scope mismatch, duplicate IDs, or file error; no new report intentionally written. |

Inputs are never modified. `--output` is required. Existing reports require `--overwrite`; even that flag cannot overwrite any input file. A verification report is separate from the catalog and does not change its review decisions.

## Verify the installation

From this folder:

```console
python -m unittest discover -s tests -p "test_*.py" -v
```

From the repository root:

```console
python -m unittest discover -s 03-metadata-verifier/tests -p "test_*.py" -v
```
