{
  "feature": "sorted-set-and-hash-operations",
  "version": "1.0.0",
  "description": "Sorted collections with ranking and scoring; nested key-value maps with field-level operations and optional TTL per field",
  "category": "data",
  "tags": [
    "sorted-sets",
    "hashes",
    "nested-kv",
    "scoring",
    "field-expiration",
    "ranking"
  ],
  "actors": [
    {
      "id": "client",
      "name": "Client",
      "type": "human",
      "description": "Application requesting sorted set or hash operations"
    }
  ],
  "fields": [
    {
      "name": "key",
      "type": "text",
      "required": true,
      "label": "Key"
    },
    {
      "name": "members",
      "type": "json",
      "required": false,
      "label": "Members"
    },
    {
      "name": "fields",
      "type": "json",
      "required": false,
      "label": "Fields"
    },
    {
      "name": "score",
      "type": "number",
      "required": false,
      "label": "Score"
    },
    {
      "name": "field_ttl_ms",
      "type": "number",
      "required": false,
      "label": "Field Ttl Ms"
    }
  ],
  "rules": {
    "general": [
      "Sorted set members are unique; adding existing member updates score",
      "Scores can be equal; ties broken by lexicographic member order",
      "Scores can be negative, infinity (-inf), or +inf",
      "Range queries support inclusive and exclusive boundaries",
      "Rank is 0-based (0 = lowest score, -1 = highest score in reverse)",
      "Lex ranges require all members to have identical scores",
      "Hash fields are unique strings; updating field overwrites value",
      "Hash supports per-field TTL (field expires independently)",
      "Numeric field operations (HINCRBY) increment field values",
      "Fields are unordered unless scanning with HSCAN"
    ]
  },
  "states": {
    "field": "presence",
    "values": [
      {
        "name": "absent",
        "initial": true,
        "description": "Collection does not exist"
      },
      {
        "name": "present",
        "description": "Collection exists"
      },
      {
        "name": "empty",
        "terminal": true,
        "description": "Collection is empty"
      }
    ]
  },
  "outcomes": {
    "zadd_members": {
      "priority": 10,
      "description": "Add or update members with scores",
      "given": [
        {
          "field": "command",
          "source": "input",
          "operator": "eq",
          "value": "ZADD"
        },
        {
          "field": "nx_xx_compat",
          "source": "input",
          "operator": "not_in",
          "value": [
            "NX+XX"
          ]
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "members",
          "description": "add new members or update scores"
        },
        {
          "action": "emit_event",
          "event": "zset.added",
          "payload": [
            "key",
            "new_count",
            "updated_count"
          ]
        }
      ],
      "result": "new member count or changed count (with CH flag); client receives count"
    },
    "zadd_incr": {
      "priority": 11,
      "description": "Increment member score",
      "given": [
        {
          "field": "incr_flag",
          "source": "input",
          "operator": "eq",
          "value": "INCR"
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "members",
          "description": "increment score (create if missing)"
        },
        {
          "action": "emit_event",
          "event": "zset.scored",
          "payload": [
            "key",
            "member",
            "new_score"
          ]
        }
      ],
      "result": "new score returned (as string)"
    },
    "zadd_conditional": {
      "priority": 12,
      "description": "Add only if condition met (NX, XX, GT, LT)",
      "given": [
        {
          "field": "condition",
          "source": "input",
          "operator": "in",
          "value": [
            "NX",
            "XX",
            "GT",
            "LT"
          ]
        },
        {
          "field": "condition_met",
          "source": "computed",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "members"
        },
        {
          "action": "emit_event",
          "event": "zset.conditional_add",
          "payload": [
            "key",
            "member",
            "score",
            "condition"
          ]
        }
      ],
      "result": "member added/updated if condition met; client receives count"
    },
    "zrem_members": {
      "priority": 13,
      "description": "Remove members by name",
      "given": [
        "ZREM key member [member ...]"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "members",
          "description": "remove specified members"
        },
        {
          "action": "emit_event",
          "event": "zset.removed",
          "payload": [
            "key",
            "removed_count"
          ]
        }
      ],
      "result": "client receives count of removed members"
    },
    "zrange_by_rank": {
      "priority": 20,
      "description": "Get members by index range",
      "given": [
        "ZRANGE key start stop [WITHSCORES]",
        {
          "field": "range_type",
          "source": "input",
          "operator": "eq",
          "value": "rank"
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "zset.range_rank",
          "payload": [
            "key",
            "start",
            "stop",
            "count_returned",
            "with_scores"
          ]
        }
      ],
      "result": "array of members (with scores if WITHSCORES); empty if out-of-range"
    },
    "zrange_by_score": {
      "priority": 21,
      "description": "Get members by score range",
      "given": [
        "ZRANGE key min max BYSCORE [WITHSCORES] [LIMIT offset count]",
        {
          "field": "min_score",
          "source": "input",
          "operator": "exists"
        },
        {
          "field": "max_score",
          "source": "input",
          "operator": "exists"
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "zset.range_score",
          "payload": [
            "key",
            "min",
            "max",
            "count_returned",
            "with_scores"
          ]
        }
      ],
      "result": "array of members in score range [min, max] (exclusive with '(' prefix; handles -inf/+inf)"
    },
    "zrange_by_lex": {
      "priority": 22,
      "description": "Get members by lexicographic range (requires equal scores)",
      "given": [
        "ZRANGE key min max BYLEX [LIMIT offset count]",
        {
          "field": "all_equal_scores",
          "source": "db",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "zset.range_lex",
          "payload": [
            "key",
            "min_lex",
            "max_lex",
            "count_returned"
          ]
        }
      ],
      "result": "array of members in lex range [min, max] (exclusive with '(' prefix; handles -/+)"
    },
    "zrank_member": {
      "priority": 23,
      "description": "Get member rank by position",
      "given": [
        "ZRANK key member [WITHSCORE]"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "zset.rank",
          "payload": [
            "key",
            "member",
            "rank",
            "score_optional"
          ]
        }
      ],
      "result": "0-based rank (or nil if member absent); score included if WITHSCORE"
    },
    "zscore_member": {
      "priority": 24,
      "description": "Get member score",
      "given": [
        "ZSCORE key member"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "zset.score_read",
          "payload": [
            "key",
            "member",
            "score"
          ]
        }
      ],
      "result": "score as string (or nil if member absent)"
    },
    "zinter_sets": {
      "priority": 30,
      "description": "Get intersection of sorted sets",
      "given": [
        "ZINTER numkeys key [key ...] [WEIGHTS weight ...] [AGGREGATE SUM|MIN|MAX]",
        {
          "field": "weights",
          "source": "input",
          "operator": "exists"
        },
        {
          "field": "aggregate",
          "source": "input",
          "operator": "exists"
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "zset.inter",
          "payload": [
            "keys",
            "weights",
            "aggregate",
            "result_cardinality"
          ]
        }
      ],
      "result": "array of members in all sets (scores combined per AGGREGATE)"
    },
    "zunion_sets": {
      "priority": 31,
      "description": "Get union of sorted sets",
      "given": [
        "ZUNION numkeys key [key ...] [WEIGHTS weight ...] [AGGREGATE SUM|MIN|MAX]"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "zset.union",
          "payload": [
            "keys",
            "weights",
            "aggregate",
            "result_cardinality"
          ]
        }
      ],
      "result": "array of members in any set (scores combined per AGGREGATE)"
    },
    "hset_fields": {
      "priority": 40,
      "description": "Set one or more field-value pairs",
      "given": [
        {
          "field": "command",
          "source": "input",
          "operator": "in",
          "value": [
            "HSET",
            "HMSET"
          ]
        },
        {
          "field": "field_value_pairs",
          "source": "input",
          "operator": "exists"
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "fields",
          "description": "set or update fields"
        },
        {
          "action": "emit_event",
          "event": "hash.set",
          "payload": [
            "key",
            "fields_added",
            "fields_updated"
          ]
        }
      ],
      "result": "count of new fields added (HSET) or OK (HMSET)"
    },
    "hget_field": {
      "priority": 41,
      "description": "Get single field value",
      "given": [
        "HGET key field"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "hash.field_read",
          "payload": [
            "key",
            "field",
            "found"
          ]
        }
      ],
      "result": "field value (or nil if field absent or expired)"
    },
    "hmget_fields": {
      "priority": 42,
      "description": "Get multiple field values",
      "given": [
        "HMGET key field [field ...]"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "hash.multi_read",
          "payload": [
            "key",
            "fields_requested",
            "fields_found"
          ]
        }
      ],
      "result": "array with value for each field (nil for missing/expired fields)"
    },
    "hgetall_fields": {
      "priority": 43,
      "description": "Get all field-value pairs",
      "given": [
        "HGETALL key"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "hash.all_read",
          "payload": [
            "key",
            "field_count"
          ]
        }
      ],
      "result": "flattened array [field1, value1, field2, value2, ...] (excludes expired fields)"
    },
    "hkeys_fields": {
      "priority": 44,
      "description": "Get all field names",
      "given": [
        "HKEYS key"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "hash.keys_read",
          "payload": [
            "key",
            "field_count"
          ]
        }
      ],
      "result": "array of all field names (excludes expired)"
    },
    "hvals_values": {
      "priority": 45,
      "description": "Get all field values",
      "given": [
        "HVALS key"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "hash.vals_read",
          "payload": [
            "key",
            "value_count"
          ]
        }
      ],
      "result": "array of all values (excludes expired fields)"
    },
    "hdel_fields": {
      "priority": 46,
      "description": "Delete fields",
      "given": [
        "HDEL key field [field ...]"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "fields",
          "description": "remove specified fields"
        },
        {
          "action": "emit_event",
          "event": "hash.deleted",
          "payload": [
            "key",
            "deleted_count"
          ]
        }
      ],
      "result": "count of deleted fields; hash deleted if empty"
    },
    "hincrby_field": {
      "priority": 47,
      "description": "Increment field value by integer",
      "given": [
        "HINCRBY key field increment",
        {
          "field": "value",
          "source": "db",
          "operator": "matches",
          "value": "^-?[0-9]+$"
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "fields",
          "description": "increment field (create if absent)"
        },
        {
          "action": "emit_event",
          "event": "hash.incr",
          "payload": [
            "key",
            "field",
            "new_value"
          ]
        }
      ],
      "result": "new field value after increment"
    },
    "hincrbyfloat_field": {
      "priority": 48,
      "description": "Increment field value by float",
      "given": [
        "HINCRBYFLOAT key field increment"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "fields",
          "description": "increment field by float"
        },
        {
          "action": "emit_event",
          "event": "hash.incrbyfloat",
          "payload": [
            "key",
            "field",
            "new_value"
          ]
        }
      ],
      "result": "new field value as decimal string"
    },
    "hexists_field": {
      "priority": 49,
      "description": "Check if field exists",
      "given": [
        "HEXISTS key field"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "hash.exists_check",
          "payload": [
            "key",
            "field",
            "exists"
          ]
        }
      ],
      "result": "1 if field exists and not expired, 0 otherwise"
    },
    "hlen_hash": {
      "priority": 50,
      "description": "Get hash field count",
      "given": [
        "HLEN key"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "hash.count",
          "payload": [
            "key",
            "field_count"
          ]
        }
      ],
      "result": "number of fields (after lazy-expiring expired fields)"
    },
    "hexpire_field": {
      "priority": 60,
      "description": "Set field expiration time (seconds)",
      "given": [
        "HEXPIRE key [NX|XX|GT|LT] seconds FIELDS count field [field ...]",
        {
          "field": "condition",
          "source": "input",
          "operator": "exists"
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "field_ttl_ms",
          "description": "set absolute expiration timestamp"
        },
        {
          "action": "emit_event",
          "event": "hash.expire_set",
          "payload": [
            "key",
            "fields_affected",
            "conditions_met"
          ]
        }
      ],
      "result": "array with count of affected fields per condition"
    },
    "hpexpire_field": {
      "priority": 61,
      "description": "Set field expiration time (milliseconds)",
      "given": [
        "HPEXPIRE key [condition] milliseconds FIELDS count field [field ...]"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "field_ttl_ms",
          "description": "set absolute expiration (milliseconds precision)"
        },
        {
          "action": "emit_event",
          "event": "hash.pexpire_set",
          "payload": [
            "key",
            "fields_affected"
          ]
        }
      ],
      "result": "array with affected field counts"
    },
    "hpersist_field": {
      "priority": 62,
      "description": "Remove field expiration (make permanent)",
      "given": [
        "HPERSIST key FIELDS count field [field ...]"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "field_ttl_ms",
          "value": null,
          "description": "remove TTL"
        },
        {
          "action": "emit_event",
          "event": "hash.persist",
          "payload": [
            "key",
            "fields_affected"
          ]
        }
      ],
      "result": "array with count of fields that had TTL removed"
    },
    "httl_field": {
      "priority": 63,
      "description": "Get field TTL (seconds)",
      "given": [
        "HTTL key field [field ...]"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "hash.ttl_read",
          "payload": [
            "key",
            "fields",
            "ttls"
          ]
        }
      ],
      "result": "array of TTLs in seconds (-1=no-ttl, -2=field-absent)"
    },
    "hscan_fields": {
      "priority": 70,
      "description": "Iterate fields with cursor",
      "given": [
        "HSCAN key cursor [MATCH pattern] [COUNT count]"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "hash.scan",
          "payload": [
            "key",
            "cursor",
            "pattern"
          ]
        }
      ],
      "result": "array [new_cursor, [field1, value1, field2, value2, ...]]"
    }
  },
  "errors": [
    {
      "code": "NOT_AN_INTEGER",
      "message": "Hash value is not an integer",
      "status": 400
    },
    {
      "code": "WRONG_TYPE",
      "message": "Operation against a key holding the wrong kind of value",
      "status": 400
    },
    {
      "code": "SYNTAX_ERROR",
      "message": "Syntax error in score or condition",
      "status": 400
    }
  ],
  "events": [
    {
      "name": "zset.added",
      "payload": []
    },
    {
      "name": "zset.conditional_add",
      "payload": []
    },
    {
      "name": "zset.removed",
      "payload": []
    },
    {
      "name": "zset.range_rank",
      "payload": []
    },
    {
      "name": "zset.range_score",
      "payload": []
    },
    {
      "name": "zset.range_lex",
      "payload": []
    },
    {
      "name": "zset.rank",
      "payload": []
    },
    {
      "name": "zset.score_read",
      "payload": []
    },
    {
      "name": "zset.inter",
      "payload": []
    },
    {
      "name": "zset.union",
      "payload": []
    },
    {
      "name": "hash.set",
      "payload": []
    },
    {
      "name": "hash.field_read",
      "payload": []
    },
    {
      "name": "hash.multi_read",
      "payload": []
    },
    {
      "name": "hash.all_read",
      "payload": []
    },
    {
      "name": "hash.keys_read",
      "payload": []
    },
    {
      "name": "hash.vals_read",
      "payload": []
    },
    {
      "name": "hash.deleted",
      "payload": []
    },
    {
      "name": "hash.incr",
      "payload": []
    },
    {
      "name": "hash.incrbyfloat",
      "payload": []
    },
    {
      "name": "hash.exists_check",
      "payload": []
    },
    {
      "name": "hash.count",
      "payload": []
    },
    {
      "name": "hash.expire_set",
      "payload": []
    },
    {
      "name": "hash.pexpire_set",
      "payload": []
    },
    {
      "name": "hash.persist",
      "payload": []
    },
    {
      "name": "hash.ttl_read",
      "payload": []
    },
    {
      "name": "hash.scan",
      "payload": []
    }
  ],
  "related": [
    {
      "feature": "string-key-value",
      "type": "optional",
      "reason": "Hash fields and sorted set members are strings"
    },
    {
      "feature": "key-expiration",
      "type": "required",
      "reason": "Hashes support per-field TTL"
    }
  ],
  "agi": {
    "goals": [
      {
        "id": "reliable_sorted_set_and_hash_operations",
        "description": "Sorted collections with ranking and scoring; nested key-value maps with field-level operations and optional TTL per field",
        "success_metrics": [
          {
            "metric": "data_accuracy",
            "target": "100%",
            "measurement": "Records matching source of truth"
          },
          {
            "metric": "duplicate_rate",
            "target": "0%",
            "measurement": "Duplicate records detected post-creation"
          }
        ],
        "constraints": [
          {
            "type": "performance",
            "description": "Data consistency must be maintained across concurrent operations",
            "negotiable": false
          }
        ]
      }
    ],
    "autonomy": {
      "level": "supervised",
      "human_checkpoints": [
        "before transitioning to a terminal state"
      ],
      "escalation_triggers": [
        "error_rate > 5"
      ]
    },
    "safety": {
      "action_permissions": [
        {
          "action": "zadd_members",
          "permission": "autonomous"
        },
        {
          "action": "zadd_incr",
          "permission": "autonomous"
        },
        {
          "action": "zadd_conditional",
          "permission": "autonomous"
        },
        {
          "action": "zrem_members",
          "permission": "autonomous"
        },
        {
          "action": "zrange_by_rank",
          "permission": "autonomous"
        },
        {
          "action": "zrange_by_score",
          "permission": "autonomous"
        },
        {
          "action": "zrange_by_lex",
          "permission": "autonomous"
        },
        {
          "action": "zrank_member",
          "permission": "autonomous"
        },
        {
          "action": "zscore_member",
          "permission": "autonomous"
        },
        {
          "action": "zinter_sets",
          "permission": "autonomous"
        },
        {
          "action": "zunion_sets",
          "permission": "autonomous"
        },
        {
          "action": "hset_fields",
          "permission": "autonomous"
        },
        {
          "action": "hget_field",
          "permission": "autonomous"
        },
        {
          "action": "hmget_fields",
          "permission": "autonomous"
        },
        {
          "action": "hgetall_fields",
          "permission": "autonomous"
        },
        {
          "action": "hkeys_fields",
          "permission": "autonomous"
        },
        {
          "action": "hvals_values",
          "permission": "autonomous"
        },
        {
          "action": "hdel_fields",
          "permission": "autonomous"
        },
        {
          "action": "hincrby_field",
          "permission": "autonomous"
        },
        {
          "action": "hincrbyfloat_field",
          "permission": "autonomous"
        },
        {
          "action": "hexists_field",
          "permission": "autonomous"
        },
        {
          "action": "hlen_hash",
          "permission": "autonomous"
        },
        {
          "action": "hexpire_field",
          "permission": "autonomous"
        },
        {
          "action": "hpexpire_field",
          "permission": "autonomous"
        },
        {
          "action": "hpersist_field",
          "permission": "autonomous"
        },
        {
          "action": "httl_field",
          "permission": "autonomous"
        },
        {
          "action": "hscan_fields",
          "permission": "autonomous"
        }
      ]
    },
    "tradeoffs": [
      {
        "prefer": "data_integrity",
        "over": "performance",
        "reason": "data consistency must be maintained across all operations"
      }
    ],
    "coordination": {
      "protocol": "orchestrated",
      "consumes": [
        {
          "capability": "key_expiration",
          "from": "key-expiration",
          "fallback": "degrade"
        }
      ]
    }
  },
  "extensions": {
    "source": {
      "repo": "https://github.com/redis/redis",
      "project": "Redis",
      "tech_stack": "C",
      "files_traced": 2,
      "entry_points": [
        "src/t_zset.c",
        "src/t_hash.c"
      ]
    }
  }
}