{
 "corpus": "arion-aer1-negative-must-fail",
 "corpus_version": "1.2.0",
 "generated": "2026-10-01T22:52:09.666Z",
 "spec": "draft-zambo-aer1-09 (negative/must-fail half of conformance)",
 "oracle": "self-oracle: expect[] is the EXACT {check,reason} failure set; a case FAILs the runner if any expected failure is absent OR any unlisted failure appears. expect=[] means the document MUST verify (commitment09 positive cases; differential cases' passing legs).",
 "bases": {
  "receipt": "aer-1/test-vectors/valid/receipt-01.json",
  "anchor": "aer-1/test-vectors/anchored/anchored-valid.json",
  "chain": "aer-1/chain-vectors-v07.json :: v07-valid-5, v07-seq-float-valid",
  "workflow": "constructed; steps carry aer-1/merkle-vectors.json :: canonical-5-step receipt_ids"
 },
 "commitment09_artifact": "draft -09 Section 7.3 chain commitment: a JSON object carried in a \"commitment\" member beside \"timeline\". verify.js check \"chain-commitment(-09)\" binds job_id to every entry's job_id, final_entry_digest to the recomputed Section 7.1 digest of the last entry, entry_count to the timeline length, and requires published_at to be RFC 3339 with a valid calendar date/time; additional members are ignored. Routing is independent of the -08 bare \"final_entry_digest\" member — a doc carrying both runs both checks.",
 "rebase_v120": {
  "from": "1.1.0",
  "to": "1.2.0",
  "reason": "vendor ops re-ran v1.1.0 through the -09 conformance kit oracle: 37/50 legacy cases agreed; 13 diverged on -08->-09 drift. v1.2.0 rebinds every case to the published -09 field names and kit-verbatim reasons; see REBASE-109.md.",
  "kit_oracle_before": "37/50 legacy cases agree (13 disagree)",
  "kit_oracle_after": "67/67 cases agree (50/50 legacy, 17/17 commitment09)",
  "draft_sections": {
   "id_tiers": "draft-zambo-aer1-09 Section 3: core id = lowercase UUID; strict UUID-v4 profile applies where certification or the disinterested tier is claimed (kit enforces it inside checkDisinterestedTier)",
   "schema_version": "draft-zambo-aer1-09 Section 3: receipt_schema_version core rule = non-empty string; the exact \"0.3\" pin is the certifier/strict profile only",
   "commitment": "draft-zambo-aer1-09 Section 7.3: chain commitment is a JSON object carried in a \"commitment\" member; the -08 bare \"final_entry_digest\" member is not a -09 check",
   "workflow": "the -09 kit's verifyWorkflow implements only the Section 8.2 offline mechanics; the Table 2/3 member-shape expectations of v1.1.0 are invisible to that oracle"
  },
  "changed_cases": [
   "r03-id-nonv4-strict",
   "r05-schema-nonstring",
   "c11-commitment-mismatch",
   "c12-commitment-badfmt",
   "w01-steps-nonlist",
   "w02-doc-not-object",
   "w03-steps-reordered",
   "w05-dup-receiptid-stale-root",
   "w08-step-seq-dup",
   "w09-step-seq-tail-skip",
   "w10-steps-null",
   "w12-merkle-wrong-order",
   "w14-step-seq-zero"
  ],
  "renamed": {
   "r05-schema-02-strict": "r05-schema-nonstring",
   "w01-missing-type": "w01-steps-nonlist",
   "w02-wrong-type": "w02-doc-not-object",
   "w03-wfid-nonuuid": "w03-steps-reordered",
   "w05-merkle-badfmt": "w05-dup-receiptid-stale-root",
   "w08-step-missing-tool": "w08-step-seq-dup",
   "w09-step-bad-ts": "w09-step-seq-tail-skip",
   "w10-verify-url-nonhttp": "w10-steps-null",
   "w12-step-bad-receipt-hash": "w12-merkle-wrong-order",
   "w14-sessionid-empty": "w14-step-seq-zero"
  },
  "new_differentials": [
   "d05-id-nonv4-tiers",
   "d06-schema-non03"
  ]
 },
 "cases": [
  {
   "name": "r01-drop-id",
   "file": "vectors/r01-drop-id.json",
   "group": "receipt",
   "flags": {},
   "spec": "S3 required members",
   "mutation": "removed required member 'id'",
   "expect": [
    {
     "check": "core",
     "reason": "missing required member: id"
    }
   ]
  },
  {
   "name": "r02-id-uppercase",
   "file": "vectors/r02-id-uppercase.json",
   "group": "receipt",
   "flags": {},
   "spec": "S3 id lowercase UUID",
   "mutation": "uppercased id hex",
   "expect": [
    {
     "check": "core",
     "reason": "id is not a lowercase UUID"
    }
   ]
  },
  {
   "name": "r03-id-nonv4-strict",
   "file": "vectors/r03-id-nonv4-strict.json",
   "group": "receipt",
   "flags": {},
   "spec": "S3 id UUID v4 — strict profile claimed via the disinterested tier (S10)",
   "mutation": "version nibble 4->5 on a tier-anchored receipt — v1.2.0 rebase: -09 binds the strict id profile to the disinterested tier (kit emits \"id is not a UUID v4 (strict profile)\"), so the case now carries the tier anchor that claims it",
   "expect": [
    {
     "check": "disinterested-tier",
     "reason": "id is not a UUID v4 (strict profile)"
    }
   ]
  },
  {
   "name": "r04-schema-empty",
   "file": "vectors/r04-schema-empty.json",
   "group": "receipt",
   "flags": {},
   "spec": "S3 receipt_schema_version non-empty",
   "mutation": "emptied schema version",
   "expect": [
    {
     "check": "core",
     "reason": "receipt_schema_version is not a non-empty string"
    }
   ]
  },
  {
   "name": "r05-schema-nonstring",
   "file": "vectors/r05-schema-nonstring.json",
   "group": "receipt",
   "flags": {},
   "spec": "S3 receipt_schema_version non-empty string",
   "mutation": "schema version as a JSON number, not a string — v1.2.0 rebase: the exact \"0.3\" pin survives only in the certifier/strict profile (see differential d06); the -09 core rule is a non-empty string",
   "expect": [
    {
     "check": "core",
     "reason": "receipt_schema_version is not a non-empty string"
    }
   ]
  },
  {
   "name": "r06-created-feb30",
   "file": "vectors/r06-created-feb30.json",
   "group": "receipt",
   "flags": {},
   "spec": "S3 valid calendar date",
   "mutation": "impossible calendar date, well-formed RFC 3339",
   "expect": [
    {
     "check": "core",
     "reason": "created_at is not a valid calendar date/time"
    }
   ]
  },
  {
   "name": "r07-created-nopad",
   "file": "vectors/r07-created-nopad.json",
   "group": "receipt",
   "flags": {},
   "spec": "S3 RFC 3339 format",
   "mutation": "unpadded month/day breaks format",
   "expect": [
    {
     "check": "core",
     "reason": "created_at is not RFC 3339"
    }
   ]
  },
  {
   "name": "r08-tool-nonobject",
   "file": "vectors/r08-tool-nonobject.json",
   "group": "receipt",
   "flags": {},
   "spec": "S3 tool object",
   "mutation": "tool member replaced by a string",
   "expect": [
    {
     "check": "core",
     "reason": "tool is not an object with name/version/scope strings"
    }
   ]
  },
  {
   "name": "r09-tool-empty-name",
   "file": "vectors/r09-tool-empty-name.json",
   "group": "receipt",
   "flags": {},
   "spec": "S3 tool.name non-empty",
   "mutation": "emptied tool.name",
   "expect": [
    {
     "check": "core",
     "reason": "tool is not an object with name/version/scope strings"
    }
   ]
  },
  {
   "name": "r10-provenance-lower",
   "file": "vectors/r10-provenance-lower.json",
   "group": "receipt",
   "flags": {},
   "spec": "S5 provenance class vocabulary",
   "mutation": "lowercased provenance label",
   "expect": [
    {
     "check": "core",
     "reason": "provenance_class is not a known class"
    }
   ]
  },
  {
   "name": "r11-bytes-badb64",
   "file": "vectors/r11-bytes-badb64.json",
   "group": "receipt",
   "flags": {},
   "spec": "S4 strict base64",
   "mutation": "non-base64 canonical_bytes",
   "expect": [
    {
     "check": "core",
     "reason": "canonical_bytes is not valid base64"
    }
   ]
  },
  {
   "name": "r12-bytes-nonutf8",
   "file": "vectors/r12-bytes-nonutf8.json",
   "group": "receipt",
   "flags": {},
   "spec": "S4 strict UTF-8",
   "mutation": "base64 of invalid UTF-8 bytes",
   "expect": [
    {
     "check": "core",
     "reason": "canonical_bytes is not valid UTF-8"
    }
   ]
  },
  {
   "name": "r13-hash-noprefix",
   "file": "vectors/r13-hash-noprefix.json",
   "group": "receipt",
   "flags": {},
   "spec": "S6 output_hash sha256: prefix",
   "mutation": "stripped 'sha256:' scheme",
   "expect": [
    {
     "check": "core",
     "reason": "output_hash is not sha256: + lowercase hex digest"
    }
   ]
  },
  {
   "name": "r14-hash-upperhex",
   "file": "vectors/r14-hash-upperhex.json",
   "group": "receipt",
   "flags": {},
   "spec": "S6 output_hash lowercase hex",
   "mutation": "uppercased digest hex",
   "expect": [
    {
     "check": "core",
     "reason": "output_hash is not sha256: + lowercase hex digest"
    }
   ]
  },
  {
   "name": "r15-hash-mismatch",
   "file": "vectors/r15-hash-mismatch.json",
   "group": "receipt",
   "flags": {},
   "spec": "S6 recomputation binding",
   "mutation": "well-formed but wrong digest",
   "expect": [
    {
     "check": "core",
     "reason": "output_hash does not match sha256(canonical_bytes)"
    }
   ]
  },
  {
   "name": "r16-status-pending",
   "file": "vectors/r16-status-pending.json",
   "group": "receipt",
   "flags": {},
   "spec": "S3 verification_status=verified",
   "mutation": "non-verified status",
   "expect": [
    {
     "check": "core",
     "reason": "verification_status is not verified"
    }
   ]
  },
  {
   "name": "r17-profile-no-inputs",
   "file": "vectors/r17-profile-no-inputs.json",
   "group": "receipt",
   "flags": {
    "profile": true
   },
   "spec": "kit profile: canonical payload carries 'inputs'",
   "mutation": "payload 'inputs' member removed, hashes repaired — only the profile check fires",
   "expect": [
    {
     "check": "reference-profile",
     "reason": "reference-producer payload omits the 'inputs' member"
    }
   ]
  },
  {
   "name": "a01-anchor-extra-member",
   "file": "vectors/a01-anchor-extra-member.json",
   "group": "anchor",
   "flags": {},
   "spec": "S10 tier member vocabulary",
   "mutation": "anchor gains a 5th member",
   "expect": [
    {
     "check": "disinterested-tier",
     "reason": "anchor has members other than log/leaf_hash/anchored_at/proof"
    }
   ]
  },
  {
   "name": "a02-anchor-missing-proof",
   "file": "vectors/a02-anchor-missing-proof.json",
   "group": "anchor",
   "flags": {},
   "spec": "S10 tier member vocabulary",
   "mutation": "anchor.proof removed (member-set + type failure)",
   "expect": [
    {
     "check": "disinterested-tier",
     "reason": "anchor has members other than log/leaf_hash/anchored_at/proof"
    },
    {
     "check": "disinterested-tier",
     "reason": "anchor.proof is not an object"
    }
   ]
  },
  {
   "name": "a03-leaf-mismatch",
   "file": "vectors/a03-leaf-mismatch.json",
   "group": "anchor",
   "flags": {},
   "spec": "S10 leaf_hash binds canonical bytes",
   "mutation": "well-formed wrong leaf_hash",
   "expect": [
    {
     "check": "disinterested-tier",
     "reason": "anchor.leaf_hash does not match canonical_bytes"
    }
   ]
  },
  {
   "name": "a04-leaf-upperhex",
   "file": "vectors/a04-leaf-upperhex.json",
   "group": "anchor",
   "flags": {},
   "spec": "S10 leaf_hash lowercase hex",
   "mutation": "uppercase leaf_hash hex",
   "expect": [
    {
     "check": "disinterested-tier",
     "reason": "anchor.leaf_hash is not sha256: + lowercase hex digest"
    }
   ]
  },
  {
   "name": "a05-anchored-badcal",
   "file": "vectors/a05-anchored-badcal.json",
   "group": "anchor",
   "flags": {},
   "spec": "S10 anchored_at calendar time",
   "mutation": "impossible calendar timestamp",
   "expect": [
    {
     "check": "disinterested-tier",
     "reason": "anchor.anchored_at is not a valid calendar date/time"
    }
   ]
  },
  {
   "name": "a06-log-empty",
   "file": "vectors/a06-log-empty.json",
   "group": "anchor",
   "flags": {},
   "spec": "S10 anchor.log non-empty",
   "mutation": "emptied anchor.log",
   "expect": [
    {
     "check": "disinterested-tier",
     "reason": "anchor.log is not a non-empty string"
    }
   ]
  },
  {
   "name": "c01-last-seq-skip",
   "file": "vectors/c01-last-seq-skip.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.2 seq contiguous 1..n",
   "mutation": "last entry seq 5->6 (no downstream links to repair)",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 4 seq 6 breaks contiguity (expected 5)"
    }
   ]
  },
  {
   "name": "c02-genesis-nonzero-relinked",
   "file": "vectors/c02-genesis-nonzero-relinked.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.2 genesis prev_digest = 64 zeros",
   "mutation": "nonzero genesis, entry 1 relinked — isolates the genesis rule",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 0 prev_digest is not 64 zero characters"
    }
   ]
  },
  {
   "name": "c03-mid-link-broken",
   "file": "vectors/c03-mid-link-broken.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.2 hash-chain link",
   "mutation": "entry 2 prev_digest zeroed, entry 3 relinked — single broken link",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 2 prev_digest does not match the digest of entry 1"
    }
   ]
  },
  {
   "name": "c04-mixed-job-relinked",
   "file": "vectors/c04-mixed-job-relinked.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.2 one job per timeline",
   "mutation": "entry 3 job_id swapped, entry 4 relinked — isolates job mixing",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 3 job_id mixes jobs"
    }
   ]
  },
  {
   "name": "c05-close-early-relinked",
   "file": "vectors/c05-close-early-relinked.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.2 close only on last entry",
   "mutation": "mid-chain close:true, downstream relinked",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 2 carries close:true before the last entry"
    }
   ]
  },
  {
   "name": "c06-no-close-last",
   "file": "vectors/c06-no-close-last.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.2 closing entry",
   "mutation": "last entry close removed",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "last entry does not carry close: true"
    }
   ]
  },
  {
   "name": "c07-close-nonbool",
   "file": "vectors/c07-close-nonbool.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.2 close boolean",
   "mutation": "last entry close: 'yes' (non-boolean + unclosed)",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 4 close is not a boolean"
    },
    {
     "check": "chain(-07/-08)",
     "reason": "last entry does not carry close: true"
    }
   ]
  },
  {
   "name": "c08-seq-float",
   "file": "vectors/c08-seq-float.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.2 seq integer",
   "mutation": "non-integer seq (structural abort)",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 1 seq is not an integer"
    }
   ]
  },
  {
   "name": "c09-entry-badb64",
   "file": "vectors/c09-entry-badb64.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.1 strict base64 entry bytes",
   "mutation": "entry 1 canonical_bytes non-base64 (structural abort)",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 1 canonical_bytes is not valid base64"
    }
   ]
  },
  {
   "name": "c10-entry-missing-jobid",
   "file": "vectors/c10-entry-missing-jobid.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.2 entry members",
   "mutation": "entry 1 job_id removed (structural abort)",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 1 missing job_id"
    }
   ]
  },
  {
   "name": "c11-commitment-mismatch",
   "file": "vectors/c11-commitment-mismatch.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.3 -09 commitment binds final digest",
   "mutation": "commitment object with wrong final_entry_digest — v1.2.0 rebase: rebound from the -08 bare \"final_entry_digest\" member to the -09 Section 7.3 \"commitment\" object (kit checks only the object form)",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment final_entry_digest does not match the recomputed digest of the last entry"
    }
   ]
  },
  {
   "name": "c12-commitment-badfmt",
   "file": "vectors/c12-commitment-badfmt.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.3 final_entry_digest 64 lowercase hex",
   "mutation": "commitment final_entry_digest carries a scheme prefix — v1.2.0 rebase to the -09 Section 7.3 commitment object",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment final_entry_digest is not 64 lowercase hex characters"
    }
   ]
  },
  {
   "name": "c13-v06-chain-under-v07",
   "file": "vectors/c13-v06-chain-under-v07.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.4: -06 chains MUST NOT verify under -07/-08",
   "mutation": "chain relinked with -06 digest recipe (sha256 of decoded bytes)",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 1 prev_digest does not match the digest of entry 0"
    }
   ]
  },
  {
   "name": "c14-first-seq-2-relinked",
   "file": "vectors/c14-first-seq-2-relinked.json",
   "group": "chain",
   "flags": {},
   "spec": "S7.2 first entry seq = 1",
   "mutation": "first entry seq 1->2, entry 1 relinked — isolates the seq-origin rule",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 0 seq 2 breaks contiguity (expected 1)"
    }
   ]
  },
  {
   "name": "cm01-valid",
   "file": "vectors/cm01-valid.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 -09 commitment binds the timeline",
   "mutation": "control: valid commitment over v07-valid-5",
   "expect": []
  },
  {
   "name": "cm02-valid-offset-frac",
   "file": "vectors/cm02-valid-offset-frac.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 published_at RFC 3339",
   "mutation": "published_at with +HH:MM offset and fractional seconds",
   "expect": []
  },
  {
   "name": "cm03-valid-single",
   "file": "vectors/cm03-valid-single.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 commitment over a one-entry timeline",
   "mutation": "single-entry closed timeline + binding commitment",
   "expect": []
  },
  {
   "name": "cm04-valid-extra-member",
   "file": "vectors/cm04-valid-extra-member.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 additional commitment members ignored",
   "mutation": "commitment carries an extra 'issuer' member",
   "expect": []
  },
  {
   "name": "cm05-digest-mismatch",
   "file": "vectors/cm05-digest-mismatch.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 final_entry_digest binds last entry",
   "mutation": "well-formed but wrong final_entry_digest",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment final_entry_digest does not match the recomputed digest of the last entry"
    }
   ]
  },
  {
   "name": "cm06-digest-uppercase",
   "file": "vectors/cm06-digest-uppercase.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 final_entry_digest 64 lowercase hex",
   "mutation": "correct digest, uppercased",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment final_entry_digest is not 64 lowercase hex characters"
    }
   ]
  },
  {
   "name": "cm07-digest-length",
   "file": "vectors/cm07-digest-length.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 final_entry_digest 64 lowercase hex",
   "mutation": "63-char digest",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment final_entry_digest is not 64 lowercase hex characters"
    }
   ]
  },
  {
   "name": "cm08-count-mismatch",
   "file": "vectors/cm08-count-mismatch.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 entry_count binds timeline length",
   "mutation": "entry_count 7 vs 5 entries",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment entry_count 7 does not match the timeline length 5"
    }
   ]
  },
  {
   "name": "cm09-count-float",
   "file": "vectors/cm09-count-float.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 entry_count integer",
   "mutation": "entry_count 5.5",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment entry_count is not an integer"
    }
   ]
  },
  {
   "name": "cm10-count-string",
   "file": "vectors/cm10-count-string.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 entry_count integer",
   "mutation": "entry_count '5' (string)",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment entry_count is not an integer"
    }
   ]
  },
  {
   "name": "cm11-job-mismatch",
   "file": "vectors/cm11-job-mismatch.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 job_id matches every entry",
   "mutation": "commitment job_id differs from all 5 entries",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "entry 0 job_id does not match the commitment job_id"
    },
    {
     "check": "chain-commitment(-09)",
     "reason": "entry 1 job_id does not match the commitment job_id"
    },
    {
     "check": "chain-commitment(-09)",
     "reason": "entry 2 job_id does not match the commitment job_id"
    },
    {
     "check": "chain-commitment(-09)",
     "reason": "entry 3 job_id does not match the commitment job_id"
    },
    {
     "check": "chain-commitment(-09)",
     "reason": "entry 4 job_id does not match the commitment job_id"
    }
   ]
  },
  {
   "name": "cm12-entry-job-mismatch",
   "file": "vectors/cm12-entry-job-mismatch.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 job_id per-entry compare + S7.2 one-job rule",
   "mutation": "entry 3 spliced to a foreign job; fires BOTH chain(-07/-08) 'mixes jobs' and chain-commitment(-09) 'does not match' — coupled rules",
   "expect": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 3 job_id mixes jobs"
    },
    {
     "check": "chain-commitment(-09)",
     "reason": "entry 3 job_id does not match the commitment job_id"
    }
   ]
  },
  {
   "name": "cm13-published-dateonly",
   "file": "vectors/cm13-published-dateonly.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 published_at RFC 3339",
   "mutation": "date-only published_at",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment published_at is not RFC 3339"
    }
   ]
  },
  {
   "name": "cm14-published-notz",
   "file": "vectors/cm14-published-notz.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 published_at RFC 3339",
   "mutation": "published_at with no timezone offset",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment published_at is not RFC 3339"
    }
   ]
  },
  {
   "name": "cm15-published-feb30",
   "file": "vectors/cm15-published-feb30.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 published_at valid calendar date/time",
   "mutation": "impossible calendar date, well-formed RFC 3339",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment published_at is not a valid calendar date/time"
    }
   ]
  },
  {
   "name": "cm16-not-object",
   "file": "vectors/cm16-not-object.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 commitment is a JSON object",
   "mutation": "commitment member is a bare hex string, not an object",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment is not a JSON object"
    }
   ]
  },
  {
   "name": "cm17-missing-member",
   "file": "vectors/cm17-missing-member.json",
   "group": "commitment09",
   "flags": {},
   "spec": "S7.3 required commitment members",
   "mutation": "entry_count member removed",
   "expect": [
    {
     "check": "chain-commitment(-09)",
     "reason": "commitment entry_count is not an integer"
    }
   ]
  },
  {
   "name": "w01-steps-nonlist",
   "file": "vectors/w01-steps-nonlist.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.2 steps is a non-empty list",
   "mutation": "steps member present but an object, not a list (was: w01-missing-type)",
   "expect": [
    {
     "check": "workflow",
     "reason": "workflow steps is not a non-empty list"
    }
   ]
  },
  {
   "name": "w02-doc-not-object",
   "file": "vectors/w02-doc-not-object.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8 workflow is a JSON object",
   "mutation": "document is a JSON array, not a workflow object (was: w02-wrong-type)",
   "expect": [
    {
     "check": "workflow",
     "reason": "workflow is not a JSON object"
    }
   ]
  },
  {
   "name": "w03-steps-reordered",
   "file": "vectors/w03-steps-reordered.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.2 step seq 1..n in order",
   "mutation": "steps 1<->2 swapped, root recomputed — isolates the order rule (was: w03-wfid-nonuuid)",
   "expect": [
    {
     "check": "workflow",
     "reason": "step seq values are not 1..5 in order (index 0 carries seq 2)"
    }
   ]
  },
  {
   "name": "w04-merkle-mismatch",
   "file": "vectors/w04-merkle-mismatch.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.1 recomputed root binding",
   "mutation": "well-formed wrong merkle_root",
   "expect": [
    {
     "check": "workflow",
     "reason": "merkle_root does not match the recomputed Section 8.1 root"
    }
   ]
  },
  {
   "name": "w05-dup-receiptid-stale-root",
   "file": "vectors/w05-dup-receiptid-stale-root.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.2 duplicate receipt_id + S8.1 root binding",
   "mutation": "step 5 duplicates step 4's receipt_id; merkle_root NOT recomputed — coupled pair, dup fires then the stale root (was: w05-merkle-badfmt)",
   "expect": [
    {
     "check": "workflow",
     "reason": "duplicate receipt_id: bf88a036-416b-456a-8e82-8c0991811d68"
    },
    {
     "check": "workflow",
     "reason": "merkle_root does not match the recomputed Section 8.1 root"
    }
   ]
  },
  {
   "name": "w06-dup-receiptid",
   "file": "vectors/w06-dup-receiptid.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.2 duplicate receipt_id",
   "mutation": "step 5 duplicates step 4's receipt_id; root recomputed — isolates the dup rule",
   "expect": [
    {
     "check": "workflow",
     "reason": "duplicate receipt_id: bf88a036-416b-456a-8e82-8c0991811d68"
    }
   ]
  },
  {
   "name": "w07-stepseq-skip",
   "file": "vectors/w07-stepseq-skip.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.2 step seq 1..n in order",
   "mutation": "step 3 seq 3->9",
   "expect": [
    {
     "check": "workflow",
     "reason": "step seq values are not 1..5 in order (index 2 carries seq 9)"
    }
   ]
  },
  {
   "name": "w08-step-seq-dup",
   "file": "vectors/w08-step-seq-dup.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.2 step seq 1..n no duplicates",
   "mutation": "step 3 seq duplicated 3->2 (was: w08-step-missing-tool)",
   "expect": [
    {
     "check": "workflow",
     "reason": "step seq values are not 1..5 in order (index 2 carries seq 2)"
    }
   ]
  },
  {
   "name": "w09-step-seq-tail-skip",
   "file": "vectors/w09-step-seq-tail-skip.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.2 step seq 1..n in order",
   "mutation": "step 5 seq skipped 5->6 (was: w09-step-bad-ts)",
   "expect": [
    {
     "check": "workflow",
     "reason": "step seq values are not 1..5 in order (index 4 carries seq 6)"
    }
   ]
  },
  {
   "name": "w10-steps-null",
   "file": "vectors/w10-steps-null.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.2 steps is a non-empty list",
   "mutation": "steps member null (was: w10-verify-url-nonhttp)",
   "expect": [
    {
     "check": "workflow",
     "reason": "workflow steps is not a non-empty list"
    }
   ]
  },
  {
   "name": "w11-empty-steps",
   "file": "vectors/w11-empty-steps.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.2 steps non-empty",
   "mutation": "steps = []",
   "expect": [
    {
     "check": "workflow",
     "reason": "workflow steps is not a non-empty list"
    }
   ]
  },
  {
   "name": "w12-merkle-wrong-order",
   "file": "vectors/w12-merkle-wrong-order.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.1 root binds the step ORDER",
   "mutation": "merkle_root recomputed over sorted receipt_ids — binds the wrong ordering (was: w12-step-bad-receipt-hash)",
   "expect": [
    {
     "check": "workflow",
     "reason": "merkle_root does not match the recomputed Section 8.1 root"
    }
   ]
  },
  {
   "name": "w14-step-seq-zero",
   "file": "vectors/w14-step-seq-zero.json",
   "group": "workflow",
   "flags": {
    "kind": "workflow"
   },
   "spec": "S8.2 step seq 1..n in order",
   "mutation": "step 4 seq zeroed (was: w14-sessionid-empty)",
   "expect": [
    {
     "check": "workflow",
     "reason": "step seq values are not 1..5 in order (index 3 carries seq 0)"
    }
   ]
  }
 ],
 "differentials": [
  {
   "name": "d01-id-trailing-newline",
   "file": "vectors/d01-id-trailing-newline.json",
   "spec": "S3 id — kit pattern tolerates trailing newline; strict does not",
   "mutation": "id + trailing \\n",
   "expect_loose": [],
   "expect_strict": [
    {
     "check": "core",
     "reason": "id is not a UUID v4"
    }
   ],
   "strict_mode": "strict"
  },
  {
   "name": "d02-offset-min-60",
   "file": "vectors/d02-offset-min-60.json",
   "spec": "S3 offset — kit bounds total<24h; strict bounds minutes<=59",
   "mutation": "offset minute component 60",
   "expect_loose": [],
   "expect_strict": [
    {
     "check": "core",
     "reason": "created_at is not a valid calendar date/time"
    }
   ],
   "strict_mode": "strict"
  },
  {
   "name": "d03-prov-trailing-newline",
   "file": "vectors/d03-prov-trailing-newline.json",
   "spec": "S5 provenance — kit pattern tolerates trailing newline; strict does not",
   "mutation": "provenance_class + trailing \\n",
   "expect_loose": [],
   "expect_strict": [
    {
     "check": "core",
     "reason": "provenance_class is not a known class"
    }
   ],
   "strict_mode": "strict"
  },
  {
   "name": "d04-v06-chain-labeled",
   "file": "vectors/d04-v06-chain-labeled.json",
   "spec": "S7.4: same -06 document — rejects under -07/-08, verifies under --chain06",
   "mutation": "-06-relinked 2-entry chain (control for c13)",
   "expect_loose": [
    {
     "check": "chain(-07/-08)",
     "reason": "entry 1 prev_digest does not match the digest of entry 0"
    }
   ],
   "expect_strict": [],
   "strict_mode": "chain06"
  },
  {
   "name": "d05-id-nonv4-tiers",
   "file": "vectors/d05-id-nonv4-tiers.json",
   "spec": "S3 id tiers — -09 core accepts any lowercase UUID; the strict/certifier profile requires UUID v4 with RFC 4122 variant bits",
   "mutation": "id version nibble 4->5 (absorbs v1.1.0 r03's strict-receipt leg)",
   "expect_loose": [],
   "expect_strict": [
    {
     "check": "core",
     "reason": "id is not a UUID v4"
    }
   ],
   "strict_mode": "strict"
  },
  {
   "name": "d06-schema-non03",
   "file": "vectors/d06-schema-non03.json",
   "spec": "S3 schema version — -09 core requires a non-empty string; the certifier/strict profile pins \"0.3\" exactly",
   "mutation": "schema '0.2' (absorbs v1.1.0 r05's strict-receipt leg)",
   "expect_loose": [],
   "expect_strict": [
    {
     "check": "core",
     "reason": "receipt_schema_version is not 0.3"
    }
   ],
   "strict_mode": "strict"
  }
 ]
}