{
  "_comment": "Cross-platform test vectors for the sealed-answer crypto protocol.",
  "_note": "Values are stable inputs and commitments. The ciphertext fields are illustrative — run the regeneration script to produce real ciphertexts for CI.",
  "_regenerate": "cd app && ./gradlew :app:testDebugUnitTest --tests 'app.closer.crypto.SealedAnswerTestVectorGenerator'",

  "protocol_version": "v1",

  "commitment": {
    "_spec": "SHA-256(\"v1|{coupleId}|{questionId}|{userId}|{canonicalJson}\"), urlsafe-base64-no-padding",
    "_canonical_json_key_order": ["scaleValue", "selectedOptionIds", "writtenText"],
    "_selectedOptionIds_order": "lexicographic ascending",
    "vectors": [
      {
        "id": "commit-001",
        "input": {
          "coupleId": "couple-abc",
          "questionId": "q-001",
          "userId": "user-alice",
          "writtenText": "I love rainy evenings at home.",
          "selectedOptionIds": ["opt-b", "opt-a"],
          "scaleValue": 7
        },
        "canonical_json": "{\"scaleValue\":7,\"selectedOptionIds\":[\"opt-a\",\"opt-b\"],\"writtenText\":\"I love rainy evenings at home.\"}",
        "commitment_hash": "sha256:REGENERATE_WITH_SCRIPT"
      },
      {
        "id": "commit-002-nulls",
        "input": {
          "coupleId": "couple-abc",
          "questionId": "q-002",
          "userId": "user-bob",
          "writtenText": null,
          "selectedOptionIds": [],
          "scaleValue": null
        },
        "canonical_json": "{\"scaleValue\":null,\"selectedOptionIds\":[],\"writtenText\":null}",
        "commitment_hash": "sha256:REGENERATE_WITH_SCRIPT"
      },
      {
        "id": "commit-003-special-chars",
        "input": {
          "coupleId": "couple-xyz",
          "questionId": "q-003",
          "userId": "user-alice",
          "writtenText": "she said \"hello\"\nand left.\ttab here",
          "selectedOptionIds": [],
          "scaleValue": null
        },
        "canonical_json": "{\"scaleValue\":null,\"selectedOptionIds\":[],\"writtenText\":\"she said \\\"hello\\\"\\nand left.\\ttab here\"}",
        "commitment_hash": "sha256:REGENERATE_WITH_SCRIPT"
      }
    ]
  },

  "sealed_payload": {
    "_spec": "AES-256-GCM via Tink AEAD. AAD = UTF-8('{coupleId}|{questionId}|{userId}'). Wire format: 'sealed:v1:{urlsafe-base64-no-padding}'.",
    "_note": "Ciphertext is non-deterministic (random nonce per encrypt call). Test by decrypt-round-trip, not by fixed ciphertext.",
    "aad_format": "{coupleId}|{questionId}|{userId}",
    "payload_format": "{\"scaleValue\":{int_or_null},\"selectedOptionIds\":[...sorted...],\"writtenText\":{string_or_null}}"
  },

  "release_key": {
    "_spec": "ECIES-P256-HKDF-HMAC-SHA256-AES128-GCM via Tink HybridEncrypt. Context info = UTF-8('{coupleId}|{questionId}|{senderUserId}|{recipientUserId}'). Wire format: 'keybox:v1:{urlsafe-base64-no-padding}'.",
    "context_info_format": "{coupleId}|{questionId}|{senderUserId}|{recipientUserId}"
  },

  "public_key": {
    "_spec": "Tink ECIES public keyset serialised as JSON, then urlsafe-base64-no-padding. Wire format: 'pub:v1:{base64}'.",
    "algorithm": "ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM"
  },

  "ios_compat_notes": [
    "Use urlsafe Base64 (no padding) for all wire formats.",
    "Canonical JSON key order is fixed: scaleValue, selectedOptionIds, writtenText.",
    "selectedOptionIds must be sorted lexicographically before hashing and before encryption.",
    "String encoding is always UTF-8.",
    "SHA-256 input is UTF-8 bytes of the full prefix+canonical-json string.",
    "ECIES ciphertext prefix format is Tink's standard; iOS must use Tink or a compatible library."
  ]
}
