=== META ===
{
  "id": "GTPX-HASH-NORMALIZATION",
  "title": "GTPX Hash Normalization",
  "version": "0.1.0",
  "status": "draft",
  "updated": "2026-04-25",
  "authority": "07_validation/GTPX-HASH-NORMALIZATION.gtpx",
  "type": "validation_hash_normalization",
  "project": "GTPX",
  "depends_on": [
    "04_contract/GTPX-PLAN-MODEL.gtpx",
    "06_protocol/GTPX-ACK-HASH.gtpx",
    "07_validation/GTPX-VALIDATION-MODEL.gtpx"
  ]
}

=== DATA ===
{
  "purpose": "Defines deterministic normalization rules for hashing GTPX payloads, plans, requests and other canonical JSON structures.",

  "hash_algorithm": "SHA-256",

  "normalization_target": [
    "canonical_json_payload",
    "plan_payload",
    "request_payload",
    "patch_payload"
  ],

  "canonical_json_rules": {
    "encoding": "UTF-8",
    "object_keys_sorted": true,
    "whitespace_ignored": true,
    "line_endings_normalized": "LF",
    "trailing_spaces_removed": true,
    "null_values_preserved": true,
    "empty_arrays_preserved": true,
    "empty_objects_preserved": true,
    "number_format_must_be_canonical": true,
    "string_values_must_not_be_modified": true
  },

  "hash_input_policy": {
    "hash_is_computed_after_normalization": true,
    "hash_target_must_be_explicit": true,
    "hash_must_not_include_hash_field_itself": true,
    "metadata_inclusion_must_be_explicit": true,
    "implicit_payload_transformation_forbidden": true
  },

  "plan_hash_policy": {
    "plan_hash_target": "payload",
    "plan_hash_excludes_fields": [
      "hash",
      "created_at",
      "created_by"
    ],
    "plan_hash_includes_parent_version_id": false
  },

  "request_hash_policy": {
    "request_hash_target": "full_request_without_payload_hash",
    "payload_hash_field_excluded": true,
    "end_of_message_included": true
  },

  "patch_hash_policy": {
    "patch_hash_target": "patch_data",
    "patch_hash_excludes_fields": [
      "hash",
      "created_at",
      "applied_at"
    ]
  },

  "hash_failure_policy": {
    "hash_mismatch_result": "invalid",
    "missing_hash_result": "blocked",
    "unsupported_hash_algorithm_result": "invalid",
    "non_canonical_payload_result": "invalid"
  }
}

=== RULES ===
{
  "sha256_is_required": true,
  "canonicalization_must_precede_hashing": true,
  "hash_field_must_not_hash_itself": true,
  "same_canonical_payload_must_produce_same_hash": true,
  "different_canonical_payload_must_produce_different_hash": true,
  "hash_mismatch_blocks_commit": true,
  "hash_mismatch_blocks_execution": true,
  "normalization_rules_must_not_be_implicit": true
}

=== STATUS ===
{
  "state": "draft",
  "open_questions": [
    "Define exact canonical number representation",
    "Define whether Unicode normalization form must be NFC",
    "Define whether metadata hash profile is needed for document-level hashing"
  ],
  "next_step": "Register GTPX-HASH-NORMALIZATION in INDEX and REGISTRY."
}