{
  "feature": "list-queue-operations",
  "version": "1.0.0",
  "description": "Ordered collection with efficient head/tail insertion, removal, and range queries; supports blocking operations and atomic moves between lists",
  "category": "data",
  "tags": [
    "lists",
    "queues",
    "stacks",
    "blocking-operations",
    "ordered-collections"
  ],
  "actors": [
    {
      "id": "client",
      "name": "Client",
      "type": "human",
      "description": "Application requesting list operations"
    }
  ],
  "fields": [
    {
      "name": "key",
      "type": "text",
      "required": true,
      "label": "Key"
    },
    {
      "name": "elements",
      "type": "json",
      "required": false,
      "label": "Elements"
    },
    {
      "name": "length",
      "type": "number",
      "required": false,
      "label": "Length"
    },
    {
      "name": "head_index",
      "type": "number",
      "required": false,
      "label": "Head Index"
    },
    {
      "name": "tail_index",
      "type": "number",
      "required": false,
      "label": "Tail Index"
    },
    {
      "name": "is_blocking",
      "type": "boolean",
      "required": false,
      "label": "Is Blocking"
    },
    {
      "name": "block_timeout_ms",
      "type": "number",
      "required": false,
      "label": "Block Timeout Ms"
    }
  ],
  "rules": {
    "general": [
      "List can be accessed from both ends (head and tail) in O(1) time",
      "Indices support negative values (-1 = last element, -2 = second-to-last, etc.)",
      "LTRIM removes elements from both ends simultaneously; intermediate indices unclamped",
      "Blocking operations (BLPOP, BRPOP, etc.) suspend client until data available or timeout",
      "When list becomes empty after pop/trim, key is automatically deleted",
      "LMOVE and BLMOVE atomically pop from source and push to destination",
      "Range indices clamped to valid bounds; out-of-range ranges return empty results",
      "All operations are atomic with respect to individual keys"
    ]
  },
  "states": {
    "field": "presence",
    "values": [
      {
        "name": "absent",
        "initial": true,
        "description": "Key does not exist"
      },
      {
        "name": "present",
        "description": "List exists with one or more elements"
      },
      {
        "name": "empty",
        "terminal": true,
        "description": "List becomes empty (key auto-deleted)"
      }
    ]
  },
  "outcomes": {
    "push_to_head": {
      "priority": 10,
      "description": "Add element(s) to head of list",
      "given": [
        "LPUSH command issued",
        "elements: one or more values to push"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "elements",
          "description": "add to head in order provided"
        },
        {
          "action": "emit_event",
          "event": "list.lpush",
          "payload": [
            "key",
            "count_pushed",
            "new_length"
          ]
        }
      ],
      "result": "list created if absent; elements added; client receives new length"
    },
    "push_to_tail": {
      "priority": 11,
      "description": "Add element(s) to tail of list",
      "given": [
        "RPUSH command issued",
        "elements: one or more values to push"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "elements",
          "description": "add to tail in order provided"
        },
        {
          "action": "emit_event",
          "event": "list.rpush",
          "payload": [
            "key",
            "count_pushed",
            "new_length"
          ]
        }
      ],
      "result": "list created if absent; elements added; client receives new length"
    },
    "push_conditional": {
      "priority": 12,
      "description": "Add elements only if list exists",
      "given": [
        {
          "field": "command",
          "source": "input",
          "operator": "in",
          "value": [
            "LPUSHX",
            "RPUSHX"
          ]
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "elements",
          "when": "list_length > 0"
        },
        {
          "action": "emit_event",
          "event": "list.push_conditional",
          "payload": [
            "key",
            "pushed_count",
            "new_length"
          ]
        }
      ],
      "result": "elements added if list present; returns 0 if key absent"
    },
    "pop_from_head": {
      "priority": 20,
      "description": "Remove and return element(s) from head",
      "given": [
        "LPOP command issued",
        {
          "field": "count",
          "source": "input",
          "operator": "gt",
          "value": 0,
          "description": "optional count parameter (default 1)"
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "elements",
          "description": "remove from head"
        },
        {
          "action": "emit_event",
          "event": "list.lpop",
          "payload": [
            "key",
            "popped_count",
            "new_length"
          ]
        }
      ],
      "result": "client receives single element or array of count elements (or nil if empty)"
    },
    "pop_from_tail": {
      "priority": 21,
      "description": "Remove and return element(s) from tail",
      "given": [
        "RPOP command issued",
        {
          "field": "count",
          "source": "input",
          "operator": "gt",
          "value": 0
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "elements",
          "description": "remove from tail"
        },
        {
          "action": "emit_event",
          "event": "list.rpop",
          "payload": [
            "key",
            "popped_count",
            "new_length"
          ]
        }
      ],
      "result": "client receives single element or array of count elements (or nil if empty)"
    },
    "pop_empty_list": {
      "priority": 22,
      "given": [
        {
          "field": "list_length",
          "source": "db",
          "operator": "eq",
          "value": 0
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "list.pop_empty",
          "payload": [
            "key"
          ]
        }
      ],
      "result": "client receives nil"
    },
    "blocking_pop": {
      "priority": 23,
      "description": "Wait for element(s) to become available",
      "given": [
        {
          "field": "command",
          "source": "input",
          "operator": "in",
          "value": [
            "BLPOP",
            "BRPOP",
            "BLMOVE",
            "BLMPOP"
          ]
        },
        {
          "field": "timeout_ms",
          "source": "input",
          "operator": "gte",
          "value": 0,
          "description": "blocking timeout (0 = indefinite)"
        },
        {
          "field": "list_has_data",
          "source": "db",
          "operator": "eq",
          "value": false
        }
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "blocking_state",
          "to": "suspended",
          "description": "client put in queue"
        },
        {
          "action": "emit_event",
          "event": "list.blocking_wait",
          "payload": [
            "key",
            "timeout_ms",
            "client_id"
          ]
        }
      ],
      "result": "client blocks until data available or timeout; receives elements or nil"
    },
    "blocking_pop_timeout": {
      "priority": 24,
      "given": [
        {
          "field": "timeout_elapsed",
          "source": "system",
          "operator": "eq",
          "value": true
        },
        {
          "field": "no_data_arrived",
          "source": "system",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "blocking_state",
          "to": "released"
        },
        {
          "action": "emit_event",
          "event": "list.blocking_timeout",
          "payload": [
            "key",
            "timeout_ms"
          ]
        }
      ],
      "result": "client unblocked; receives nil"
    },
    "get_range": {
      "priority": 30,
      "description": "Retrieve elements by index range",
      "given": [
        "LRANGE key start stop",
        "start: zero-based index (negative counts from tail)",
        "stop: inclusive end index"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "list.range_read",
          "payload": [
            "key",
            "start",
            "stop",
            "elements_returned"
          ]
        }
      ],
      "result": "array of elements from start to stop inclusive (clamped to bounds); empty array if out-of-range"
    },
    "get_index": {
      "priority": 31,
      "description": "Retrieve single element by index",
      "given": [
        "LINDEX key index",
        "index: zero-based position (negative counts from tail)"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "list.index_read",
          "payload": [
            "key",
            "index",
            "found"
          ]
        }
      ],
      "result": "element at index (or nil if out-of-range)"
    },
    "get_length": {
      "priority": 32,
      "description": "Get list length",
      "given": [
        "LLEN key"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "list.len",
          "payload": [
            "key",
            "length"
          ]
        }
      ],
      "result": "number of elements (0 if key absent)"
    },
    "set_index": {
      "priority": 40,
      "description": "Overwrite element at index",
      "given": [
        "LSET key index element",
        "index: must be within [0, length-1] or [-length, -1]"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "elements",
          "description": "replace at index"
        },
        {
          "action": "emit_event",
          "event": "list.set",
          "payload": [
            "key",
            "index",
            "new_element"
          ]
        }
      ],
      "result": "element replaced; client receives OK"
    },
    "set_out_of_range": {
      "priority": 41,
      "error": "OUT_OF_RANGE",
      "given": [
        {
          "field": "index",
          "source": "input",
          "operator": "not_in",
          "value": "[valid_indices]"
        }
      ],
      "then": [],
      "result": "error returned; list unchanged"
    },
    "insert_element": {
      "priority": 42,
      "description": "Insert element before/after pivot",
      "given": [
        "LINSERT key BEFORE|AFTER pivot element",
        "pivot: element to find (first occurrence used)",
        {
          "field": "pivot_found",
          "source": "db",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "elements",
          "description": "insert before or after first matching pivot"
        },
        {
          "action": "emit_event",
          "event": "list.insert",
          "payload": [
            "key",
            "direction",
            "new_length"
          ]
        }
      ],
      "result": "element inserted; client receives new length"
    },
    "insert_pivot_not_found": {
      "priority": 43,
      "given": [
        {
          "field": "pivot_found",
          "source": "db",
          "operator": "eq",
          "value": false
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "list.insert_failed",
          "payload": [
            "key",
            "pivot"
          ]
        }
      ],
      "result": "list unchanged; client receives -1"
    },
    "trim_range": {
      "priority": 44,
      "description": "Keep only elements in range, remove rest",
      "given": [
        "LTRIM key start stop",
        "start: first index to keep",
        "stop: last index to keep (inclusive)"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "elements",
          "description": "remove elements outside [start, stop]"
        },
        {
          "action": "emit_event",
          "event": "list.trimmed",
          "payload": [
            "key",
            "start",
            "stop",
            "removed_count"
          ]
        }
      ],
      "result": "list trimmed; client receives OK; key deleted if empty"
    },
    "remove_elements": {
      "priority": 45,
      "description": "Remove matching elements",
      "given": [
        "LREM key count element",
        "count: positive=remove from head, negative=from tail, 0=all occurrences"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "elements",
          "description": "remove matching elements per count direction"
        },
        {
          "action": "emit_event",
          "event": "list.removed",
          "payload": [
            "key",
            "count_removed",
            "new_length"
          ]
        }
      ],
      "result": "matching elements removed; client receives count removed"
    },
    "find_position": {
      "priority": 46,
      "description": "Find position(s) of element with options",
      "given": [
        "LPOS key element [RANK rank] [COUNT count] [MAXLEN len]"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "list.pos_search",
          "payload": [
            "key",
            "element",
            "rank",
            "count",
            "positions_found"
          ]
        }
      ],
      "result": "single position or array of positions (or nil if not found)"
    },
    "move_between_lists": {
      "priority": 50,
      "description": "Atomically pop from source and push to destination",
      "given": [
        "LMOVE source destination LEFT|RIGHT LEFT|RIGHT",
        {
          "field": "source_has_data",
          "source": "db",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "source.elements",
          "description": "pop from source"
        },
        {
          "action": "set_field",
          "target": "destination.elements",
          "description": "push to destination"
        },
        {
          "action": "emit_event",
          "event": "list.moved",
          "payload": [
            "source_key",
            "destination_key",
            "element",
            "new_source_length",
            "new_dest_length"
          ]
        }
      ],
      "result": "element moved atomically; client receives moved element"
    },
    "move_empty_source": {
      "priority": 51,
      "given": [
        {
          "field": "source_has_data",
          "source": "db",
          "operator": "eq",
          "value": false
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "list.move_failed",
          "payload": [
            "source_key"
          ]
        }
      ],
      "result": "lists unchanged; client receives nil"
    },
    "blocking_move": {
      "priority": 52,
      "description": "Block until source has data, then move",
      "given": [
        {
          "field": "command",
          "source": "input",
          "operator": "eq",
          "value": "BLMOVE"
        },
        {
          "field": "source_empty",
          "source": "db",
          "operator": "eq",
          "value": true
        },
        {
          "field": "timeout_ms",
          "source": "input",
          "operator": "gte",
          "value": 0
        }
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "blocking_state",
          "to": "suspended"
        },
        {
          "action": "emit_event",
          "event": "list.blocking_move",
          "payload": [
            "source_key",
            "timeout_ms"
          ]
        }
      ],
      "result": "client blocks until source has data or timeout; then moves and returns element"
    },
    "mpop_from_multiple_keys": {
      "priority": 60,
      "description": "Pop from first non-empty list among multiple",
      "given": [
        "LMPOP numkeys key [key ...] LEFT|RIGHT [COUNT count]",
        "first_non_empty: first key in list with available data"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "first_non_empty.elements",
          "description": "pop count elements from this list"
        },
        {
          "action": "emit_event",
          "event": "list.mpop",
          "payload": [
            "key_popped",
            "count_popped",
            "remaining_keys_checked"
          ]
        }
      ],
      "result": "nested array [key, [elements...]] or nil if all empty"
    },
    "blocking_mpop": {
      "priority": 61,
      "description": "Block until any of multiple lists has data",
      "given": [
        {
          "field": "command",
          "source": "input",
          "operator": "eq",
          "value": "BLMPOP"
        },
        {
          "field": "any_nonempty",
          "source": "db",
          "operator": "eq",
          "value": false
        }
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "blocking_state",
          "to": "suspended"
        },
        {
          "action": "emit_event",
          "event": "list.blocking_mpop",
          "payload": [
            "keys_list",
            "timeout_ms"
          ]
        }
      ],
      "result": "client blocks until any key has data or timeout; then pops and returns [key, elements]"
    }
  },
  "errors": [
    {
      "code": "OUT_OF_RANGE",
      "message": "Index is out of range",
      "status": 400
    },
    {
      "code": "WRONG_TYPE",
      "message": "Operation against a key holding the wrong kind of value",
      "status": 400
    }
  ],
  "events": [
    {
      "name": "list.lpush",
      "payload": []
    },
    {
      "name": "list.rpush",
      "payload": []
    },
    {
      "name": "list.push_conditional",
      "payload": []
    },
    {
      "name": "list.lpop",
      "payload": []
    },
    {
      "name": "list.rpop",
      "payload": []
    },
    {
      "name": "list.pop_empty",
      "payload": []
    },
    {
      "name": "list.blocking_wait",
      "payload": []
    },
    {
      "name": "list.blocking_timeout",
      "payload": []
    },
    {
      "name": "list.range_read",
      "payload": []
    },
    {
      "name": "list.index_read",
      "payload": []
    },
    {
      "name": "list.len",
      "payload": []
    },
    {
      "name": "list.set",
      "payload": []
    },
    {
      "name": "list.insert",
      "payload": []
    },
    {
      "name": "list.trimmed",
      "payload": []
    },
    {
      "name": "list.removed",
      "payload": []
    },
    {
      "name": "list.pos_search",
      "payload": []
    },
    {
      "name": "list.moved",
      "payload": []
    },
    {
      "name": "list.blocking_move",
      "payload": []
    },
    {
      "name": "list.mpop",
      "payload": []
    },
    {
      "name": "list.blocking_mpop",
      "payload": []
    }
  ],
  "related": [
    {
      "feature": "string-key-value",
      "type": "optional",
      "reason": "Elements are strings or numeric values"
    },
    {
      "feature": "multi-exec-transactions",
      "type": "optional",
      "reason": "Often used within transactions"
    }
  ],
  "agi": {
    "goals": [
      {
        "id": "reliable_list_queue_operations",
        "description": "Ordered collection with efficient head/tail insertion, removal, and range queries; supports blocking operations and atomic moves between lists",
        "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",
        "before permanently deleting records"
      ],
      "escalation_triggers": [
        "error_rate > 5"
      ]
    },
    "safety": {
      "action_permissions": [
        {
          "action": "push_to_head",
          "permission": "autonomous"
        },
        {
          "action": "push_to_tail",
          "permission": "autonomous"
        },
        {
          "action": "push_conditional",
          "permission": "autonomous"
        },
        {
          "action": "pop_from_head",
          "permission": "autonomous"
        },
        {
          "action": "pop_from_tail",
          "permission": "autonomous"
        },
        {
          "action": "pop_empty_list",
          "permission": "autonomous"
        },
        {
          "action": "blocking_pop",
          "permission": "human_required"
        },
        {
          "action": "blocking_pop_timeout",
          "permission": "human_required"
        },
        {
          "action": "get_range",
          "permission": "autonomous"
        },
        {
          "action": "get_index",
          "permission": "autonomous"
        },
        {
          "action": "get_length",
          "permission": "autonomous"
        },
        {
          "action": "set_index",
          "permission": "autonomous"
        },
        {
          "action": "set_out_of_range",
          "permission": "autonomous"
        },
        {
          "action": "insert_element",
          "permission": "autonomous"
        },
        {
          "action": "insert_pivot_not_found",
          "permission": "autonomous"
        },
        {
          "action": "trim_range",
          "permission": "autonomous"
        },
        {
          "action": "remove_elements",
          "permission": "human_required"
        },
        {
          "action": "find_position",
          "permission": "autonomous"
        },
        {
          "action": "move_between_lists",
          "permission": "autonomous"
        },
        {
          "action": "move_empty_source",
          "permission": "autonomous"
        },
        {
          "action": "blocking_move",
          "permission": "human_required"
        },
        {
          "action": "mpop_from_multiple_keys",
          "permission": "autonomous"
        },
        {
          "action": "blocking_mpop",
          "permission": "human_required"
        }
      ]
    },
    "tradeoffs": [
      {
        "prefer": "data_integrity",
        "over": "performance",
        "reason": "data consistency must be maintained across all operations"
      }
    ]
  },
  "extensions": {
    "source": {
      "repo": "https://github.com/redis/redis",
      "project": "Redis",
      "tech_stack": "C",
      "files_traced": 2,
      "entry_points": [
        "src/t_list.c",
        "src/quicklist.h"
      ]
    }
  }
}