{
  "feature": "string-key-value",
  "version": "1.0.0",
  "description": "Store and retrieve arbitrary-length string values with atomic increment, decrement, append, and range operations",
  "category": "data",
  "tags": [
    "strings",
    "key-value",
    "atomic-operations",
    "numeric-operations"
  ],
  "actors": [
    {
      "id": "client",
      "name": "Client",
      "type": "human",
      "description": "Application requesting string operations"
    }
  ],
  "fields": [
    {
      "name": "key",
      "type": "text",
      "required": true,
      "label": "Key"
    },
    {
      "name": "value",
      "type": "text",
      "required": false,
      "label": "Value"
    },
    {
      "name": "ttl_milliseconds",
      "type": "number",
      "required": false,
      "label": "Ttl Milliseconds"
    },
    {
      "name": "is_numeric",
      "type": "boolean",
      "required": false,
      "label": "Is Numeric"
    },
    {
      "name": "old_value",
      "type": "text",
      "required": false,
      "label": "Old Value"
    },
    {
      "name": "encoding",
      "type": "select",
      "options": [
        {
          "value": "raw",
          "label": "Raw"
        },
        {
          "value": "integer",
          "label": "Integer"
        },
        {
          "value": "embedded",
          "label": "Embedded"
        }
      ],
      "required": false,
      "label": "Encoding"
    }
  ],
  "rules": {
    "general": [
      "String size cannot exceed 512 MB (configurable via proto_max_bulk_len)",
      "Numeric operations (INCR, DECR) require value to be a valid 64-bit signed integer; otherwise fail with syntax error",
      "Increment/decrement values must fit in [-2^63, 2^63-1]; overflow checked and rejected with error",
      "Floating-point increment (INCRBYFLOAT) parsed as long double; operations returning NaN or Infinity fail",
      "APPEND and SETRANGE extend string with zero-padding if needed; SETRANGE with negative offset rejected",
      "All operations are atomic—no partial states visible to concurrent clients",
      "SET with NX (if-not-exists) and XX (if-exists) conditions are mutually exclusive"
    ]
  },
  "states": {
    "field": "existence",
    "values": [
      {
        "name": "absent",
        "initial": true,
        "description": "Key does not exist"
      },
      {
        "name": "present",
        "description": "Key exists with string value"
      },
      {
        "name": "expired",
        "terminal": true,
        "description": "TTL elapsed; key auto-deleted"
      }
    ]
  },
  "outcomes": {
    "read_existing_string": {
      "priority": 1,
      "description": "Retrieve existing string value",
      "given": [
        "key exists and has string value",
        "key is not expired"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "string.read",
          "payload": [
            "key",
            "length"
          ]
        }
      ],
      "result": "client receives full string value"
    },
    "read_missing_key": {
      "priority": 2,
      "description": "Attempt to read non-existent key",
      "given": [
        "key does not exist"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "string.miss",
          "payload": [
            "key"
          ]
        }
      ],
      "result": "client receives null/nil"
    },
    "read_with_ttl_modification": {
      "priority": 3,
      "description": "Read value and optionally modify or check TTL",
      "given": [
        "key exists with string value",
        "GETEX command with optional expiry flags"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "ttl_milliseconds"
        },
        {
          "action": "set_field",
          "target": "ttl_milliseconds",
          "value": null
        },
        {
          "action": "emit_event",
          "event": "string.getex",
          "payload": [
            "key",
            "ttl_modified"
          ]
        }
      ],
      "result": "client receives string value; TTL optionally modified"
    },
    "set_or_overwrite": {
      "priority": 10,
      "description": "Set value unconditionally, overwriting if exists",
      "given": [
        "SET command issued"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "value",
          "description": "store new value"
        },
        {
          "action": "set_field",
          "target": "ttl_milliseconds",
          "value": null
        },
        {
          "action": "set_field",
          "target": "is_numeric",
          "description": "evaluate if value parseable as integer for optimization"
        },
        {
          "action": "emit_event",
          "event": "string.set",
          "payload": [
            "key",
            "new_length",
            "encoding_chosen"
          ]
        }
      ],
      "result": "key now holds new value; client receives OK"
    },
    "set_with_conditions": {
      "priority": 11,
      "description": "SET only if condition met (NX, XX, or equality check)",
      "given": [
        {
          "field": "condition_type",
          "source": "input",
          "operator": "in",
          "value": [
            "NX",
            "XX",
            "IFEQ",
            "IFNE",
            "IFDEQ",
            "IFDNE"
          ]
        },
        {
          "field": "condition_met",
          "source": "computed",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "value",
          "description": "store new value"
        },
        {
          "action": "emit_event",
          "event": "string.set_conditional",
          "payload": [
            "key",
            "condition_type",
            "result"
          ]
        }
      ],
      "result": "value set and OK returned; or nil if condition not met"
    },
    "set_with_ttl": {
      "priority": 12,
      "description": "Set value with immediate expiration time",
      "given": [
        "SET with EX|PX|EXAT|PXAT flag"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "value"
        },
        {
          "action": "set_field",
          "target": "ttl_milliseconds",
          "description": "calculate absolute expiration time"
        },
        {
          "action": "emit_event",
          "event": "string.set_expiring",
          "payload": [
            "key",
            "ttl_milliseconds"
          ]
        }
      ],
      "result": "key set with expiration; expires at specified time"
    },
    "conditional_set_fails": {
      "priority": 13,
      "error": "CONDITION_NOT_MET",
      "given": [
        "SET with NX|XX|IFEQ|IFNE condition",
        {
          "field": "condition_met",
          "source": "computed",
          "operator": "eq",
          "value": false
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "string.set_rejected",
          "payload": [
            "key",
            "condition_type"
          ]
        }
      ],
      "result": "value unchanged; client receives nil"
    },
    "append_to_string": {
      "priority": 20,
      "description": "Append suffix to existing or missing string",
      "given": [
        "APPEND command",
        {
          "field": "value",
          "source": "input",
          "operator": "exists"
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "value",
          "description": "concatenate suffix to end"
        },
        {
          "action": "emit_event",
          "event": "string.appended",
          "payload": [
            "key",
            "appended_length",
            "total_length"
          ]
        }
      ],
      "result": "string extended; client receives new total length",
      "error": "STRING_TOO_LARGE"
    },
    "get_substring": {
      "priority": 21,
      "description": "Extract substring by start/end indices",
      "given": [
        "GETRANGE key start end",
        {
          "field": "start",
          "source": "input",
          "operator": "gte",
          "value": "-2^31"
        },
        {
          "field": "end",
          "source": "input",
          "operator": "lte",
          "value": "2^31-1"
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "string.range_read",
          "payload": [
            "key",
            "start",
            "end",
            "extracted_length"
          ]
        }
      ],
      "result": "substring from start to end inclusive (0-indexed, supports negative indices); empty string if range out of bounds"
    },
    "set_substring": {
      "priority": 22,
      "description": "Overwrite portion of string starting at offset",
      "given": [
        "SETRANGE key offset value",
        {
          "field": "offset",
          "source": "input",
          "operator": "gte",
          "value": 0
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "value",
          "description": "overwrite starting at offset; zero-pad if needed"
        },
        {
          "action": "emit_event",
          "event": "string.range_written",
          "payload": [
            "key",
            "offset",
            "written_length",
            "new_total_length"
          ]
        }
      ],
      "result": "string modified; client receives new total length"
    },
    "setrange_with_invalid_offset": {
      "priority": 23,
      "error": "INVALID_OFFSET",
      "given": [
        "SETRANGE with negative offset"
      ],
      "then": [],
      "result": "error returned; string unchanged"
    },
    "increment_integer": {
      "priority": 30,
      "description": "Increment numeric string value by integer amount",
      "given": [
        "INCR, INCRBY, or DECR command",
        {
          "field": "value",
          "source": "db",
          "operator": "matches",
          "value": "^-?[0-9]{1,19}$"
        },
        {
          "field": "increment_amount",
          "source": "computed",
          "operator": "exists"
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "value",
          "description": "increment or decrement value"
        },
        {
          "action": "emit_event",
          "event": "string.incr",
          "payload": [
            "key",
            "operation",
            "amount",
            "new_value"
          ]
        }
      ],
      "result": "client receives new numeric value"
    },
    "increment_non_numeric": {
      "priority": 31,
      "error": "NOT_AN_INTEGER",
      "given": [
        "value is not a valid 64-bit signed integer string"
      ],
      "then": [],
      "result": "error returned; value unchanged"
    },
    "increment_overflow": {
      "priority": 32,
      "error": "INCREMENT_OVERFLOW",
      "given": [
        {
          "field": "would_overflow",
          "source": "computed",
          "operator": "eq",
          "value": true,
          "description": "increment would exceed 64-bit bounds"
        }
      ],
      "then": [],
      "result": "error returned; value unchanged"
    },
    "increment_float": {
      "priority": 33,
      "description": "Increment numeric string by floating-point amount",
      "given": [
        "INCRBYFLOAT command",
        {
          "field": "value",
          "source": "db",
          "operator": "exists"
        },
        {
          "field": "result",
          "source": "computed",
          "operator": "not_in",
          "value": [
            "NaN",
            "Infinity"
          ]
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "value",
          "description": "increment by float; store as formatted decimal string"
        },
        {
          "action": "emit_event",
          "event": "string.incrbyfloat",
          "payload": [
            "key",
            "amount",
            "new_value"
          ]
        }
      ],
      "result": "client receives new value as decimal string"
    },
    "increment_float_invalid": {
      "priority": 34,
      "error": "FLOAT_INVALID",
      "given": [
        {
          "field": "result",
          "source": "computed",
          "operator": "in",
          "value": [
            "NaN",
            "Infinity"
          ]
        }
      ],
      "then": [],
      "result": "error returned; value unchanged"
    },
    "getset_atomically": {
      "priority": 40,
      "description": "Atomically retrieve old value and set new value",
      "given": [
        "GETSET or SET with GET flag"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "string.getset",
          "payload": [
            "key",
            "old_value",
            "new_value"
          ]
        }
      ],
      "result": "old value returned to client; new value now stored"
    },
    "getdel_atomically": {
      "priority": 41,
      "description": "Atomically retrieve value and delete key",
      "given": [
        "GETDEL command"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "string.getdel",
          "payload": [
            "key",
            "deleted_value"
          ]
        },
        {
          "action": "transition_state",
          "field": "existence",
          "from": "present",
          "to": "absent"
        }
      ],
      "result": "value returned to client; key deleted"
    },
    "mget_multiple_keys": {
      "priority": 50,
      "description": "Retrieve multiple values in single request",
      "given": [
        "MGET key1 [key2 ...]"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "string.mget",
          "payload": [
            "keys_count",
            "results_count"
          ]
        }
      ],
      "result": "array returned with value for each key (nil for missing or non-string keys)"
    },
    "mset_multiple_keys": {
      "priority": 51,
      "description": "Set multiple key-value pairs atomically",
      "given": [
        "MSET key1 value1 [key2 value2 ...]"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "string.mset",
          "payload": [
            "pairs_count"
          ]
        }
      ],
      "result": "all keys set; client receives OK"
    },
    "msetnx_conditional_bulk": {
      "priority": 52,
      "description": "Set multiple pairs only if ALL keys absent",
      "given": [
        "MSETNX key1 value1 [key2 value2 ...]",
        {
          "field": "all_keys_absent",
          "source": "db",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "string.msetnx_success",
          "payload": [
            "pairs_set_count"
          ]
        }
      ],
      "result": "all keys set; client receives 1"
    },
    "msetnx_condition_fails": {
      "priority": 53,
      "error": "KEY_EXISTS",
      "given": [
        {
          "field": "all_keys_absent",
          "source": "db",
          "operator": "eq",
          "value": false
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "string.msetnx_rejected",
          "payload": [
            "keys_skipped"
          ]
        }
      ],
      "result": "no keys set; client receives 0"
    }
  },
  "errors": [
    {
      "code": "NOT_AN_INTEGER",
      "message": "Value is not an integer or out of range",
      "status": 400
    },
    {
      "code": "INCREMENT_OVERFLOW",
      "message": "Increment or decrement would overflow",
      "status": 400
    },
    {
      "code": "CONDITION_NOT_MET",
      "message": "SET condition not met",
      "status": 409
    },
    {
      "code": "INVALID_OFFSET",
      "message": "Offset is out of range",
      "status": 400
    },
    {
      "code": "STRING_TOO_LARGE",
      "message": "String exceeds maximum allowed size",
      "status": 413
    },
    {
      "code": "FLOAT_INVALID",
      "message": "Float increment resulted in NaN or Infinity",
      "status": 400
    },
    {
      "code": "KEY_EXISTS",
      "message": "One or more keys already exist",
      "status": 409
    }
  ],
  "events": [
    {
      "name": "string.read",
      "payload": []
    },
    {
      "name": "string.miss",
      "payload": []
    },
    {
      "name": "string.set",
      "payload": []
    },
    {
      "name": "string.set_conditional",
      "payload": []
    },
    {
      "name": "string.set_expiring",
      "payload": []
    },
    {
      "name": "string.appended",
      "payload": []
    },
    {
      "name": "string.range_read",
      "payload": []
    },
    {
      "name": "string.range_written",
      "payload": []
    },
    {
      "name": "string.incr",
      "payload": []
    },
    {
      "name": "string.incrbyfloat",
      "payload": []
    },
    {
      "name": "string.getset",
      "payload": []
    },
    {
      "name": "string.getdel",
      "payload": []
    },
    {
      "name": "string.mget",
      "payload": []
    },
    {
      "name": "string.mset",
      "payload": []
    },
    {
      "name": "string.msetnx_success",
      "payload": []
    },
    {
      "name": "string.msetnx_rejected",
      "payload": []
    }
  ],
  "related": [
    {
      "feature": "key-expiration",
      "type": "required",
      "reason": "TTL support integrated into string operations"
    },
    {
      "feature": "multi-exec-transactions",
      "type": "optional",
      "reason": "Multiple string commands often wrapped in transactions"
    }
  ],
  "agi": {
    "goals": [
      {
        "id": "reliable_string_key_value",
        "description": "Store and retrieve arbitrary-length string values with atomic increment, decrement, append, and range operations",
        "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": "read_existing_string",
          "permission": "autonomous"
        },
        {
          "action": "read_missing_key",
          "permission": "autonomous"
        },
        {
          "action": "read_with_ttl_modification",
          "permission": "supervised"
        },
        {
          "action": "set_or_overwrite",
          "permission": "autonomous"
        },
        {
          "action": "set_with_conditions",
          "permission": "autonomous"
        },
        {
          "action": "set_with_ttl",
          "permission": "autonomous"
        },
        {
          "action": "conditional_set_fails",
          "permission": "autonomous"
        },
        {
          "action": "append_to_string",
          "permission": "autonomous"
        },
        {
          "action": "get_substring",
          "permission": "autonomous"
        },
        {
          "action": "set_substring",
          "permission": "autonomous"
        },
        {
          "action": "setrange_with_invalid_offset",
          "permission": "autonomous"
        },
        {
          "action": "increment_integer",
          "permission": "autonomous"
        },
        {
          "action": "increment_non_numeric",
          "permission": "autonomous"
        },
        {
          "action": "increment_overflow",
          "permission": "autonomous"
        },
        {
          "action": "increment_float",
          "permission": "autonomous"
        },
        {
          "action": "increment_float_invalid",
          "permission": "autonomous"
        },
        {
          "action": "getset_atomically",
          "permission": "autonomous"
        },
        {
          "action": "getdel_atomically",
          "permission": "autonomous"
        },
        {
          "action": "mget_multiple_keys",
          "permission": "autonomous"
        },
        {
          "action": "mset_multiple_keys",
          "permission": "autonomous"
        },
        {
          "action": "msetnx_conditional_bulk",
          "permission": "autonomous"
        },
        {
          "action": "msetnx_condition_fails",
          "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_string.c",
        "src/server.c"
      ]
    }
  }
}