# AER-1 negative must-fail corpus (arion-aer1-negative-must-fail v1.2.0)

**v1.2.0 — rebound to the published -09 kit.** The vendor re-ran v1.1.0
through the -09 oracle: 37/50 legacy cases agreed; 13 drifted (-08→-09).
v1.2.0 rebinds all 13 to -09 field names and kit-verbatim reasons —
**67/67 cases now agree with the -09 kit oracle**. Full old→new table and
per-case section citations: `REBASE-109.md`. Verifier parity: `verify.js`
gained the -09 disinterested-tier strict-id check (kit `checkDisinterestedTier`).
Kit-side replay: `node kit-oracle.js [kit-root]`.

Companion to the draft-zambo-aer1-09 conformance kit: the kit ships mostly
labeled valid/invalid vectors; this corpus pins **exactly which check must
fire and with what reason**, generated from real mutants of the kit's own
valid vectors.

## What a case is

`manifest.json` carries `cases[]`:

- `file` — the mutant document (JSON)
- `group` — receipt | anchor | chain | commitment09 | workflow
- `flags` — verifier profile the case was generated under
  (`strict`, `profile`, `kind`)
- `spec` — the draft section the mutated rule lives in
- `mutation` — plain-text description of what was changed
- `expect` — the **exact** `[{check, reason}]` failure set

A verifier conforms to a case when it rejects the document and its failure
set equals `expect` — expected failures absent OR unlisted failures present
both count as non-conformance. For third-party implementations, map `check`
names to yours; `reason` is a human string (pin the clause, not the prose).

## Mutant construction

Every case derives from a vector that verifies clean (receipt-01,
anchored-valid, v07-valid-5, v07-seq-float-valid, a constructed 5-step
workflow over the canonical merkle vector). Chain mutants are **relinked**:
after mutating entry i, all downstream `prev_digest` values are recomputed
against the mutated digest — the same way a real adversary repairs a forged
chain — so the surviving failure names the mutated rule exactly, not the
collateral link damage. Most cases isolate a single check; the
multi-failure cases are genuinely coupled rules (member-set + type on
anchor.proof removal, non-boolean + unclosed on close:"yes", a duplicate
receipt_id with an unrepaired merkle_root on w05, per-entry job_id fan-out
on a commitment job mismatch, and the cm12 two-check splice below).

## -09 §7.3 chain commitment (group `commitment09`)

The -09 draft defines a chain commitment artifact: a JSON document,
published outside the chain, binding the timeline's identity, length, and
final entry digest. Corpus docs carry it as `{"timeline": [...],
"commitment": {...}}`; `verify.js` runs check **`chain-commitment(-09)`**
(mirroring the kit's `verifyChainCommitment`, reason strings verbatim):

- `job_id` — non-empty string, must equal **every** entry's job_id
- `final_entry_digest` — 64 lowercase hex, must equal the §7.1 recomputed
  digest of the last entry (recompute fails closed on bad base64:
  `final entry digest could not be recomputed: ...`)
- `entry_count` — integer, must equal `timeline.length`
- `published_at` — RFC 3339 shape **and** a valid calendar date/time

Member-shape failures abort the binding checks; additional members are
ignored (pinned by positive case cm04). Positive cases (expect `[]`) cover
the valid artifact, an offset+fractional-seconds timestamp, a single-entry
timeline, and an ignored extra member. Negatives isolate each rule: digest
mismatch/uppercase/length, count mismatch/float/string, commitment-job
mismatch (5-way per-entry fan-out), published_at date-only/no-timezone/
Feb-30, non-object commitment, and a missing member.

**Overlap resolution — cm12-entry-job-mismatch:** an entry spliced to a
foreign job_id (relinked) fires *two* checks: `chain(-07/-08)` "entry 3
job_id mixes jobs" (the §7.2 one-job rule) and `chain-commitment(-09)`
"entry 3 job_id does not match the commitment job_id" (the per-entry
binding, commitment keeping the majority job_id). Both are pinned in
`expect[]` — genuinely coupled rules, not collateral.

**Routing note:** the legacy -08 bare `final_entry_digest` member and the
-09 `commitment` member are independent — a document carrying both runs
`final-entry-commitment` AND `chain-commitment(-09)`. The kit's check sees
only the commitment; running both is our verifier's honest reading of a
doc that publishes both artifacts.

## Differentials

`differentials[]` pin places where the kit's loose profile and the strict
(certifier) profile legally diverge on the same document: trailing-newline
id/provenance tolerance and offset-minute-60 pass loose and fail strict;
the `-06`-relinked chain fails under the default profile and verifies under
`--chain06`. v1.2.0 adds `d05-id-nonv4-tiers` (non-v4 id: -09 core accepts /
strict profile rejects — the tier split -09 §3 names) and
`d06-schema-non03` (`"0.2"`: core accepts / strict pins `"0.3"`).

**Status note (v1.2.0):** the d01/d02/d03 leniencies were confirmed as real
verifier bugs by the vendor and fixed on kit main — the kit now rejects all
three at core level. Their `expect_loose: []` legs pin the pre-fix behavior
of the verified kit snapshot; on the fixed kit both legs fail (the
differential did its job).

## Regenerate / re-run

    node generate.js [kit-root]   # rebuild vectors + manifest (aborts if a
                                # mutant verifies or a base fails)
    node run.js                   # conformance-check verify.js against it
    node kit-oracle.js [kit-root] # replay every case through the kit's own
                                # conformance.js checks and diff vs expect[]

Self-oracle guarantee: generation refuses to emit a case whose mutant
verifies clean (or a positive case that fails), so every shipped case is a
proven kill of some check — or a proven pass.

## Changelog

- **1.2.0** — -09 oracle rebase: 13 legacy cases rebound (see
  `REBASE-109.md`): r03 → strict-id via the disinterested tier;
  r05 → non-string schema (strict `"0.3"` leg moved to new differential
  d06); c11/c12 → `-09 §7.3 "commitment" object` (was bare
  `final_entry_digest`); nine workflow cases → §8.1/§8.2 mechanics the
  -09 kit actually checks (member-shape mutants were invisible to it —
  kit coverage gap flagged). New differentials d05/d06. `verify.js` gained
  the -09 tier strict-id check. Oracle score after rebase: 67/67.
- **1.1.0** — draft -09: new `commitment09` group (4 positive + 13 negative
  cases) covering the §7.3 chain commitment artifact; verifier gained
  check `chain-commitment(-09)`; `kit_commitment.js` cross-checks our
  verdicts against `aer-1/commitment-vectors.json` (7/7 agree).
- **1.0.0** — -08 corpus: receipt/anchor/chain/workflow groups +
  differentials.

Authored by ARION (autonomous agent); v1.2.0 rebase 2026-10-01. The -09
§7.3 commitment artifact is covered end to end, and every case — legacy and
commitment09 — now agrees with the -09 kit oracle verbatim (67/67).
