{
  "feature": "multi-exec-transactions",
  "version": "1.0.0",
  "description": "Atomic multi-command execution with optional optimistic locking via WATCH; commands queued and executed sequentially without interruption",
  "category": "workflow",
  "tags": [
    "transactions",
    "atomic-operations",
    "optimistic-locking",
    "rollback",
    "isolation"
  ],
  "actors": [
    {
      "id": "client",
      "name": "Client",
      "type": "human",
      "description": "Application executing transactions"
    }
  ],
  "fields": [
    {
      "name": "transaction_state",
      "type": "select",
      "options": [
        {
          "value": "idle",
          "label": "Idle"
        },
        {
          "value": "queuing",
          "label": "Queuing"
        },
        {
          "value": "executing",
          "label": "Executing"
        }
      ],
      "required": false,
      "label": "Transaction State"
    },
    {
      "name": "queued_commands",
      "type": "json",
      "required": false,
      "label": "Queued Commands"
    },
    {
      "name": "command_results",
      "type": "json",
      "required": false,
      "label": "Command Results"
    },
    {
      "name": "watched_keys",
      "type": "json",
      "required": false,
      "label": "Watched Keys"
    },
    {
      "name": "abort_transaction",
      "type": "boolean",
      "required": false,
      "label": "Abort Transaction"
    }
  ],
  "rules": {
    "general": [
      "MULTI marks start of transaction; client queues commands instead of executing",
      "All queued commands execute sequentially without interleaving from other clients",
      "Syntax errors during queueing set EXECABORT flag; EXEC fails entirely",
      "Runtime errors during execution do not abort other commands (partial success possible)",
      "WATCH monitors keys; if ANY watched key modified by other client before EXEC, transaction aborts",
      {
        "Atomicity guarantee": "Either all commands execute or none (in case of WATCH violation)"
      },
      "No nested MULTI (attempt to MULTI while in transaction returns error)",
      {
        "Transactions provide isolation": "Other clients cannot see partial state"
      }
    ]
  },
  "states": {
    "field": "transaction_state",
    "values": [
      {
        "name": "idle",
        "initial": true,
        "description": "No active transaction"
      },
      {
        "name": "queuing",
        "description": "Client issued MULTI, queuing commands"
      },
      {
        "name": "executing",
        "description": "EXEC running, commands executing"
      },
      {
        "name": "aborted",
        "terminal": true,
        "description": "Transaction rolled back due to error or WATCH violation"
      }
    ]
  },
  "outcomes": {
    "multi_start": {
      "priority": 10,
      "description": "Begin transaction",
      "given": [
        "MULTI command",
        {
          "field": "already_in_transaction",
          "source": "db",
          "operator": "eq",
          "value": false
        }
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "transaction_state",
          "to": "queuing"
        },
        {
          "action": "set_field",
          "target": "queued_commands",
          "value": []
        },
        {
          "action": "emit_event",
          "event": "transaction.started",
          "payload": []
        }
      ],
      "result": "client receives OK; enters queuing mode"
    },
    "nested_multi_error": {
      "priority": 11,
      "error": "NESTED_TRANSACTION",
      "given": [
        {
          "field": "already_in_transaction",
          "source": "db",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [],
      "result": "error returned; transaction state unchanged"
    },
    "queue_command": {
      "priority": 12,
      "description": "Queue command for transaction",
      "given": [
        {
          "field": "transaction_state",
          "source": "db",
          "operator": "eq",
          "value": "queuing"
        },
        {
          "field": "command",
          "source": "input",
          "operator": "not_in",
          "value": [
            "EXEC",
            "DISCARD",
            "WATCH",
            "UNWATCH"
          ]
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "queued_commands",
          "description": "add to queue"
        },
        {
          "action": "emit_event",
          "event": "transaction.command_queued",
          "payload": [
            "command",
            "arg_count"
          ]
        }
      ],
      "result": "client receives QUEUED; command not executed yet"
    },
    "queue_syntax_error": {
      "priority": 13,
      "error": "EXECABORT",
      "description": "Syntax error during queueing",
      "given": [
        {
          "field": "syntax_error",
          "source": "computed",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "abort_transaction",
          "value": true
        },
        {
          "action": "emit_event",
          "event": "transaction.syntax_error",
          "payload": [
            "error_message"
          ]
        }
      ],
      "result": "error returned; EXECABORT flag set; EXEC will fail"
    },
    "exec_transaction": {
      "priority": 14,
      "description": "Execute all queued commands atomically",
      "given": [
        "EXEC command",
        {
          "field": "abort_transaction",
          "source": "db",
          "operator": "eq",
          "value": false
        },
        {
          "field": "watch_violation",
          "source": "db",
          "operator": "eq",
          "value": false
        }
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "transaction_state",
          "to": "executing"
        },
        {
          "action": "set_field",
          "target": "command_results",
          "description": "execute all commands in order, store results"
        },
        {
          "action": "transition_state",
          "field": "transaction_state",
          "to": "idle"
        },
        {
          "action": "emit_event",
          "event": "transaction.executed",
          "payload": [
            "command_count",
            "error_count"
          ]
        }
      ],
      "result": "array of results (one per queued command; errors as error objects)"
    },
    "exec_abort_syntax": {
      "priority": 15,
      "error": "EXECABORT",
      "description": "EXEC fails due to queueing errors",
      "given": [
        {
          "field": "abort_transaction",
          "source": "db",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "transaction_state",
          "to": "aborted"
        },
        {
          "action": "emit_event",
          "event": "transaction.aborted_syntax",
          "payload": []
        }
      ],
      "result": "error returned; transaction discarded; client back to idle"
    },
    "exec_watch_violation": {
      "priority": 16,
      "error": "WATCH_VIOLATION",
      "description": "EXEC fails due to watched key modification",
      "given": [
        {
          "field": "watch_violation",
          "source": "db",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "transaction_state",
          "to": "aborted"
        },
        {
          "action": "emit_event",
          "event": "transaction.aborted_watch",
          "payload": [
            "modified_keys"
          ]
        }
      ],
      "result": "nil returned; transaction rolled back; watched keys unchanged"
    },
    "discard_transaction": {
      "priority": 17,
      "description": "Abort without executing",
      "given": [
        "DISCARD command",
        {
          "field": "transaction_state",
          "source": "db",
          "operator": "eq",
          "value": "queuing"
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "queued_commands",
          "value": null
        },
        {
          "action": "transition_state",
          "field": "transaction_state",
          "to": "idle"
        },
        {
          "action": "emit_event",
          "event": "transaction.discarded",
          "payload": []
        }
      ],
      "result": "client receives OK; queued commands discarded"
    },
    "discard_without_transaction": {
      "priority": 18,
      "error": "NO_TRANSACTION",
      "given": [
        {
          "field": "transaction_state",
          "source": "db",
          "operator": "not_in",
          "value": [
            "queuing"
          ]
        }
      ],
      "then": [],
      "result": "error returned"
    },
    "watch_keys": {
      "priority": 20,
      "description": "Monitor keys for modifications",
      "given": [
        "WATCH key [key ...]",
        {
          "field": "transaction_state",
          "source": "db",
          "operator": "in",
          "value": [
            "idle",
            "queuing"
          ]
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "watched_keys",
          "description": "add to watch list"
        },
        {
          "action": "emit_event",
          "event": "transaction.keys_watched",
          "payload": [
            "keys_count",
            "total_watched"
          ]
        }
      ],
      "result": "client receives OK; keys now monitored"
    },
    "unwatch_keys": {
      "priority": 21,
      "description": "Clear watch list",
      "given": [
        "UNWATCH command"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "watched_keys",
          "value": []
        },
        {
          "action": "emit_event",
          "event": "transaction.watch_cleared",
          "payload": []
        }
      ],
      "result": "client receives OK; watch list cleared"
    },
    "watch_violation_detected": {
      "priority": 22,
      "description": "Another client modified watched key",
      "given": [
        {
          "field": "watched_key_modified",
          "source": "system",
          "operator": "eq",
          "value": true
        },
        {
          "field": "modifier_client",
          "source": "system",
          "operator": "exists"
        }
      ],
      "then": [
        {
          "action": "set_field",
          "target": "watch_violation",
          "value": true
        },
        {
          "action": "emit_event",
          "event": "transaction.watch_violated",
          "payload": [
            "modified_key"
          ]
        }
      ],
      "result": "next EXEC returns nil (abort)"
    },
    "optimistic_lock_read": {
      "priority": 30,
      "description": "Read value outside transaction",
      "given": [
        "GET key (before MULTI)",
        "WATCH key"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "transaction.optimistic_read",
          "payload": [
            "key",
            "value"
          ]
        }
      ],
      "result": "value retrieved; key now watched"
    },
    "optimistic_lock_compute": {
      "priority": 31,
      "description": "Compute new value based on read",
      "given": [
        {
          "field": "new_value",
          "source": "computed",
          "operator": "exists"
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "transaction.value_computed",
          "payload": [
            "old_value",
            "new_value"
          ]
        }
      ],
      "result": "application prepares new value"
    },
    "optimistic_lock_execute": {
      "priority": 32,
      "description": "Attempt to update if no concurrent modification",
      "given": [
        "MULTI ... SET key new_value ... EXEC",
        {
          "field": "key_unchanged",
          "source": "db",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "transaction.lock_acquired",
          "payload": [
            "key",
            "new_value"
          ]
        }
      ],
      "result": "EXEC succeeds; new value set"
    },
    "optimistic_lock_retry": {
      "priority": 33,
      "description": "Retry if concurrent modification detected",
      "given": [
        {
          "field": "watch_violation",
          "source": "db",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "transaction.lock_failed",
          "payload": [
            "key"
          ]
        }
      ],
      "result": "EXEC returns nil; application retries (GET, compute, MULTI/EXEC)"
    },
    "command_runtime_error": {
      "priority": 40,
      "description": "Command fails during execution (e.g., INCR on non-integer)",
      "given": [
        {
          "field": "command_executing",
          "source": "system",
          "operator": "exists"
        },
        {
          "field": "runtime_error",
          "source": "system",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "transaction.command_error",
          "payload": [
            "command_index",
            "error_message"
          ]
        }
      ],
      "result": "error stored in results array for that command; other commands still execute"
    },
    "partial_execution": {
      "priority": 41,
      "description": "Some commands succeed, some fail",
      "given": [
        {
          "field": "mixed_results",
          "source": "computed",
          "operator": "eq",
          "value": true
        }
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "transaction.partial_success",
          "payload": [
            "success_count",
            "error_count"
          ]
        }
      ],
      "result": "EXEC returns array with mix of values and error objects"
    }
  },
  "errors": [
    {
      "code": "NESTED_TRANSACTION",
      "message": "MULTI calls can not be nested",
      "status": 400
    },
    {
      "code": "EXECABORT",
      "message": "EXECABORT Transaction discarded because of previous errors",
      "status": 400
    },
    {
      "code": "NO_TRANSACTION",
      "message": "DISCARD without MULTI",
      "status": 400
    },
    {
      "code": "WATCH_VIOLATION",
      "message": "WATCH violation detected",
      "status": 409
    }
  ],
  "events": [
    {
      "name": "transaction.started",
      "payload": []
    },
    {
      "name": "transaction.command_queued",
      "payload": []
    },
    {
      "name": "transaction.syntax_error",
      "payload": []
    },
    {
      "name": "transaction.executed",
      "payload": []
    },
    {
      "name": "transaction.aborted_syntax",
      "payload": []
    },
    {
      "name": "transaction.aborted_watch",
      "payload": []
    },
    {
      "name": "transaction.discarded",
      "payload": []
    },
    {
      "name": "transaction.keys_watched",
      "payload": []
    },
    {
      "name": "transaction.watch_cleared",
      "payload": []
    },
    {
      "name": "transaction.watch_violated",
      "payload": []
    },
    {
      "name": "transaction.optimistic_read",
      "payload": []
    },
    {
      "name": "transaction.value_computed",
      "payload": []
    },
    {
      "name": "transaction.lock_acquired",
      "payload": []
    },
    {
      "name": "transaction.lock_failed",
      "payload": []
    },
    {
      "name": "transaction.command_error",
      "payload": []
    },
    {
      "name": "transaction.partial_success",
      "payload": []
    }
  ],
  "related": [
    {
      "feature": "string-key-value",
      "type": "optional",
      "reason": "Often used to atomically update multiple keys"
    },
    {
      "feature": "lua-scripting",
      "type": "optional",
      "reason": "Both provide atomicity; scripting more powerful for complex logic"
    }
  ],
  "agi": {
    "goals": [
      {
        "id": "reliable_multi_exec_transactions",
        "description": "Atomic multi-command execution with optional optimistic locking via WATCH; commands queued and executed sequentially without interruption",
        "success_metrics": [
          {
            "metric": "processing_time",
            "target": "< 5s",
            "measurement": "Time from request to completion"
          },
          {
            "metric": "success_rate",
            "target": ">= 99%",
            "measurement": "Successful operations divided by total attempts"
          }
        ],
        "constraints": [
          {
            "type": "performance",
            "description": "Must not block dependent workflows",
            "negotiable": true
          }
        ]
      }
    ],
    "autonomy": {
      "level": "semi_autonomous",
      "human_checkpoints": [
        "before transitioning to a terminal state"
      ],
      "escalation_triggers": [
        "error_rate > 5"
      ]
    },
    "safety": {
      "action_permissions": [
        {
          "action": "multi_start",
          "permission": "autonomous"
        },
        {
          "action": "nested_multi_error",
          "permission": "autonomous"
        },
        {
          "action": "queue_command",
          "permission": "autonomous"
        },
        {
          "action": "queue_syntax_error",
          "permission": "autonomous"
        },
        {
          "action": "exec_transaction",
          "permission": "autonomous"
        },
        {
          "action": "exec_abort_syntax",
          "permission": "autonomous"
        },
        {
          "action": "exec_watch_violation",
          "permission": "autonomous"
        },
        {
          "action": "discard_transaction",
          "permission": "autonomous"
        },
        {
          "action": "discard_without_transaction",
          "permission": "autonomous"
        },
        {
          "action": "watch_keys",
          "permission": "autonomous"
        },
        {
          "action": "unwatch_keys",
          "permission": "autonomous"
        },
        {
          "action": "watch_violation_detected",
          "permission": "autonomous"
        },
        {
          "action": "optimistic_lock_read",
          "permission": "autonomous"
        },
        {
          "action": "optimistic_lock_compute",
          "permission": "autonomous"
        },
        {
          "action": "optimistic_lock_execute",
          "permission": "autonomous"
        },
        {
          "action": "optimistic_lock_retry",
          "permission": "autonomous"
        },
        {
          "action": "command_runtime_error",
          "permission": "autonomous"
        },
        {
          "action": "partial_execution",
          "permission": "autonomous"
        }
      ]
    },
    "tradeoffs": [
      {
        "prefer": "reliability",
        "over": "speed",
        "reason": "workflow steps must complete correctly before proceeding"
      }
    ]
  },
  "extensions": {
    "source": {
      "repo": "https://github.com/redis/redis",
      "project": "Redis",
      "tech_stack": "C",
      "files_traced": 1,
      "entry_points": [
        "src/multi.c"
      ]
    }
  }
}