{
  "$comment": "Conformance corpus for /protocol/contracts/wire/wire.cddl. Every rejection class named in registries/error-codes.md must have at least one negative vector here, and spec-check.sh fails if one does not. Vectors are declarative: a generator materializes the CBOR from `fields`, so the corpus stays readable and diffable rather than being a directory of opaque blobs. The CALL and MEDIA vectors (tags 23 and 24) carry their bytes in the sibling file call-frames.json, which is generated by the client from Sources/WealdRelayNetworking by scripts/call-vectors.sh and checked byte for byte by backend/wealdrelay/tests/call_vectors.rs. Two independently written codecs that were never compared are two bugs waiting, and vectors generated by the side under test would prove nothing. The WAKE vectors (tag 25, protocol version 4) carry their bytes in the sibling file push-frames.json, which is the one generated corpus in this directory that was computed by hand from the CDDL rather than by an implementation, because the frame was specified before either codec existed and a corpus written by the first codec to arrive would have ratified whatever that codec happened to do. Whichever side grows a generator first must reproduce that file byte for byte. What stays here for push is the half no byte string can express: a registration refused because the operator configured no ringer, a principal over its hourly ceiling, and a relay with no database.",
  "version": 1,
  "max_ct_bytes": 1048576,
  "vectors": [
    {
      "id": "env-valid-mls-first-link",
      "expect": "accept",
      "note": "Canonical accepted envelope. ctr 0, prev_self all-zero.",
      "fields": {
        "v": 1,
        "enc": 1,
        "group": "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff",
        "epoch": 7,
        "ct": "hex:d0c0ffee",
        "hash": "computed"
      }
    },
    {
      "id": "env-valid-max-ct",
      "expect": "accept",
      "note": "ct exactly at the configured ceiling. Boundary must be inclusive.",
      "fields": {
        "v": 1,
        "enc": 1,
        "epoch": 7,
        "ct": "fill:1048576",
        "hash": "computed"
      }
    },
    {
      "id": "env-valid-duplicate-hash-resend",
      "expect": "accept",
      "note": "Byte-identical resend of env-valid-mls-first-link. MUST return the ORIGINAL seq and MUST NOT take the per-group counter lock. Proves a crash-resend is free and never renumbers an author chain link.",
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "env-reject-ephemeral-retired",
      "expect": "reject/unknown_required_field",
      "note": "Kind 0x00F0 is retired to reserved forever and the relay must not implement it: under enc 1 the kind is inside ct, so a relay told to drop one kind and keep every other cannot tell them apart. This vector replaces env-valid-ephemeral-not-persisted, which asserted behaviour the relay must not have. The id is replaced rather than deleted because a removed vector with no replacement reads as coverage that was never there. The ephemeral path is the LIVE frame; see /protocol/relay/presence.md.",
      "fields": {
        "v": 1,
        "enc": 1,
        "epoch": 7,
        "ct": "hex:ef00",
        "kind": 240,
        "hash": "computed"
      }
    },
    {
      "id": "env-reject-version-unsupported",
      "expect": "version/protocol_unsupported",
      "fields": {
        "v": 2,
        "enc": 1,
        "epoch": 7,
        "ct": "hex:d0c0ffee",
        "hash": "computed"
      }
    },
    {
      "id": "env-denied-plaintext-under-mls-floor",
      "expect": "denied/plaintext_refused",
      "note": "THE hosted-tier property test. With WEALD_RELAY_MIN_ENC=mls this must be refused. Run against a relay configured exactly as hosted is configured, where the setting is not writable.",
      "relay_config": {
        "WEALD_RELAY_MIN_ENC": "mls"
      },
      "fields": {
        "v": 1,
        "enc": 0,
        "epoch": 7,
        "ct": "hex:706c61696e",
        "hash": "computed"
      }
    },
    {
      "id": "env-accept-plaintext-under-none-floor",
      "expect": "accept",
      "note": "Same bytes as above under MIN_ENC=none. Self-host Phases 2 and 3 only. /readyz must report the setting and the client must render the explicit 'this relay accepts unencrypted envelopes' state.",
      "relay_config": {
        "WEALD_RELAY_MIN_ENC": "none"
      },
      "replays": "env-denied-plaintext-under-mls-floor"
    },
    {
      "id": "env-reject-hash-mismatch",
      "expect": "reject/hash_mismatch",
      "note": "hash is valid BLAKE3 of a different ct. Must not be confused with a malformed hash.",
      "fields": {
        "v": 1,
        "enc": 1,
        "epoch": 7,
        "ct": "hex:d0c0ffee",
        "hash": "hex:0000000000000000000000000000000000000000000000000000000000000001"
      }
    },
    {
      "id": "env-reject-hash-wrong-length",
      "expect": "reject/malformed_header",
      "fields": {
        "v": 1,
        "enc": 1,
        "epoch": 7,
        "ct": "hex:d0c0ffee",
        "hash": "hex:00112233"
      }
    },
    {
      "id": "env-reject-ct-oversize",
      "expect": "reject/envelope_too_large",
      "fields": {
        "v": 1,
        "enc": 1,
        "epoch": 7,
        "ct": "fill:1048577",
        "hash": "computed"
      }
    },
    {
      "id": "env-reject-ct-empty",
      "expect": "reject/malformed_header",
      "fields": {
        "v": 1,
        "enc": 1,
        "epoch": 7,
        "ct": "hex:",
        "hash": "computed"
      }
    },
    {
      "id": "env-reject-unknown-map-key",
      "expect": "reject/unknown_required_field",
      "note": "Unknown key 9 in the Envelope map. Envelope is closed; Payload kinds are open. Those two rules are deliberately opposite.",
      "raw_cbor": "a90101020103582000112233445566778899aabbccddeeff00112233445566778899aabbccddeeff040705000600075820aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4844d0c0ffee0901"
    },
    {
      "id": "env-reject-indefinite-length-bstr",
      "expect": "reject/noncanonical_cbor",
      "note": "Deterministic CBOR is a validation rule, not a convention. An indefinite-length ct is refused even when it decodes to identical bytes.",
      "raw_cbor": "indefinite-ct"
    },
    {
      "id": "env-reject-unsorted-map-keys",
      "expect": "reject/noncanonical_cbor",
      "note": "Same eight fields, keys emitted descending. Refused so that `hash` is a stable content address rather than an encoder artifact.",
      "raw_cbor": "descending-keys"
    },
    {
      "id": "env-reject-nonshortest-integer",
      "expect": "reject/noncanonical_cbor",
      "note": "epoch 7 encoded as a two-byte uint.",
      "raw_cbor": "nonshortest-epoch"
    },
    {
      "id": "env-reject-float-field",
      "expect": "reject/noncanonical_cbor",
      "note": "ts as a float. No floats appear anywhere in this protocol.",
      "raw_cbor": "float-ts"
    },
    {
      "id": "env-denied-writer-not-in-access-set",
      "expect": "denied/writer_not_in_access_set",
      "note": "Well-formed, correctly hashed envelope sent on a session authenticated by a key absent from the latest ACCESS set. This is the one authorization decision the relay makes, and it makes it without reading ciphertext.",
      "fields": {
        "v": 1,
        "enc": 1,
        "epoch": 7,
        "ct": "hex:d0c0ffee",
        "hash": "computed"
      },
      "session_device": "unenrolled"
    },
    {
      "id": "env-denied-unknown-group",
      "expect": "denied/group_unknown",
      "fields": {
        "v": 1,
        "enc": 1,
        "group": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
        "epoch": 7,
        "ct": "hex:d0c0ffee",
        "hash": "computed"
      }
    },
    {
      "id": "env-denied-service-read-only",
      "expect": "denied/service_read_only",
      "note": "Durable SEND under WEALD_RELAY_WRITE_MODE=read_only. The paired positive assertion is that SUB, RECON, export and recovery reads all still succeed in the same run. A read-only relay that also stops reconciling is a bug, not a safer state.",
      "relay_config": {
        "WEALD_RELAY_WRITE_MODE": "read_only"
      },
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "env-quota-storage-exhausted",
      "expect": "quota/storage_exhausted",
      "note": "Must carry retry-after. Must never be a silent accept.",
      "relay_config": {
        "storage_full": true
      },
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "env-quota-log-budget-exhausted",
      "expect": "quota/log_budget_exhausted",
      "note": "The workspace's envelope log is at WEALD_RELAY_MAX_LOG_GB. Must carry the limit and must never carry an interval: waiting does not clear this one, a signed drop_before behind an accepted checkpoint does. Must never be a silent accept and must never be a silent drop, because a dropped envelope is a hole in an author chain the client was told nothing about. Distinct from quota/storage_exhausted, which is the media bucket and a different lever.",
      "relay_config": {
        "log_budget_full": true
      },
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "env-retry-backpressure",
      "expect": "retry/backpressure",
      "note": "Receive queue full. The relay must stop reading the socket and push back through TCP rather than accepting and discarding, because a dropped envelope is a hole in an author chain and therefore a security alarm on somebody else's screen. Must carry retry-after.",
      "relay_config": {
        "inject": "receive_queue_full"
      },
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "env-retry-lock-timeout",
      "expect": "retry/lock_timeout",
      "note": "Per-group counter row lock timed out. This code appearing above noise is a REGRESSION alarm, not a capacity signal: with no relay-maintained head chain, SEND is never supposed to contend across groups. The test asserts that a concurrent write to a DIFFERENT group in the same run does not produce it.",
      "relay_config": {
        "inject": "counter_lock_timeout"
      },
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "env-retry-failover",
      "expect": "retry/failover",
      "note": "Database failover mid-transaction. The client resends verbatim and the duplicate-hash path returns the original seq if the first write committed.",
      "relay_config": {
        "inject": "db_failover"
      },
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "env-quota-rate-limited",
      "expect": "quota/rate_limited",
      "note": "Per-IP connection rate limit exceeded. Sized for cost control, not confidentiality: an attacker holding a key can consume bandwidth and quota and can read nothing.",
      "relay_config": {
        "rate_limit_connections_per_ip": 1
      }
    },
    {
      "id": "env-quota-seats-exhausted",
      "expect": "quota/seats_exhausted",
      "note": "Workspace seat limit reached at admission. Must name the limit and the lever that clears it.",
      "relay_config": {
        "seats": 1
      }
    },
    {
      "id": "env-quota-group-ingress-principal-minute",
      "expect": "quota/group_ingress_limited",
      "note": "The admission-blind abuse budget in relay/wire.md: 8 MiB per authenticated principal per target group per minute. This is the vector the guard exists for. Because the relay cannot establish MLS membership from opaque ciphertext, an access-set principal who merely knows a group id can otherwise inject into it; the budget is what stops a known-but-nonmember group being made expensive. Must be retryable and must carry retry-after and the limit.",
      "session_device": "device-a",
      "relay_config": {
        "group_ingress_principal_bytes_per_minute": 8388608,
        "clock": "frozen"
      },
      "repeat": 9,
      "replays": "env-valid-max-ct"
    },
    {
      "id": "env-accept-group-ingress-principal-minute-boundary",
      "expect": "accept",
      "note": "Eight maximum-size envelopes in one frozen minute, exactly at the per-principal-per-group budget. The boundary is inclusive, as it is for max_ct_bytes: wire.md sets the limit so that eight maximum-size document changes per minute stay well above normal interactive use, so the eighth must be accepted. A guard that rejects at the limit rather than above it turns a cost control into an outage.",
      "session_device": "device-a",
      "relay_config": {
        "group_ingress_principal_bytes_per_minute": 8388608,
        "clock": "frozen"
      },
      "repeat": 8,
      "replays": "env-valid-max-ct"
    },
    {
      "id": "env-quota-group-ingress-workspace-minute",
      "expect": "quota/group_ingress_limited",
      "note": "The 64 MiB per workspace per minute half of the same budget, reached across several groups by one principal so that no per-group counter alone would have caught it. Same stable code, because a client's remedy is identical and the distinction is an operator concern.",
      "session_device": "device-a",
      "relay_config": {
        "group_ingress_workspace_bytes_per_minute": 67108864,
        "clock": "frozen"
      },
      "repeat": 65,
      "replays": "env-valid-max-ct"
    },
    {
      "id": "env-quota-group-ingress-backlog",
      "expect": "quota/group_ingress_limited",
      "note": "32 MiB of not-yet-delivered envelope backlog per principal/group, with no subscriber draining it. Distinct from the two rate limits: this one is a standing volume rather than a per-minute flow, so a sender who waits out a minute must still be refused while the backlog stands. Distinct from retry/backpressure, which is the relay's own receive queue rather than an undelivered store.",
      "session_device": "device-a",
      "relay_config": {
        "group_ingress_backlog_bytes": 33554432,
        "no_subscribers": true
      },
      "repeat": 33,
      "replays": "env-valid-max-ct"
    },
    {
      "id": "env-quota-group-ingress-charged-before-persistence",
      "expect": "quota/group_ingress_limited",
      "note": "The property that makes the guard worth having: the budget is charged before persistence, so a refused SEND must leave nothing behind. After this vector the group's head, its seq and its storage footprint must be byte-identical to their values before it, and the per-group counter lock must never have been taken. A guard that rejects after writing has already paid the cost it exists to avoid.",
      "session_device": "device-a",
      "relay_config": {
        "group_ingress_principal_bytes_per_minute": 0,
        "assert_no_write": true
      },
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "env-accept-blob-not-charged-to-group-ingress",
      "expect": "accept",
      "note": "wire.md is explicit that media uses BLOB and not this path, so a BLOB well past the SEND ingress budget must be accepted. Present because the cheapest wrong implementation of this guard is one counter over all inbound bytes, which would break media upload for every paying customer and would pass every other vector here.",
      "session_device": "device-a",
      "frame": "BLOB",
      "relay_config": {
        "group_ingress_principal_bytes_per_minute": 1
      }
    },
    {
      "id": "env-version-below-client-floor",
      "expect": "version/below_client_floor",
      "note": "Relay advertises a version below the client's pinned floor on CONNECT. The client MUST abort the connection and must never silently continue, because silently continuing is the downgrade this field exists to prevent.",
      "relay_config": {
        "advertise_version": 0
      }
    },
    {
      "id": "invite-denied-code-invalid",
      "expect": "denied/invite_code_invalid",
      "note": "Wrong code half. Counts against the 5-per-token budget and the 100-per-source-IP-per-hour budget. Argon2id cost must make guessing expensive for the attacker and unnoticeable for the joiner, so the test asserts both the rejection and the latency floor.",
      "invite": {
        "code": "wrong",
        "attempt": 1
      }
    },
    {
      "id": "invite-denied-attempts-exhausted",
      "expect": "denied/invite_code_invalid",
      "note": "Sixth attempt on one token. Must remain the same code rather than a distinguishable one, so a guesser learns nothing from the boundary.",
      "invite": {
        "code": "wrong",
        "attempt": 6
      }
    },
    {
      "id": "invite-denied-seat-spent",
      "expect": "denied/invite_seat_spent",
      "invite": {
        "seats": 1,
        "already_redeemed": 1
      }
    },
    {
      "id": "invite-denied-expired",
      "expect": "denied/invite_expired",
      "note": "Evaluated against the client's own clock. Paired with clock-skew-refuses-issuance-only: a client outside the skew bound refuses to ISSUE an invite precisely so that a 24-hour credential never becomes a 24-day one.",
      "invite": {
        "expired_minutes_ago": 1
      }
    },
    {
      "id": "wrap-accept-first-in-slot",
      "expect": "accept",
      "note": "A recovery wrap for an empty (group, tag) slot. The relay stores it without opening it: the tag is BLAKE3(export(weald wraptag v1) || recovery_pubkey), derived from the group's own epoch secret, so the relay holds an opaque slot and not an identity.",
      "wrap": {
        "tag": "aa",
        "epoch": 4,
        "slot": "empty"
      }
    },
    {
      "id": "wrap-accept-advances-the-slot",
      "expect": "accept",
      "note": "The same slot at a later epoch. The superseded wrap moves to the prior slot and is retained for 30 days, which is the overlap a two-phase cross-group recovery handoff lands in.",
      "wrap": {
        "tag": "aa",
        "epoch": 5,
        "slot": "holds-epoch-4"
      }
    },
    {
      "id": "wrap-denied-not-newer",
      "expect": "denied/wrap_not_newer",
      "note": "A captured wrap offered again. Equal epochs are refused by the same rule as older ones: a slot that can be rewritten at its current epoch is a slot an attacker can overwrite with a value nobody can open. The relay cannot verify the seal, so monotonicity is the entire defence available to it.",
      "wrap": {
        "tag": "aa",
        "epoch": 4,
        "slot": "holds-epoch-5"
      }
    },
    {
      "id": "wrap-reject-tag-shared-across-groups",
      "expect": "reject/malformed_header",
      "note": "The same tag offered in a second group. This is the one row that would turn the wrap table into a group-membership graph, since joining two groups on a common tag says they share a person. Refused by a unique index, so the refusal survives any code path that forgets to check.",
      "wrap": {
        "tag": "aa",
        "epoch": 1,
        "slot": "empty",
        "group": "second"
      }
    },
    {
      "id": "env-denied-group-frozen",
      "expect": "denied/group_frozen",
      "note": "Group frozen by a retention chain or an in-flight commit. Must carry the current state hash so the client rebases rather than guesses.",
      "relay_config": {
        "freeze_group": true
      },
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "chain-valid-dense",
      "expect": "client_accept",
      "note": "Client-side vector. ctr 0,1,2 with correct prev_self linkage.",
      "chain": [
        {
          "ctr": 0,
          "prev": "zero"
        },
        {
          "ctr": 1,
          "prev": "link0"
        },
        {
          "ctr": 2,
          "prev": "link1"
        }
      ]
    },
    {
      "id": "chain-gap-no-reset-is-evidence",
      "expect": "client_split_view_warning",
      "note": "ctr 0 then 2. The receiving client must retain and render the payload as rejected, never drop it, and must raise the split-view warning naming the author.",
      "chain": [
        {
          "ctr": 0,
          "prev": "zero"
        },
        {
          "ctr": 2,
          "prev": "link0"
        }
      ]
    },
    {
      "id": "chain-gap-with-reset-is-stated",
      "expect": "client_unverified_gap",
      "note": "Same gap preceded by a signed chain.reset (0x0072). Renders as a chain reset by that author at that date, NOT as tampering. This vector is the one that keeps the alarm from being trained into noise by ordinary crashes.",
      "chain": [
        {
          "ctr": 0,
          "prev": "zero"
        },
        {
          "kind": "0x0072",
          "last_proven": 0,
          "resumes_at": 2
        },
        {
          "ctr": 2,
          "prev": "link0"
        }
      ]
    },
    {
      "id": "chain-fork-same-ctr-different-content",
      "expect": "client_split_view_warning",
      "note": "Two distinct envelopes at ctr 1 from one author. An honest client can never produce this, because the counter is written ahead of the wire in the same transaction as the MLS state.",
      "chain": [
        {
          "ctr": 0,
          "prev": "zero"
        },
        {
          "ctr": 1,
          "prev": "link0",
          "body": "A"
        },
        {
          "ctr": 1,
          "prev": "link0",
          "body": "B"
        }
      ]
    },
    {
      "id": "attest-device-silent-against-evidence",
      "expect": "client_split_view_warning",
      "note": "Application envelopes arrive from a device author while no head.attest from that author arrives across two consecutive rounds.",
      "attest": {
        "rounds": 2,
        "author_kind": "device",
        "sends_envelopes": true,
        "attests": false
      }
    },
    {
      "id": "attest-device-absent-quietly-is-normal",
      "expect": "client_accept",
      "note": "A shut laptop. Absence alone raises nothing. This negative-of-the-negative vector exists so the detector cannot be tightened into a false-positive generator.",
      "attest": {
        "rounds": 4,
        "author_kind": "device",
        "sends_envelopes": false,
        "attests": false
      }
    },
    {
      "id": "attest-agent-unproxied-is-warning",
      "expect": "client_split_view_warning",
      "note": "Agent envelopes arrive while its issuing device attested in the same round WITHOUT covering that agent. The pair contradict each other and the warning names both.",
      "attest": {
        "author_kind": "agent",
        "sends_envelopes": true,
        "issuer_attests": true,
        "issuer_covers_agent": false
      }
    },
    {
      "id": "attest-agent-proxied-is-normal",
      "expect": "client_accept",
      "note": "Ordinary agent traffic, covered by the proxying device. Agents are the highest-volume writers in the system, so this must be silent or the warning is worthless.",
      "attest": {
        "author_kind": "agent",
        "sends_envelopes": true,
        "issuer_attests": true,
        "issuer_covers_agent": true
      }
    },
    {
      "id": "attest-agent-issuer-offline-is-normal",
      "expect": "client_accept",
      "note": "Agent silent because its issuing device is offline. The ordinary silence of a shut laptop.",
      "attest": {
        "author_kind": "agent",
        "sends_envelopes": false,
        "issuer_attests": false
      }
    },
    {
      "id": "attest-total-silence-with-live-traffic",
      "expect": "client_split_view_warning",
      "note": "Envelopes arriving, zero peer attestations for 60 minutes. Warning names the RELAY rather than any author. This is the vector that closes the fail-open hole where a relay withholds every attestation from the client it is lying to.",
      "attest": {
        "minutes": 60,
        "peer_attestations": 0,
        "receiving_envelopes": true
      }
    },
    {
      "id": "attest-expected-set-comes-from-ratchet-tree",
      "expect": "client_split_view_warning",
      "note": "Relay serves an attestation set smaller than the client's own ratchet tree device leaves. The client must compute the expected set locally and report agreement as a fraction of it, naming who it has not heard from. A relay that can shrink the expected set can hide a partition.",
      "attest": {
        "relay_claims_leaves": 2,
        "ratchet_tree_device_leaves": 5
      }
    },
    {
      "id": "seq-gap-after-rollback-is-legal",
      "expect": "client_accept",
      "note": "A gap left by a rolled-back transaction. Negentropy reconciles over the space that exists, not over a dense range. A client that treats a seq gap as an alarm has confused the sync cursor with the author chain."
    },
    {
      "id": "clock-skew-refuses-issuance-only",
      "expect": "client_clock_warning",
      "note": "Local clock 6 minutes from observed relay time. Client raises the warning naming the skew and refuses to ISSUE certificates or invites, while continuing to read, write and sync. Refusing to work would be a worse failure than a stale expiry check.",
      "clock": {
        "skew_minutes": 6
      }
    },
    {
      "id": "clock-skew-under-bound-is-silent",
      "expect": "client_accept",
      "clock": {
        "skew_minutes": 4
      }
    },
    {
      "id": "live-accept-round-trip",
      "expect": "accept",
      "note": "One LIVE frame, tag 21, group and epoch and a sealed LiveBody. Encodes as [21, [group, epoch, ct]] through the same array path HANDSHAKE uses, and decodes back to identical bytes. Never stored: the integration proof asserts a zero-row delta across every table.",
      "fields": {
        "tag": 21,
        "group": "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff",
        "epoch": 7,
        "ct": "hex:a10142beef"
      }
    },
    {
      "id": "live-accept-ct-at-ceiling",
      "expect": "accept",
      "note": "ct exactly 4096 bytes. The boundary is inclusive: a bound a client cannot reach is a bound it cannot plan against.",
      "fields": {
        "tag": 21,
        "epoch": 7,
        "ct": "fill:4096"
      }
    },
    {
      "id": "live-reject-ct-oversize",
      "expect": "reject/envelope_too_large",
      "note": "One byte past the 4 KiB ceiling. A beat is a signed struct rather than a payload, so a larger one is a client using the ephemeral path for something durable.",
      "fields": {
        "tag": 21,
        "epoch": 7,
        "ct": "fill:4097"
      }
    },
    {
      "id": "live-reject-path-disabled",
      "expect": "reject/protocol_unsupported",
      "note": "WEALD_RELAY_LIVE=off. A version answer rather than a denial: the frame is well formed and the client's correct response is to stop sending it, not to retry. The connection stays up.",
      "fields": {
        "tag": 21,
        "epoch": 7,
        "ct": "hex:a10142beef"
      }
    },
    {
      "id": "live-quota-rate-limited",
      "expect": "quota/rate_limited",
      "note": "The sixty-first beat in one minute on one connection. Refused on the frame only: the connection stays up and durable traffic is unaffected, which is the whole point of budgeting presence separately from the 600 envelope allowance.",
      "fields": {
        "tag": 21,
        "epoch": 7,
        "ct": "hex:a10142beef",
        "repeat": 61
      }
    },
    {
      "id": "live-denied-outside-access-set",
      "expect": "denied/writer_not_in_access_set",
      "note": "A beat into a group whose workspace this session did not authenticate into. Refused by exactly the check SEND is refused by (ws.rs::authorize_group), reused rather than copied.",
      "fields": {
        "tag": 21,
        "epoch": 7,
        "ct": "hex:a10142beef"
      }
    },
    {
      "id": "keys-accept-publish",
      "expect": "accept",
      "note": "KEYS form 1. Packages stored against the authenticated device key; answered with form 2 carrying the shelf depth, which is the number AUTH_ACK has reported since step 5 with no publisher to fill it.",
      "fields": {
        "tag": 22,
        "form": 1,
        "packages": [
          "hex:6b7031",
          "hex:6b7032"
        ]
      }
    },
    {
      "id": "keys-accept-fetch-consumes",
      "expect": "accept",
      "note": "KEYS form 3 for one package, answered with form 4. The package is deleted as it is handed out: serving the same one twice would give two dm groups the same joiner leaf key.",
      "fields": {
        "tag": 22,
        "form": 3,
        "device": "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff",
        "count": 1
      }
    },
    {
      "id": "keys-accept-empty-shelf-is-not-an-error",
      "expect": "accept",
      "note": "KEYS form 5. An empty shelf is a real answer and not a refusal: the correct client behaviour is to wait for the peer to top up, and an error here would invite the retry loop that actually drains a shelf.",
      "fields": {
        "tag": 22,
        "form": 3,
        "device": "aa112233445566778899aabbccddeeff00112233445566778899aabbccddeeff",
        "count": 1
      }
    },
    {
      "id": "keys-quota-over-outstanding-cap",
      "expect": "quota/seats_exhausted",
      "note": "A publication that would take this device past 100 outstanding. Nothing is stored and the oldest are not evicted: a silent discard would leave the publisher believing it had a shelf, and the first person to add it to a conversation would get an unaddable member with no error anywhere.",
      "fields": {
        "tag": 22,
        "form": 1,
        "packages": [
          "fill:32"
        ],
        "outstanding": 100
      }
    },
    {
      "id": "keys-reject-fetch-count-over-cap",
      "expect": "reject/envelope_too_large",
      "note": "A fetch asking for nine. Capped at eight because higher is enumeration.",
      "fields": {
        "tag": 22,
        "form": 3,
        "device": "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff",
        "count": 9
      }
    },
    {
      "id": "keys-denied-cross-workspace-fetch",
      "expect": "denied/writer_not_in_access_set",
      "note": "A fetch whose target device is not in the access set of the session's workspace. Checked against the target and not only the requester, because otherwise any admitted device could enumerate another workspace's shelf.",
      "fields": {
        "tag": 22,
        "form": 3,
        "device": "ff112233445566778899aabbccddeeff00112233445566778899aabbccddeeff",
        "count": 1
      }
    },
    {
      "id": "dm-welcome-accept-blinded-tag",
      "expect": "accept",
      "note": "One dm.welcome, kind 0x0022, in the workspace root group. The tag is BLAKE3 over the label and the key package reference, so it names nothing to anybody who does not already hold that package.",
      "fields": {
        "v": 1,
        "enc": 1,
        "epoch": 7,
        "kind": 34,
        "ct": "hex:a2015820aaaa",
        "hash": "computed"
      }
    },
    {
      "id": "dm-welcome-carries-no-group-id",
      "expect": "accept",
      "note": "The property that matters, asserted as a vector so it is checked rather than reviewed: the record is two fields and neither is a group id. The joiner learns the group from inside the Welcome. Naming it here would let every root member learn which pair opened a conversation and when.",
      "fields": {
        "v": 1,
        "enc": 1,
        "epoch": 7,
        "kind": 34,
        "ct": "hex:a2015820bbbb",
        "hash": "computed"
      }
    },
    {
      "id": "call-accept-offer-not-persisted",
      "expect": "accept",
      "note": "One CALL offer, frame tag 23. Fanned out to every version 3 subscriber of the group and written nowhere. The zero-row Postgres delta is the assertion, over every table the relay writes to, measured immediately before and immediately after: this and the media vector below are what replaced env-valid-ephemeral-not-persisted, which asserted the same property of a kind no blind relay can implement. Proved by backend/wealdrelay/tests/calls_socket.rs and recorded in build-evidence/step-35/call-transcript.txt. The bytes are in call-frames.json, generated by the client.",
      "fields": {
        "tag": 23,
        "call_id": "c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1",
        "group": "9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a",
        "epoch": 7,
        "kind": 1,
        "body": "hex:deadbeef"
      }
    },
    {
      "id": "media-accept-not-persisted",
      "expect": "accept",
      "note": "One MEDIA frame, frame tag 24, routed at the participants of its call and written nowhere. Carries no group by design: the group was checked when a CALL admitted the connection to this call id, and repeating it here would put a Postgres read on a path carrying fifty frames a second per stream. Zero-row delta, same measurement as above.",
      "fields": {
        "tag": 24,
        "call_id": "c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1",
        "stream": "00000001",
        "seq": 42,
        "ct": "fill:11:80"
      }
    },
    {
      "id": "media-accept-max-ct",
      "expect": "accept",
      "note": "ct at exactly the 1500-byte ceiling. The boundary is inclusive, and the vector below is one byte over.",
      "fields": {
        "tag": 24,
        "call_id": "c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1",
        "stream": "00000001",
        "seq": 1,
        "ct": "fill:22:1500"
      }
    },
    {
      "id": "media-reject-oversized-ct",
      "expect": "reject/envelope_too_large",
      "note": "One byte over the ceiling. Refused on the declared length before the payload is copied anywhere or charged against any budget, and the refusal names the media ceiling rather than the frame ceiling, which is how a reader can tell which check fired.",
      "fields": {
        "tag": 24,
        "call_id": "c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1",
        "stream": "00000001",
        "seq": 1,
        "ct": "fill:22:1501"
      }
    },
    {
      "id": "call-reject-unknown-kind",
      "expect": "reject/malformed_header",
      "note": "Kind 240, which is the retired 0x00F0 ephemeral number. The kind set is closed and an unrecognised value is refused rather than forwarded: forwarding one would let a future client change routing semantics without a version bump, and forwarding this one in particular would quietly revive a reservation presence.md retired.",
      "fields": {
        "tag": 23,
        "call_id": "c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1",
        "group": "9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a",
        "epoch": 7,
        "kind": 240,
        "body": "hex:00"
      }
    },
    {
      "id": "media-denied-not-a-participant",
      "expect": "denied/writer_not_in_access_set",
      "note": "A MEDIA frame for a call this connection was never admitted to. The refusal the whole design rests on: MEDIA carries no group and consults no database, so the registry is the only thing between a media frame and a call the sender was not in. A call this process has never heard of gives the same answer rather than a different one, because telling the two apart would be an oracle.",
      "fields": {
        "tag": 24,
        "call_id": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
        "stream": "00000001",
        "seq": 1,
        "ct": "fill:11:80"
      }
    },
    {
      "id": "call-denied-group-not-admitted",
      "expect": "denied/writer_not_in_access_set",
      "note": "A CALL naming a group the sender can see and is not admitted to. Group ids are not secrets: they appear in CONNECT and a member of one workspace on a shared relay may well learn another's. Knowing one buys nothing, because admission is checked against the workspace that admitted the socket rather than against what the frame asserts. The same code answers a call id already open against a different group, which is what makes a guessed call id worthless.",
      "fields": {
        "tag": 23,
        "call_id": "c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1",
        "group": "5555555555555555555555555555555555555555555555555555555555555555",
        "epoch": 7,
        "kind": 1,
        "body": "hex:deadbeef"
      }
    },
    {
      "id": "media-quota-stream-rate",
      "expect": "quota/group_ingress_limited",
      "note": "The sixty-first frame on one stream inside one second. This is the code frame.rs has carried since step 2 with nothing referring to it; a limit the spec claims and the code does not enforce is worse than no limit. The refusal is reported at most once a second, because answering every frame of a flood is an amplifier and the answers would fill the flooder's own bounded outbound queue and turn a rate limit into a disconnect.",
      "fields": {
        "tag": 24,
        "call_id": "c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1",
        "stream": "00000001",
        "seq": 60,
        "ct": "fill:11:80"
      }
    },
    {
      "id": "wake-accept-register-round-trip",
      "expect": "accept",
      "note": "One WAKE Register, frame tag 25, answered with form 2 carrying the expiry the relay will actually forget the row at. The bytes are in push-frames.json under the same name. Stored against (workspace_id, entry_hash), so a device has at most one live registration per workspace and re-registering replaces rather than accumulates. The registration is never on the critical path of anything: the frame is answered from the row it wrote and touches no other table.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake"
      },
      "fields": {
        "tag": 25,
        "form": 1,
        "handle": "7f3a9c1d5e2b48a06c91d4f7e3b8a25c",
        "categories": 1,
        "expires_at": 1786000000000
      }
    },
    {
      "id": "wake-accept-handle-is-absent-from-the-access-state-query",
      "expect": "accept",
      "note": "The negative proof written as a vector so it is checked rather than reviewed: after the registration above, the ACCESS state query carries exactly the two facts it has always carried and not a third. A handle in that answer would make a wake capability readable by every admitted device in the workspace, and the query is the one place a reader would reasonably look for it.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake"
      },
      "replays": "wake-accept-register-round-trip"
    },
    {
      "id": "wake-accept-two-workspaces-hold-unlinkable-handles",
      "expect": "accept",
      "note": "The same device registering in two workspaces. Keyed on entry_hash, which is salted per workspace by relay_workspace.salt and never rotated, so the two rows are unrelated and cross-workspace unlinkability is a property of the key rather than an operational promise. Asserted by a property test over randomised device and workspace pairs rather than by one comparison.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake",
        "workspaces": 2
      },
      "replays": "wake-accept-register-round-trip"
    },
    {
      "id": "wake-accept-clear-with-no-row-is-still-cleared",
      "expect": "accept",
      "note": "A Clear from a principal holding no registration, answered with form 4 exactly as one holding a row is. Indistinguishable on purpose: a different answer would turn this frame into an oracle for whether a given principal has push configured, which is a fact about a person's device that no other member is entitled to.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake"
      },
      "fields": {
        "tag": 25,
        "form": 3
      }
    },
    {
      "id": "wake-accept-query-states-the-ringer-the-operator-chose",
      "expect": "accept",
      "note": "A Query answered with form 6 carrying WEALD_RELAY_PUSH_REGISTER_URL. This is what makes a self-hosted deployment work with a shipped client and no client-side configuration: the device does not know which ringer to register with, must not guess, and is told. Asked over this frame rather than at CONNECT_ACK time, because adding a field to CONNECT_ACK is the one thing a version negotiation must not require.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake",
        "WEALD_RELAY_PUSH_REGISTER_URL": "https://ringer.weald.team/v1/handles"
      },
      "fields": {
        "tag": 25,
        "form": 5
      }
    },
    {
      "id": "wake-accept-a-connected-principal-is-never-woken",
      "expect": "accept",
      "note": "An envelope accepted for a group whose other admitted principal holds a live socket. No wake is enqueued at all. Push exists for a device that is not holding a socket, and waking one that is would be a duplicate notification and a metadata leak for no benefit. The assertion is that the outbound counter is unchanged, not that the ringer answered.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake"
      },
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "wake-accept-a-hanging-ringer-adds-no-send-latency",
      "expect": "accept",
      "note": "A SEND on a process whose configured ringer accepts the connection and then hangs for thirty seconds. The write commits first and a wake is never on the critical path, so this must land inside the step 4 latency baseline. Written as a vector because the requirement that makes push safe to run is a measurement rather than a sentence, and the gate proves it with a listener that does exactly that.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake",
        "inject": "ringer_hangs_30s"
      },
      "replays": "env-valid-mls-first-link"
    },
    {
      "id": "wake-reject-handle-wrong-length",
      "expect": "reject/push_handle_malformed",
      "note": "A 15 byte handle. A reject and not a denial because a wrong-length handle is permanently wrong as sent, so resending it would be wrong in the same way. The bytes, and the sixteen sibling refusals covering both length boundaries, the empty and undefined-bit bitmasks, an elapsed expiry, a plaintext and an oversized register_url, indefinite length, a non-shortest integer, a map where an array is required, a trailing byte and a frame past the 1 KiB ceiling, are in push-frames.json.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake"
      },
      "fields": {
        "tag": 25,
        "form": 1,
        "handle": "7f3a9c1d5e2b48a06c91d4f7e3b8a2",
        "categories": 1,
        "expires_at": 1786000000000
      }
    },
    {
      "id": "wake-denied-push-not-configured",
      "expect": "denied/push_not_configured",
      "note": "A well-formed Register sent to a relay with WEALD_RELAY_PUSH=off, which is the default and a supported deployment. Denied rather than rejected, because the frame is correct and the answer would change if the operator changed one variable; the client's remedy is to send Query and read the Capability answer, not to retry the registration. The paired positive assertion is that the connection stays up and every durable path is unaffected.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "off"
      },
      "replays": "wake-accept-register-round-trip"
    },
    {
      "id": "wake-limit-registration-rate",
      "expect": "limit/push_registration_rate",
      "note": "The sixth registration from one principal inside one hour. Rotation is weekly by design, so five is generous, and the ceiling exists because a registration is a write and a device with a loop must not be one. Must carry retry-after. Refused on the frame only: the connection stays up and durable traffic is untouched, exactly as a spent LIVE budget is. This is the first code in the limit class, and the class arrived with this version.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake",
        "clock": "frozen"
      },
      "repeat": 6,
      "replays": "wake-accept-register-round-trip"
    },
    {
      "id": "wake-retry-push-backpressure",
      "expect": "retry/push_backpressure",
      "note": "No database. A registration is an admission-path write and fails closed like every other one: the client resends verbatim after the named interval and never assumes it registered. Distinct from retry/backpressure, which is the relay's own receive queue, and distinct from the wake path's bounded outbound queue, which drops the oldest and increments a counter rather than answering anybody, because a wake has nobody to answer.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake",
        "inject": "db_unavailable"
      },
      "replays": "wake-accept-register-round-trip"
    },
    {
      "id": "wake-negative-a-handle-never-reaches-a-log",
      "expect": "reject/push_handle_malformed",
      "note": "The same malformed registration as above, run with the relay at debug level and its whole log captured. The assertion is on the log rather than on the answer: no substring of the handle appears at any level, including inside the error that names the defect, which is the line a hand-written diagnostic is most likely to cross. Three absences are load-bearing for this design and this is the one a refactor breaks silently.",
      "relay_config": {
        "WEALD_RELAY_PUSH": "on",
        "WEALD_RELAY_PUSH_URL": "https://ringer.weald.team/v1/wake",
        "WEALD_RELAY_LOG": "debug",
        "assert_no_handle_in_logs": true
      },
      "replays": "wake-reject-handle-wrong-length"
    }
  ]
}
