# EXPECTED — aer1verify.swift verdicts

Ground truth produced by the canonical independent verifier
(`node verify.js <dir>`), which the Swift program ports check-for-check.
Two runs are exercised by `tools/swift_conformance.sh`.

## Run 1 — kit-snapshot/aer-1/test-vectors (30 files, recursive)

Command:

    swift deliverables/aer1/swift/aer1verify.swift \
        deliverables/aer1/kit-snapshot/aer-1/test-vectors

Files are processed sorted by path (`-` sorts before `/`, so
`invalid-profile/` precedes `invalid/`). Expected output, one line per
file:

| file | verdict | first failing check (FAIL lines only) |
|------|---------|----------------------------------------|
| anchored/anchored-bad-id-version.json | FAIL | id is not a UUID v4 (strict profile) |
| anchored/anchored-bad-leaf-hash.json | FAIL | anchor.leaf_hash does not match canonical_bytes |
| anchored/anchored-bad-timestamp.json | FAIL | anchor.anchored_at is not a valid calendar date/time |
| anchored/anchored-missing-proof.json | FAIL | anchor has members other than log/leaf_hash/anchored_at/proof (+1 more) |
| anchored/anchored-valid.json | PASS | |
| invalid-profile/missing-inputs.json | PASS | (core-valid; this is the intentional profile boundary — it fails only under `--profile`) |
| invalid/bad-created-at.json | FAIL | created_at is not RFC 3339 |
| invalid/bad-id.json | FAIL | id is not a lowercase UUID |
| invalid/bad-offset-range.json | FAIL | created_at is not a valid calendar date/time |
| invalid/bad-provenance.json | FAIL | provenance_class is not a known class |
| invalid/bad-verification-status.json | FAIL | verification_status is not verified |
| invalid/base64-unpadded.json | FAIL | canonical_bytes is not valid base64 |
| invalid/bytes-not-base64.json | FAIL | canonical_bytes is not valid base64 |
| invalid/feb29-1900.json | FAIL | created_at is not a valid calendar date/time |
| invalid/feb29-non-leap.json | FAIL | created_at is not a valid calendar date/time |
| invalid/hash-bad-format.json | FAIL | output_hash is not sha256: + lowercase hex digest |
| invalid/hash-mismatch.json | FAIL | output_hash does not match sha256(canonical_bytes) |
| invalid/id-trailing-newline.json | FAIL | id is not a lowercase UUID |
| invalid/impossible-date.json | FAIL | created_at is not a valid calendar date/time |
| invalid/missing-output-hash.json | FAIL | missing required member: output_hash |
| invalid/non-utf8-bytes.json | FAIL | canonical_bytes is not valid UTF-8 |
| invalid/provenance-trailing-newline.json | FAIL | provenance_class is not a known class |
| invalid/tool-empty-name.json | FAIL | tool is not an object with name/version/scope strings |
| invalid/tool-not-object.json | FAIL | tool is not an object with name/version/scope strings |
| invalid/uppercase-id.json | FAIL | id is not a lowercase UUID |
| valid/feb29-leap.json | PASS | |
| valid/fraction-one-digit.json | PASS | |
| valid/receipt-01.json | PASS | |
| valid/receipt-02.json | PASS | |
| valid/receipt-03-live.json | PASS | |

Expected tail:

    CONFORMANCE: 7/30
    exit code: 1

Note on missing-inputs.json: it is intentionally core-valid (the kit's
profile-boundary fixture). verify.js — and therefore this port — reports
PASS for it in default mode; it is rejected only when the
reference-producer profile is enabled (`--profile`). Do not "fix" this to
match the directory name; the boundary is intentional. (Enabling
`--profile` would also fail the legitimate valid/receipt-03-live.json,
whose canonical payload omits "inputs".)

## Run 2 — kit-snapshot/aer-1/frozen-vectors/v1.3.0 (18 files, flat)

Same format as test-vectors (receipt fixtures + a MANIFEST.txt carrying
sha256 checksums only). Expected:

| file | verdict |
|------|---------|
| anchored-bad-leaf-hash.json | FAIL |
| anchored-bad-timestamp.json | FAIL |
| anchored-missing-proof.json | FAIL |
| anchored-valid.json | PASS |
| bad-created-at.json | FAIL |
| bad-id.json | FAIL |
| bad-provenance.json | FAIL |
| bytes-not-base64.json | FAIL |
| hash-bad-format.json | FAIL |
| hash-mismatch.json | FAIL |
| impossible-date.json | FAIL |
| missing-inputs.json | PASS (profile boundary, see note above) |
| missing-output-hash.json | FAIL |
| non-utf8-bytes.json | FAIL |
| receipt-01.json | PASS |
| receipt-02.json | PASS |
| receipt-03-live.json | PASS |
| tool-not-object.json | FAIL |

Expected tail:

    CONFORMANCE: 5/18
    exit code: 1

## Judgment calls vs verify.js (documented, not silently changed)

- Directory scanning is recursive; verify.js read only top-level *.json.
  Required so the nested test-vectors layout works as a single target.
  For flat dirs (v1.3.0) behavior is identical.
- Parse failure reason is "not valid JSON" (verify.js appends the JS
  error message, which has no Swift equivalent).
- `--json` output uses JSONSerialization pretty printing (field order may
  differ from JS JSON.stringify indentation).
- verify.js's unreadable-file crash becomes a FAIL line (fail closed).

Everything else — check order, failure strings, strict/chain06/profile/
anchor flags, auto kind detection — is a verbatim port.
