{
  "components": {
    "schemas": {
      "BulkAffectedBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/BulkAffectedBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "affected": {
            "description": "Number of rows the operation touched",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "affected"
        ],
        "type": "object"
      },
      "BulkRerunBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/BulkRerunBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "triggered": {
            "description": "New runs spawned by the rerun, keyed by task",
            "items": {
              "$ref": "#/components/schemas/TriggeredRunRef"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "triggered"
        ],
        "type": "object"
      },
      "CapInfo": {
        "additionalProperties": false,
        "properties": {
          "available": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "available"
        ],
        "type": "object"
      },
      "ConfigStaleSSEEvent": {
        "additionalProperties": false,
        "properties": {
          "stale": {
            "description": "True when runwisp.toml changed on disk but isn't applied yet",
            "type": "boolean"
          }
        },
        "required": [
          "stale"
        ],
        "type": "object"
      },
      "DaemonInfo": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/DaemonInfo.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "auth_disabled": {
            "type": "boolean"
          },
          "capabilities": {
            "items": {
              "$ref": "#/components/schemas/CapInfo"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "cloud_enabled": {
            "type": "boolean"
          },
          "config_loaded_at": {
            "format": "date-time",
            "type": "string"
          },
          "config_stale": {
            "type": "boolean"
          },
          "external_url": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "port": {
            "format": "int64",
            "type": "integer"
          },
          "resolved_timezone": {
            "type": "string"
          },
          "scheduling_active": {
            "type": "boolean"
          },
          "service_managed": {
            "type": "boolean"
          },
          "tasks": {
            "items": {
              "$ref": "#/components/schemas/TaskBrief"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "timezone_source": {
            "enum": [
              "config",
              "system"
            ],
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "version",
          "fingerprint",
          "port",
          "external_url",
          "cloud_enabled",
          "scheduling_active",
          "service_managed",
          "auth_disabled",
          "config_loaded_at",
          "config_stale",
          "resolved_timezone",
          "timezone_source",
          "tasks",
          "capabilities"
        ],
        "type": "object"
      },
      "DaemonLogLineEvent": {
        "additionalProperties": false,
        "properties": {
          "line": {
            "description": "One captured daemon log line",
            "type": "string"
          }
        },
        "required": [
          "line"
        ],
        "type": "object"
      },
      "EndReason": {
        "description": "Why a run ended. Set when status=ended.",
        "enum": [
          "success",
          "failed",
          "stopped",
          "timeout",
          "crashed",
          "skipped",
          "log_overflow",
          "queue_full",
          "dst_skipped",
          "daemon_stopped",
          "missed",
          "start_failed"
        ],
        "type": "string"
      },
      "ErrorDetail": {
        "additionalProperties": false,
        "properties": {
          "location": {
            "description": "Where the error occurred, e.g. 'body.items[3].tags' or 'path.thing-id'",
            "type": "string"
          },
          "message": {
            "description": "Error message text",
            "type": "string"
          },
          "value": {
            "description": "The value at the given location"
          }
        },
        "type": "object"
      },
      "ErrorModel": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/ErrorModel.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "detail": {
            "description": "A human-readable explanation specific to this occurrence of the problem.",
            "examples": [
              "Property foo is required but is missing."
            ],
            "type": "string"
          },
          "errors": {
            "description": "Optional list of individual error details",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "instance": {
            "description": "A URI reference that identifies the specific occurrence of the problem.",
            "examples": [
              "https://example.com/error-log/abc123"
            ],
            "format": "uri",
            "type": "string"
          },
          "status": {
            "description": "HTTP status code",
            "examples": [
              400
            ],
            "format": "int64",
            "type": "integer"
          },
          "title": {
            "description": "A short, human-readable summary of the problem type. This value should not change between occurrences of the error.",
            "examples": [
              "Bad Request"
            ],
            "type": "string"
          },
          "type": {
            "default": "about:blank",
            "description": "A URI reference to human-readable documentation for the error.",
            "examples": [
              "https://example.com/errors/example"
            ],
            "format": "uri",
            "type": "string"
          }
        },
        "type": "object"
      },
      "InstanceInfo": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/InstanceInfo.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "app": {
            "description": "Always \"runwisp\"; lets a caller confirm the port-holder is a RunWisp daemon.",
            "type": "string"
          },
          "config_path": {
            "type": "string"
          },
          "data_dir": {
            "type": "string"
          },
          "fingerprint": {
            "type": "string"
          },
          "pid": {
            "format": "int64",
            "type": "integer"
          },
          "socket_path": {
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "app",
          "version",
          "fingerprint",
          "pid",
          "data_dir",
          "config_path",
          "socket_path"
        ],
        "type": "object"
      },
      "LocalCredentialsBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/LocalCredentialsBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "ephemeral": {
            "description": "Always true on success — the endpoint refuses to return env-var-supplied passwords.",
            "type": "boolean"
          },
          "password": {
            "description": "Ephemeral password generated in memory at boot. Omitted unless ephemeral=true.",
            "type": "string"
          }
        },
        "required": [
          "password",
          "ephemeral"
        ],
        "type": "object"
      },
      "LogDoneEvent": {
        "additionalProperties": false,
        "properties": {
          "final_line": {
            "description": "Last line number emitted before the run terminated",
            "format": "int64",
            "type": "integer"
          },
          "status": {
            "description": "Reason the stream is closing (e.g. 'ended')",
            "type": "string"
          }
        },
        "required": [
          "final_line",
          "status"
        ],
        "type": "object"
      },
      "LogDroppedEvent": {
        "additionalProperties": false,
        "properties": {
          "after": {
            "description": "Highest line number observed before drops occurred",
            "format": "int64",
            "type": "integer"
          },
          "count": {
            "description": "Number of line events dropped due to overflow",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "after",
          "count"
        ],
        "type": "object"
      },
      "LogLineEntry": {
        "additionalProperties": false,
        "properties": {
          "continued": {
            "description": "True if this segment continues an oversized split line",
            "type": "boolean"
          },
          "frame_count": {
            "description": "Number of recorded prior frames if this line is a settled progress bar / redraw anchor; 0 otherwise",
            "format": "int64",
            "type": "integer"
          },
          "n": {
            "description": "Absolute line number",
            "format": "int64",
            "type": "integer"
          },
          "stream": {
            "description": "Stream identifier (stdout/stderr/system)",
            "type": "string"
          },
          "text": {
            "description": "Line content without trailing newline",
            "type": "string"
          },
          "ts": {
            "description": "Unix milliseconds timestamp; 0 if unavailable",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "n",
          "ts",
          "stream",
          "text"
        ],
        "type": "object"
      },
      "LogLineHistoryBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/LogLineHistoryBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "frames": {
            "description": "Prior whole-region frames, oldest first; each frame is one or more rows",
            "items": {
              "items": {
                "type": "string"
              },
              "type": [
                "array",
                "null"
              ]
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "frames"
        ],
        "type": "object"
      },
      "LogLineSSEEvent": {
        "additionalProperties": false,
        "properties": {
          "continued": {
            "description": "True if this segment continues an oversized split line",
            "type": "boolean"
          },
          "frame_count": {
            "description": "Number of recorded prior frames if this line is a settled progress bar / redraw anchor; 0 otherwise",
            "format": "int64",
            "type": "integer"
          },
          "n": {
            "description": "Absolute line number",
            "format": "int64",
            "type": "integer"
          },
          "stream": {
            "description": "Stream identifier (stdout/stderr/system)",
            "type": "string"
          },
          "text": {
            "description": "Line content without trailing newline",
            "type": "string"
          },
          "ts": {
            "description": "Unix milliseconds timestamp; 0 if unavailable",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "n",
          "ts",
          "stream",
          "text"
        ],
        "type": "object"
      },
      "LogPageBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/LogPageBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "finalized": {
            "description": "True if the run has ended and the log is final",
            "type": "boolean"
          },
          "first_available": {
            "description": "Lowest line number still on disk; lines below were rotated away",
            "format": "int64",
            "type": "integer"
          },
          "lines": {
            "description": "Returned lines, ascending by n",
            "items": {
              "$ref": "#/components/schemas/LogLineEntry"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "total_lines": {
            "description": "Total lines produced across all segments",
            "format": "int64",
            "type": "integer"
          },
          "truncated": {
            "description": "True if rotation has dropped lines below first_available",
            "type": "boolean"
          }
        },
        "required": [
          "lines",
          "first_available",
          "total_lines",
          "truncated",
          "finalized"
        ],
        "type": "object"
      },
      "LogRegionSSEEvent": {
        "additionalProperties": false,
        "properties": {
          "epoch": {
            "description": "Region generation; bumps on screen reset so stale frames can be discarded",
            "format": "int64",
            "type": "integer"
          },
          "rows": {
            "description": "Current frame of the region, one entry per row; empty clears the overlay",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "stream": {
            "description": "Stream identifier (stdout/stderr)",
            "type": "string"
          }
        },
        "required": [
          "stream",
          "epoch",
          "rows"
        ],
        "type": "object"
      },
      "LogRotatedEvent": {
        "additionalProperties": false,
        "properties": {
          "first_available": {
            "description": "Lowest line number still on disk after rotation",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "first_available"
        ],
        "type": "object"
      },
      "LogSearchBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/LogSearchBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "exhausted": {
            "description": "True when no further runs / lines need scanning",
            "type": "boolean"
          },
          "hits": {
            "description": "Hits ordered newest-run-first, then ascending line within a run",
            "items": {
              "$ref": "#/components/schemas/LogSearchHit"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "next_cursor": {
            "description": "Opaque token to fetch the next page; empty when the scan is exhausted",
            "type": "string"
          },
          "scanned_runs": {
            "description": "Number of runs visited by this request",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "hits",
          "exhausted",
          "scanned_runs"
        ],
        "type": "object"
      },
      "LogSearchHit": {
        "additionalProperties": false,
        "properties": {
          "n": {
            "description": "Absolute line number within the run",
            "format": "int64",
            "type": "integer"
          },
          "run_id": {
            "description": "ULID of the run containing this line",
            "type": "string"
          },
          "stream": {
            "description": "Stream identifier (stdout/stderr/system)",
            "type": "string"
          },
          "text": {
            "description": "Matched line content without trailing newline",
            "type": "string"
          },
          "ts": {
            "description": "Run created_at in Unix milliseconds (used for newest-first sort)",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "run_id",
          "n",
          "stream",
          "text",
          "ts"
        ],
        "type": "object"
      },
      "MetricsSample": {
        "additionalProperties": false,
        "properties": {
          "cpu": {
            "description": "CPU usage percentage (0-100)",
            "format": "double",
            "type": "number"
          },
          "mem": {
            "description": "Memory usage percentage (0-100)",
            "format": "double",
            "type": "number"
          },
          "mem_total": {
            "description": "Total memory in bytes",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "mem_used": {
            "description": "Used memory in bytes",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "ts": {
            "description": "Unix timestamp (seconds)",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "ts",
          "cpu",
          "mem",
          "mem_used",
          "mem_total"
        ],
        "type": "object"
      },
      "NotificationCreatedEvent": {
        "additionalProperties": false,
        "properties": {
          "notification": {
            "$ref": "#/components/schemas/NotificationDTO"
          },
          "unread_count": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "notification",
          "unread_count"
        ],
        "type": "object"
      },
      "NotificationDTO": {
        "additionalProperties": false,
        "properties": {
          "body": {
            "description": "Pre-rendered body text",
            "type": "string"
          },
          "count": {
            "description": "Number of coalesced occurrences within the window",
            "format": "int64",
            "type": "integer"
          },
          "created_at": {
            "description": "First time this notification was raised",
            "format": "date-time",
            "type": "string"
          },
          "fingerprint": {
            "description": "Coalescing key (FNV1a hex)",
            "type": "string"
          },
          "id": {
            "description": "Stable ULID identifier",
            "type": "string"
          },
          "kind": {
            "description": "Event kind (run.failed, notify.delivery_failed, ...)",
            "type": "string"
          },
          "last_occurred_at": {
            "description": "Most recent occurrence",
            "format": "date-time",
            "type": "string"
          },
          "occurrences": {
            "description": "Most-recent timestamps (newest first), ISO8601",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "read_at": {
            "description": "When the operator marked this row read; null/absent when unread",
            "format": "date-time",
            "type": "string"
          },
          "run_id": {
            "description": "Run that produced this notification (empty when not run-derived)",
            "type": "string"
          },
          "severity": {
            "description": "info | warn | error",
            "type": "string"
          },
          "task_name": {
            "description": "Task that produced this notification (empty for daemon-level events)",
            "type": "string"
          },
          "title": {
            "description": "Human-readable title",
            "type": "string"
          }
        },
        "required": [
          "id",
          "fingerprint",
          "kind",
          "severity",
          "task_name",
          "run_id",
          "title",
          "body",
          "count",
          "occurrences",
          "created_at",
          "last_occurred_at"
        ],
        "type": "object"
      },
      "NotificationUnreadBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/NotificationUnreadBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "count": {
            "description": "Number of notifications with read_at IS NULL",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "count"
        ],
        "type": "object"
      },
      "NotificationUnreadCountEvent": {
        "additionalProperties": false,
        "properties": {
          "unread_count": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "unread_count"
        ],
        "type": "object"
      },
      "NotificationUpdatedEvent": {
        "additionalProperties": false,
        "properties": {
          "notification": {
            "$ref": "#/components/schemas/NotificationDTO"
          },
          "unread_count": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "notification",
          "unread_count"
        ],
        "type": "object"
      },
      "NotificationsListBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/NotificationsListBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "items": {
            "description": "Notifications in id-DESC order",
            "items": {
              "$ref": "#/components/schemas/NotificationDTO"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "next_cursor": {
            "description": "Cursor to pass as 'before' on the next page; empty when exhausted",
            "type": "string"
          }
        },
        "required": [
          "items"
        ],
        "type": "object"
      },
      "PingEvent": {
        "additionalProperties": false,
        "type": "object"
      },
      "ReloadResult": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/ReloadResult.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "added": {
            "description": "Names of tasks added by the reload",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "changed": {
            "description": "Tasks whose definition changed, with the reasons",
            "items": {
              "$ref": "#/components/schemas/ReloadTaskChange"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "removed": {
            "description": "Names of tasks removed by the reload",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "added",
          "removed",
          "changed"
        ],
        "type": "object"
      },
      "ReloadTaskChange": {
        "additionalProperties": false,
        "properties": {
          "name": {
            "description": "Task name",
            "type": "string"
          },
          "reasons": {
            "description": "Why the task is considered changed",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "name",
          "reasons"
        ],
        "type": "object"
      },
      "Run": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/Run.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "end_at": {
            "format": "date-time",
            "type": "string"
          },
          "end_reason": {
            "$ref": "#/components/schemas/EndReason"
          },
          "exit_code": {
            "format": "int64",
            "type": "integer"
          },
          "external_execution_id": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "instance_index": {
            "format": "int64",
            "type": "integer"
          },
          "params": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object"
          },
          "retry_attempt": {
            "format": "int64",
            "type": "integer"
          },
          "retry_of_run_id": {
            "type": "string"
          },
          "start_at": {
            "format": "date-time",
            "type": "string"
          },
          "status": {
            "description": "Run lifecycle phase",
            "enum": [
              "pending",
              "running",
              "ended"
            ],
            "type": "string"
          },
          "task_name": {
            "type": "string"
          },
          "triggered_by": {
            "description": "How the run was triggered",
            "enum": [
              "cron",
              "api",
              "cloud",
              "service",
              "startup"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "task_name",
          "status",
          "exit_code",
          "triggered_by",
          "created_at",
          "retry_attempt",
          "instance_index"
        ],
        "type": "object"
      },
      "RunCompletedEvent": {
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "string"
          },
          "run": {
            "$ref": "#/components/schemas/Run"
          }
        },
        "required": [
          "run"
        ],
        "type": "object"
      },
      "RunCreatedEvent": {
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "string"
          },
          "run": {
            "$ref": "#/components/schemas/Run"
          }
        },
        "required": [
          "run"
        ],
        "type": "object"
      },
      "RunDeletedSSEEvent": {
        "additionalProperties": false,
        "properties": {
          "run_id": {
            "type": "string"
          },
          "task_name": {
            "type": "string"
          }
        },
        "required": [
          "run_id",
          "task_name"
        ],
        "type": "object"
      },
      "RunFailedEvent": {
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "string"
          },
          "run": {
            "$ref": "#/components/schemas/Run"
          }
        },
        "required": [
          "run"
        ],
        "type": "object"
      },
      "RunFilter": {
        "additionalProperties": false,
        "properties": {
          "created_after": {
            "description": "Only runs created at or after this time",
            "format": "date-time",
            "type": "string"
          },
          "created_before": {
            "description": "Only runs created at or before this time",
            "format": "date-time",
            "type": "string"
          },
          "exit_code_max": {
            "description": "Only runs whose exit code is \u003c= this (inclusive)",
            "format": "int64",
            "type": "integer"
          },
          "exit_code_min": {
            "description": "Only runs whose exit code is \u003e= this (inclusive)",
            "format": "int64",
            "type": "integer"
          },
          "retries_only": {
            "description": "Only runs that are a retry (retry_attempt \u003e 0)",
            "type": "boolean"
          },
          "search": {
            "description": "Search query against task_name / id",
            "type": "string"
          },
          "status": {
            "description": "Comma-separated run statuses (phase or end reason); a run matches any listed value",
            "type": "string"
          },
          "task_name": {
            "description": "Filter by task name",
            "type": "string"
          },
          "triggered_by": {
            "description": "Filter by what triggered the run (cron/api/cloud/service/startup)",
            "type": "string"
          }
        },
        "type": "object"
      },
      "RunSelector": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/RunSelector.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "except_ids": {
            "description": "IDs to exclude when MatchAll is true",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "filter": {
            "$ref": "#/components/schemas/RunFilter",
            "description": "Filter to apply when MatchAll is true"
          },
          "ids": {
            "description": "Explicit run IDs to select when MatchAll is false",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "match_all": {
            "description": "When true, selects every run matching Filter except those listed in ExceptIDs",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "RunStartedEvent": {
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "string"
          },
          "run": {
            "$ref": "#/components/schemas/Run"
          }
        },
        "required": [
          "run"
        ],
        "type": "object"
      },
      "RunSummary": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/RunSummary.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "failed": {
            "description": "Number of failed runs",
            "format": "int64",
            "type": "integer"
          },
          "last_failure": {
            "description": "Timestamp of most recent failure",
            "format": "date-time",
            "type": "string"
          },
          "missed": {
            "description": "Number of scheduled runs missed during downtime",
            "format": "int64",
            "type": "integer"
          },
          "success": {
            "description": "Number of successful runs",
            "format": "int64",
            "type": "integer"
          },
          "total": {
            "description": "Total number of runs",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "total",
          "success",
          "failed",
          "missed"
        ],
        "type": "object"
      },
      "RunUpdatedEvent": {
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "string"
          },
          "run": {
            "$ref": "#/components/schemas/Run"
          }
        },
        "required": [
          "run"
        ],
        "type": "object"
      },
      "RunsResponseBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/RunsResponseBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "runs": {
            "description": "List of runs",
            "items": {
              "$ref": "#/components/schemas/Run"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "total": {
            "description": "Total matching runs",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "runs",
          "total"
        ],
        "type": "object"
      },
      "StopRunOutputBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/StopRunOutputBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "message": {
            "description": "Result message",
            "type": "string"
          }
        },
        "required": [
          "message"
        ],
        "type": "object"
      },
      "SystemSampleSSEEvent": {
        "additionalProperties": false,
        "properties": {
          "sample": {
            "$ref": "#/components/schemas/MetricsSample",
            "description": "Resource snapshot, same shape as a metrics-history entry"
          },
          "uptime": {
            "description": "Human-readable daemon uptime",
            "type": "string"
          }
        },
        "required": [
          "sample",
          "uptime"
        ],
        "type": "object"
      },
      "SystemStats": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/SystemStats.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "arch": {
            "description": "CPU architecture (e.g. amd64, arm64)",
            "type": "string"
          },
          "cpu_cores": {
            "description": "Number of CPU cores",
            "format": "int64",
            "type": "integer"
          },
          "cpu_usage": {
            "description": "CPU usage percentage (0-100)",
            "format": "double",
            "type": "number"
          },
          "host": {
            "description": "Hostname",
            "type": "string"
          },
          "mem_total": {
            "description": "Total memory in bytes",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "mem_usage": {
            "description": "Memory usage percentage (0-100)",
            "format": "double",
            "type": "number"
          },
          "mem_used": {
            "description": "Used memory in bytes",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "name": {
            "description": "Application name",
            "type": "string"
          },
          "os": {
            "description": "Operating system (e.g. linux, darwin, windows)",
            "type": "string"
          },
          "uptime": {
            "description": "Human-readable uptime",
            "type": "string"
          },
          "version": {
            "description": "RunWisp version",
            "type": "string"
          },
          "work_dir": {
            "description": "Working directory of the daemon process",
            "type": "string"
          }
        },
        "required": [
          "cpu_usage",
          "mem_usage",
          "mem_total",
          "mem_used",
          "uptime",
          "version",
          "name",
          "cpu_cores",
          "host",
          "os",
          "arch",
          "work_dir"
        ],
        "type": "object"
      },
      "TaskBrief": {
        "additionalProperties": false,
        "properties": {
          "api_trigger": {
            "type": "boolean"
          },
          "catch_up": {
            "type": "string"
          },
          "compose": {
            "$ref": "#/components/schemas/TaskComposeRef"
          },
          "cron": {
            "type": "string"
          },
          "depends_on": {
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "group": {
            "type": "string"
          },
          "instances": {
            "format": "int64",
            "type": "integer"
          },
          "kind": {
            "enum": [
              "task",
              "service"
            ],
            "type": "string"
          },
          "max_concurrent": {
            "format": "int64",
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "on_overlap": {
            "type": "string"
          },
          "parameters": {
            "items": {
              "$ref": "#/components/schemas/TaskParam"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "restart": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "api_trigger"
        ],
        "type": "object"
      },
      "TaskComposeRef": {
        "additionalProperties": false,
        "properties": {
          "file": {
            "type": "string"
          },
          "project_name": {
            "type": "string"
          },
          "service": {
            "type": "string"
          }
        },
        "required": [
          "file",
          "project_name"
        ],
        "type": "object"
      },
      "TaskParam": {
        "additionalProperties": false,
        "properties": {
          "allow_custom": {
            "description": "When choices is set, allow values outside the list",
            "type": "boolean"
          },
          "choices": {
            "description": "Allowed values; renders as a dropdown",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "default": {
            "description": "Default value used by scheduled runs and pre-filled in manual forms",
            "type": "string"
          },
          "description": {
            "description": "Help text shown under the field",
            "type": "string"
          },
          "key": {
            "description": "Canonical parameter key (env name, positional label, or option/flag token)",
            "type": "string"
          },
          "kind": {
            "description": "How the parameter renders into the run",
            "enum": [
              "env",
              "arg",
              "option",
              "flag"
            ],
            "type": "string"
          },
          "required": {
            "description": "Whether a manual trigger must supply a value",
            "type": "boolean"
          },
          "type": {
            "description": "Value type; defaults to string",
            "enum": [
              "string",
              "number"
            ],
            "type": "string"
          }
        },
        "required": [
          "kind",
          "key"
        ],
        "type": "object"
      },
      "TaskResponse": {
        "additionalProperties": false,
        "properties": {
          "api_trigger": {
            "type": "boolean"
          },
          "autostart": {
            "description": "For services: whether instances start at boot. False boots in the stopped state until started via API/UI.",
            "type": "boolean"
          },
          "catch_up": {
            "description": "What to do when cron ticks are missed during downtime",
            "enum": [
              "latest",
              "all",
              "skip"
            ],
            "type": "string"
          },
          "compose": {
            "$ref": "#/components/schemas/TaskComposeRef",
            "description": "Provenance metadata for tasks imported from a docker compose file"
          },
          "cron": {
            "type": "string"
          },
          "depends_on": {
            "description": "For services: service names that must be healthy before this one starts at boot — boot ordering only, not a workflow DAG",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "description": {
            "type": "string"
          },
          "env": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Environment variables overlaid on the task's process env. Values are visible to authenticated operators in the API/UI; env_file values merge in beneath the inline entries.",
            "type": "object"
          },
          "env_file": {
            "description": "Path to a dotenv file whose KEY=VALUE pairs merge into env (inline entries win). Values are visible in the API/UI like inline env.",
            "type": "string"
          },
          "exit_codes": {
            "description": "Process exit codes treated as success; defaults to [0]",
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "graceful_stop": {
            "description": "Window between the stop signal and SIGKILL when a run is stopped, in nanoseconds",
            "format": "int64",
            "type": "integer"
          },
          "group": {
            "type": "string"
          },
          "healthy_after": {
            "description": "For services: an instance that runs at least this long counts as healthy — resets the restart counter and clears the failed-start streak; fast exits below it count toward start_retries, in nanoseconds",
            "format": "int64",
            "type": "integer"
          },
          "instances": {
            "description": "For services: number of always-running instances",
            "format": "int64",
            "type": "integer"
          },
          "jitter": {
            "description": "Cap how far a cron task's start may slip so tasks sharing a fire time take turns through a daemon-wide one-at-a-time gate instead of stampeding; a run starts as soon as the gate frees and slips up to this window only under contention, in nanoseconds",
            "format": "int64",
            "type": "integer"
          },
          "keep_for": {
            "description": "Retention window in nanoseconds; 0 means no cap was configured",
            "format": "int64",
            "type": "integer"
          },
          "keep_runs": {
            "description": "Row-count retention cap; 0 means no cap was configured",
            "format": "int64",
            "type": "integer"
          },
          "kind": {
            "description": "Whether this is a scheduled task or an always-on service",
            "enum": [
              "task",
              "service"
            ],
            "type": "string"
          },
          "log_max_size": {
            "description": "Per-run log size cap in bytes",
            "format": "int64",
            "type": "integer"
          },
          "log_on_full": {
            "description": "What to do when log output exceeds log_max_size",
            "enum": [
              "drop_new",
              "drop_old",
              "kill_task"
            ],
            "type": "string"
          },
          "max_catch_up_runs": {
            "description": "Cap on catch-up runs triggered when catch_up = all",
            "format": "int64",
            "type": "integer"
          },
          "max_concurrent": {
            "description": "Maximum overlapping runs allowed for this task",
            "format": "int64",
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "next_run_at": {
            "type": "string"
          },
          "on_overlap": {
            "description": "How overlapping runs are handled",
            "enum": [
              "queue",
              "skip",
              "terminate"
            ],
            "type": "string"
          },
          "parameters": {
            "description": "Per-execution parameters an operator may supply at manual trigger time; scheduled runs use the declared defaults",
            "items": {
              "$ref": "#/components/schemas/TaskParam"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "priority": {
            "description": "For services: boot start order, lowest first (name breaks ties). Start order only — not a dependency.",
            "format": "int64",
            "type": "integer"
          },
          "queue_max": {
            "description": "Maximum runs that can wait when on_overlap = queue",
            "format": "int64",
            "type": "integer"
          },
          "restart": {
            "description": "Whether and when a task is restarted after completion",
            "enum": [
              "never",
              "always",
              "on_failure"
            ],
            "type": "string"
          },
          "restart_backoff": {
            "description": "Backoff curve between consecutive restarts",
            "enum": [
              "constant",
              "linear",
              "exponential"
            ],
            "type": "string"
          },
          "restart_delay": {
            "description": "Base delay before each restart, in nanoseconds",
            "format": "int64",
            "type": "integer"
          },
          "retry_attempts": {
            "format": "int64",
            "type": "integer"
          },
          "retry_backoff": {
            "description": "Backoff curve between consecutive retries",
            "enum": [
              "constant",
              "linear",
              "exponential"
            ],
            "type": "string"
          },
          "retry_delay": {
            "description": "Base delay before each retry, in nanoseconds",
            "format": "int64",
            "type": "integer"
          },
          "run_on_start": {
            "description": "For tasks: fire once at daemon startup, in addition to any cron schedule",
            "type": "boolean"
          },
          "secrets_file": {
            "description": "Path to a dotenv file whose KEY=VALUE pairs are injected into the task's process env. The path is visible in the API/UI; keys and values never leave the daemon.",
            "type": "string"
          },
          "shell": {
            "description": "Absolute path to the shell interpreter for run scripts; defaults to /bin/sh",
            "type": "string"
          },
          "start_retries": {
            "description": "For services: consecutive fast failures tolerated before an instance is marked FATAL and stops restarting",
            "format": "int64",
            "type": "integer"
          },
          "stop_signal": {
            "description": "Signal sent to stop a run before SIGKILL; defaults to SIGTERM",
            "enum": [
              "SIGTERM",
              "SIGINT",
              "SIGQUIT",
              "SIGHUP",
              "SIGKILL",
              "SIGUSR1",
              "SIGUSR2"
            ],
            "type": "string"
          },
          "timeout": {
            "description": "Per-run timeout in nanoseconds",
            "format": "int64",
            "type": "integer"
          },
          "timezone": {
            "description": "IANA timezone for cron evaluation; falls back to scheduler.timezone, then the daemon's resolved system timezone",
            "type": "string"
          },
          "umask": {
            "description": "Octal file-creation mask applied to the run's process; empty inherits the daemon's umask",
            "type": "string"
          },
          "user": {
            "description": "Run the process as this OS user, in 'user' or 'user:group' form (name or numeric id). Empty runs as the daemon's user; switching users needs the daemon running as root.",
            "type": "string"
          },
          "working_dir": {
            "description": "Resolved working directory for the task's process; empty inherits the daemon's working directory",
            "type": "string"
          }
        },
        "required": [
          "name",
          "api_trigger",
          "autostart"
        ],
        "type": "object"
      },
      "TriggerRunInputBody": {
        "additionalProperties": false,
        "properties": {
          "$schema": {
            "description": "A URL to the JSON Schema for this object.",
            "examples": [
              "http://localhost:9477/schemas/TriggerRunInputBody.json"
            ],
            "format": "uri",
            "readOnly": true,
            "type": "string"
          },
          "params": {
            "additionalProperties": {
              "type": [
                "string",
                "null"
              ]
            },
            "description": "Values for the task's declared parameters, keyed by parameter identity. A null value omits that parameter (overriding its default); an empty string passes an empty value; an absent key uses the declared default.",
            "type": "object"
          }
        },
        "type": "object"
      },
      "TriggeredRunRef": {
        "additionalProperties": false,
        "properties": {
          "run_id": {
            "type": "string"
          },
          "task_name": {
            "type": "string"
          }
        },
        "required": [
          "task_name",
          "run_id"
        ],
        "type": "object"
      }
    }
  },
  "info": {
    "title": "RunWisp API",
    "version": "dev"
  },
  "openapi": "3.1.0",
  "paths": {
    "/api/daemon/log-stream": {
      "get": {
        "description": "Server-Sent Events stream of daemon log lines. Replays the last 100 buffered lines, then emits new lines as they're written until the client disconnects.",
        "operationId": "streamDaemonLog",
        "responses": {
          "200": {
            "content": {
              "text/event-stream": {
                "schema": {
                  "description": "Each oneOf object in the array represents one possible Server Sent Events (SSE) message, serialized as UTF-8 text according to the SSE specification.",
                  "items": {
                    "oneOf": [
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/DaemonLogLineEvent"
                          },
                          "event": {
                            "const": "line",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event line",
                        "type": "object"
                      }
                    ]
                  },
                  "title": "Server Sent Events",
                  "type": "array"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Stream the daemon's recent log output",
        "tags": [
          "System"
        ]
      }
    },
    "/api/info": {
      "get": {
        "operationId": "getInfo",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DaemonInfo"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get daemon info",
        "tags": [
          "System"
        ]
      }
    },
    "/api/instance": {
      "get": {
        "description": "Returns the running daemon's datadir, config path, socket path, pid, version and fingerprint. Used by a second `runwisp` that hit a port conflict to discover and offer to connect to or stop this daemon. Always 403 over non-loopback TCP — the paths are local-only.",
        "operationId": "getInstance",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstanceInfo"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get local daemon identity (loopback/socket only)",
        "tags": [
          "System"
        ]
      }
    },
    "/api/local/credentials": {
      "get": {
        "description": "Returns the in-memory ephemeral password to a local CLI/TUI client arriving on the Unix socket. Always 403 over TCP — even with a valid JWT. Always 404 when the daemon is configured with RUNWISP_PASSWORD.",
        "operationId": "getLocalCredentials",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocalCredentialsBody"
                }
              }
            },
            "description": "OK",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Retrieve the daemon's ephemeral password (Unix socket only)",
        "tags": [
          "System"
        ]
      }
    },
    "/api/notifications": {
      "get": {
        "operationId": "listNotifications",
        "parameters": [
          {
            "description": "Max items per page",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "description": "Max items per page",
              "format": "int64",
              "maximum": 500,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor: return only items with id \u003c before (descending)",
            "explode": false,
            "in": "query",
            "name": "before",
            "schema": {
              "description": "Cursor: return only items with id \u003c before (descending)",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationsListBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List in-app notifications",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/notifications/read": {
      "post": {
        "operationId": "markAllNotificationsRead",
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Mark every unread notification read",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/notifications/stream": {
      "get": {
        "description": "Server-Sent Events stream emitting notification.created and notification.updated as in-app rows are coalesced or marked read/unread.",
        "operationId": "streamNotifications",
        "responses": {
          "200": {
            "content": {
              "text/event-stream": {
                "schema": {
                  "description": "Each oneOf object in the array represents one possible Server Sent Events (SSE) message, serialized as UTF-8 text according to the SSE specification.",
                  "items": {
                    "oneOf": [
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/NotificationCreatedEvent"
                          },
                          "event": {
                            "const": "notification.created",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event notification.created",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/NotificationUpdatedEvent"
                          },
                          "event": {
                            "const": "notification.updated",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event notification.updated",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/NotificationUnreadCountEvent"
                          },
                          "event": {
                            "const": "notifications.unread_count_changed",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event notifications.unread_count_changed",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/PingEvent"
                          },
                          "event": {
                            "const": "ping",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event ping",
                        "type": "object"
                      }
                    ]
                  },
                  "title": "Server Sent Events",
                  "type": "array"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Stream notification create/update events",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/notifications/unread-count": {
      "get": {
        "operationId": "getUnreadNotificationCount",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationUnreadBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Count notifications with read_at IS NULL",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/notifications/{id}/read": {
      "post": {
        "operationId": "markNotificationRead",
        "parameters": [
          {
            "description": "Notification ULID",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "description": "Notification ULID",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Mark a single notification read",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/notifications/{id}/unread": {
      "post": {
        "operationId": "markNotificationUnread",
        "parameters": [
          {
            "description": "Notification ULID",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "description": "Notification ULID",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Mark a single notification unread",
        "tags": [
          "Notifications"
        ]
      }
    },
    "/api/reload": {
      "post": {
        "description": "Re-reads the config file and reconciles the live task set (added/changed/removed). Validate-first: a config that fails to load or changes a restart-only setting is rejected and nothing is applied.",
        "operationId": "reload",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReloadResult"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Reload runwisp.toml",
        "tags": [
          "System"
        ]
      }
    },
    "/api/runs": {
      "get": {
        "operationId": "getAllRuns",
        "parameters": [
          {
            "description": "Max results per page",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "description": "Max results per page",
              "format": "int64",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Pagination offset",
            "explode": false,
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "description": "Pagination offset",
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "Comma-separated run statuses (phase or end reason); a run matches any listed value",
            "explode": false,
            "in": "query",
            "name": "status",
            "schema": {
              "description": "Comma-separated run statuses (phase or end reason); a run matches any listed value",
              "type": "string"
            }
          },
          {
            "description": "Filter by task name",
            "explode": false,
            "in": "query",
            "name": "task_name",
            "schema": {
              "description": "Filter by task name",
              "type": "string"
            }
          },
          {
            "description": "Filter by what triggered the run",
            "explode": false,
            "in": "query",
            "name": "triggered_by",
            "schema": {
              "description": "Filter by what triggered the run",
              "enum": [
                "cron",
                "api",
                "cloud",
                "service",
                "startup",
                ""
              ],
              "type": "string"
            }
          },
          {
            "description": "Only runs created at or after this RFC3339 time",
            "explode": false,
            "in": "query",
            "name": "created_after",
            "schema": {
              "description": "Only runs created at or after this RFC3339 time",
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Only runs created at or before this RFC3339 time",
            "explode": false,
            "in": "query",
            "name": "created_before",
            "schema": {
              "description": "Only runs created at or before this RFC3339 time",
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Only runs whose exit code is \u003e= this (inclusive)",
            "explode": false,
            "in": "query",
            "name": "exit_code_min",
            "schema": {
              "description": "Only runs whose exit code is \u003e= this (inclusive)",
              "pattern": "^-?[0-9]+$",
              "type": "string"
            }
          },
          {
            "description": "Only runs whose exit code is \u003c= this (inclusive)",
            "explode": false,
            "in": "query",
            "name": "exit_code_max",
            "schema": {
              "description": "Only runs whose exit code is \u003c= this (inclusive)",
              "pattern": "^-?[0-9]+$",
              "type": "string"
            }
          },
          {
            "description": "Only runs that are a retry (retry_attempt \u003e 0)",
            "explode": false,
            "in": "query",
            "name": "retries_only",
            "schema": {
              "description": "Only runs that are a retry (retry_attempt \u003e 0)",
              "type": "boolean"
            }
          },
          {
            "description": "Field to sort by",
            "explode": false,
            "in": "query",
            "name": "sort_field",
            "schema": {
              "description": "Field to sort by",
              "enum": [
                "task_name",
                "status",
                "start_at",
                "exit_code",
                "duration",
                "created_at",
                ""
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction",
            "explode": false,
            "in": "query",
            "name": "sort_direction",
            "schema": {
              "description": "Sort direction",
              "enum": [
                "asc",
                "desc",
                ""
              ],
              "type": "string"
            }
          },
          {
            "description": "Search query",
            "explode": false,
            "in": "query",
            "name": "search",
            "schema": {
              "description": "Search query",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunsResponseBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List all runs",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/runs/bulk/cancel": {
      "post": {
        "operationId": "bulkCancelRuns",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunSelector"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkAffectedBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Cancel every running run matched by the selector",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/runs/bulk/delete": {
      "post": {
        "description": "Marks matching terminal runs as deleted. Rows remain on disk for a short undo window before the purger reclaims them.",
        "operationId": "bulkDeleteRuns",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunSelector"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkAffectedBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Soft-delete every run matched by the selector",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/runs/bulk/rerun": {
      "post": {
        "operationId": "bulkRerunRuns",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunSelector"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkRerunBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Re-run the unique tasks behind the selector's runs",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/runs/bulk/restore": {
      "post": {
        "operationId": "bulkRestoreRuns",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunSelector"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkAffectedBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Restore soft-deleted runs matching the selector",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/runs/summary": {
      "get": {
        "operationId": "getRunSummary",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunSummary"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get aggregate run statistics",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/runs/{runId}": {
      "get": {
        "operationId": "getRunById",
        "parameters": [
          {
            "description": "Run ULID",
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "description": "Run ULID",
              "maxLength": 26,
              "minLength": 26,
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Run"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get a single run by ID",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/stream": {
      "get": {
        "description": "Single Server-Sent Events feed the web UI holds open per tab: run lifecycle events, periodic system resource samples, config-staleness flips, and in-app notifications. A client subscribes only to the event names it cares about.",
        "operationId": "streamAppEvents",
        "responses": {
          "200": {
            "content": {
              "text/event-stream": {
                "schema": {
                  "description": "Each oneOf object in the array represents one possible Server Sent Events (SSE) message, serialized as UTF-8 text according to the SSE specification.",
                  "items": {
                    "oneOf": [
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/ConfigStaleSSEEvent"
                          },
                          "event": {
                            "const": "config.stale",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event config.stale",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/NotificationCreatedEvent"
                          },
                          "event": {
                            "const": "notification.created",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event notification.created",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/NotificationUpdatedEvent"
                          },
                          "event": {
                            "const": "notification.updated",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event notification.updated",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/NotificationUnreadCountEvent"
                          },
                          "event": {
                            "const": "notifications.unread_count_changed",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event notifications.unread_count_changed",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/PingEvent"
                          },
                          "event": {
                            "const": "ping",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event ping",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/RunCompletedEvent"
                          },
                          "event": {
                            "const": "run.completed",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event run.completed",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/RunCreatedEvent"
                          },
                          "event": {
                            "const": "run.created",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event run.created",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/RunDeletedSSEEvent"
                          },
                          "event": {
                            "const": "run.deleted",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event run.deleted",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/RunFailedEvent"
                          },
                          "event": {
                            "const": "run.failed",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event run.failed",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/RunStartedEvent"
                          },
                          "event": {
                            "const": "run.started",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event run.started",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/RunUpdatedEvent"
                          },
                          "event": {
                            "const": "run.updated",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event run.updated",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/SystemSampleSSEEvent"
                          },
                          "event": {
                            "const": "system",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event system",
                        "type": "object"
                      }
                    ]
                  },
                  "title": "Server Sent Events",
                  "type": "array"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Stream live application events",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/system": {
      "get": {
        "operationId": "getSystemStats",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemStats"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get system statistics",
        "tags": [
          "System"
        ]
      }
    },
    "/api/system/history": {
      "get": {
        "operationId": "getMetricsHistory",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/MetricsSample"
                  },
                  "type": [
                    "array",
                    "null"
                  ]
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get historical system metrics",
        "tags": [
          "System"
        ]
      }
    },
    "/api/tasks": {
      "get": {
        "operationId": "getTasks",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/TaskResponse"
                  },
                  "type": [
                    "array",
                    "null"
                  ]
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List all tasks",
        "tags": [
          "Tasks"
        ]
      }
    },
    "/api/tasks/{taskName}/log/search": {
      "get": {
        "description": "Streams on disk through the task's runs newest-first and returns matching lines. Pure on-demand scan; no index is maintained. Use `cursor` to paginate beyond the per-request hit/run budget.",
        "operationId": "searchLogs",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          },
          {
            "description": "Restrict the search to one run (ULID). Empty searches every non-deleted run of the task.",
            "explode": false,
            "in": "query",
            "name": "run_id",
            "schema": {
              "description": "Restrict the search to one run (ULID). Empty searches every non-deleted run of the task.",
              "type": "string"
            }
          },
          {
            "description": "Substring (or regex when regex=true) to search for",
            "explode": false,
            "in": "query",
            "name": "q",
            "schema": {
              "description": "Substring (or regex when regex=true) to search for",
              "maxLength": 1024,
              "minLength": 1,
              "type": "string"
            }
          },
          {
            "description": "Treat q as an RE2 regular expression",
            "explode": false,
            "in": "query",
            "name": "regex",
            "schema": {
              "description": "Treat q as an RE2 regular expression",
              "type": "boolean"
            }
          },
          {
            "description": "Match case-sensitively (default is case-insensitive)",
            "explode": false,
            "in": "query",
            "name": "case",
            "schema": {
              "description": "Match case-sensitively (default is case-insensitive)",
              "type": "boolean"
            }
          },
          {
            "description": "Max hits returned (default 200)",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Max hits returned (default 200)",
              "format": "int64",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Opaque continuation token returned by a previous call",
            "explode": false,
            "in": "query",
            "name": "cursor",
            "schema": {
              "description": "Opaque continuation token returned by a previous call",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogSearchBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Search log lines across runs of a task",
        "tags": [
          "Logs"
        ]
      }
    },
    "/api/tasks/{taskName}/restart": {
      "post": {
        "operationId": "restartService",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StopRunOutputBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Restart all instances of a service",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/tasks/{taskName}/run": {
      "post": {
        "description": "Triggers the task and returns the pending run immediately. Pass `wait=true` to instead hold the request open until the run finishes and return it with its exit code and end reason — a one-call alternative to triggering then polling.",
        "operationId": "triggerRun",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          },
          {
            "description": "Block until the run finishes and return the completed run (with exit_code and end_reason). Best for short tasks; long runs may exceed reverse-proxy timeouts — follow the log stream or poll instead.",
            "explode": false,
            "in": "query",
            "name": "wait",
            "schema": {
              "description": "Block until the run finishes and return the completed run (with exit_code and end_reason). Best for short tasks; long runs may exceed reverse-proxy timeouts — follow the log stream or poll instead.",
              "type": "boolean"
            }
          },
          {
            "description": "With wait=true, the maximum seconds to hold the request open. On timeout the run keeps running and the response returns it in its current (non-terminal) state.",
            "explode": false,
            "in": "query",
            "name": "wait_timeout",
            "schema": {
              "default": 300,
              "description": "With wait=true, the maximum seconds to hold the request open. On timeout the run keeps running and the response returns it in its current (non-terminal) state.",
              "format": "int64",
              "maximum": 3600,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TriggerRunInputBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Run"
                }
              }
            },
            "description": "Created"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Trigger a new run",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/tasks/{taskName}/runs": {
      "get": {
        "operationId": "getTaskRuns",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          },
          {
            "description": "Max results per page",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 50,
              "description": "Max results per page",
              "format": "int64",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Pagination offset",
            "explode": false,
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "description": "Pagination offset",
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "Comma-separated run statuses (phase or end reason); a run matches any listed value",
            "explode": false,
            "in": "query",
            "name": "status",
            "schema": {
              "description": "Comma-separated run statuses (phase or end reason); a run matches any listed value",
              "type": "string"
            }
          },
          {
            "description": "Filter by task name",
            "explode": false,
            "in": "query",
            "name": "task_name",
            "schema": {
              "description": "Filter by task name",
              "type": "string"
            }
          },
          {
            "description": "Filter by what triggered the run",
            "explode": false,
            "in": "query",
            "name": "triggered_by",
            "schema": {
              "description": "Filter by what triggered the run",
              "enum": [
                "cron",
                "api",
                "cloud",
                "service",
                "startup",
                ""
              ],
              "type": "string"
            }
          },
          {
            "description": "Only runs created at or after this RFC3339 time",
            "explode": false,
            "in": "query",
            "name": "created_after",
            "schema": {
              "description": "Only runs created at or after this RFC3339 time",
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Only runs created at or before this RFC3339 time",
            "explode": false,
            "in": "query",
            "name": "created_before",
            "schema": {
              "description": "Only runs created at or before this RFC3339 time",
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Only runs whose exit code is \u003e= this (inclusive)",
            "explode": false,
            "in": "query",
            "name": "exit_code_min",
            "schema": {
              "description": "Only runs whose exit code is \u003e= this (inclusive)",
              "pattern": "^-?[0-9]+$",
              "type": "string"
            }
          },
          {
            "description": "Only runs whose exit code is \u003c= this (inclusive)",
            "explode": false,
            "in": "query",
            "name": "exit_code_max",
            "schema": {
              "description": "Only runs whose exit code is \u003c= this (inclusive)",
              "pattern": "^-?[0-9]+$",
              "type": "string"
            }
          },
          {
            "description": "Only runs that are a retry (retry_attempt \u003e 0)",
            "explode": false,
            "in": "query",
            "name": "retries_only",
            "schema": {
              "description": "Only runs that are a retry (retry_attempt \u003e 0)",
              "type": "boolean"
            }
          },
          {
            "description": "Field to sort by",
            "explode": false,
            "in": "query",
            "name": "sort_field",
            "schema": {
              "description": "Field to sort by",
              "enum": [
                "task_name",
                "status",
                "start_at",
                "exit_code",
                "duration",
                "created_at",
                ""
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction",
            "explode": false,
            "in": "query",
            "name": "sort_direction",
            "schema": {
              "description": "Sort direction",
              "enum": [
                "asc",
                "desc",
                ""
              ],
              "type": "string"
            }
          },
          {
            "description": "Search query",
            "explode": false,
            "in": "query",
            "name": "search",
            "schema": {
              "description": "Search query",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunsResponseBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List runs for a task",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/tasks/{taskName}/runs/{runId}": {
      "delete": {
        "operationId": "deleteRun",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          },
          {
            "description": "Run ULID",
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "description": "Run ULID",
              "maxLength": 26,
              "minLength": 26,
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Delete a run",
        "tags": [
          "Runs"
        ]
      },
      "get": {
        "operationId": "getRun",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          },
          {
            "description": "Run ULID",
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "description": "Run ULID",
              "maxLength": 26,
              "minLength": 26,
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Run"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get a single run",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/tasks/{taskName}/runs/{runId}/log": {
      "get": {
        "description": "Returns a JSON page of absolute-line-numbered log entries. Use `from` (negative for tail) and `limit` to window the result.",
        "operationId": "getLogPage",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          },
          {
            "description": "Run ULID",
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "description": "Run ULID",
              "maxLength": 26,
              "minLength": 26,
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
              "type": "string"
            }
          },
          {
            "description": "Anchor line number; 0 is the first line, negative values count from end (default -1000)",
            "explode": false,
            "in": "query",
            "name": "from",
            "schema": {
              "default": -1000,
              "description": "Anchor line number; 0 is the first line, negative values count from end (default -1000)",
              "format": "int64",
              "type": "integer"
            }
          },
          {
            "description": "Max lines returned (default 1000)",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "description": "Max lines returned (default 1000)",
              "format": "int64",
              "maximum": 10000,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogPageBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get a page of log lines",
        "tags": [
          "Logs"
        ]
      }
    },
    "/api/tasks/{taskName}/runs/{runId}/log/line/{lineNum}/history": {
      "get": {
        "description": "Returns the prior whole-region frames a progress bar or multi-line redraw passed through before settling into the committed line. Empty unless the line's `frame_count` is non-zero.",
        "operationId": "getLogLineHistory",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          },
          {
            "description": "Run ULID",
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "description": "Run ULID",
              "maxLength": 26,
              "minLength": 26,
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
              "type": "string"
            }
          },
          {
            "description": "Anchor line number to fetch frame history for",
            "in": "path",
            "name": "lineNum",
            "required": true,
            "schema": {
              "description": "Anchor line number to fetch frame history for",
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogLineHistoryBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get the frame history of a settled progress bar / redraw line",
        "tags": [
          "Logs"
        ]
      }
    },
    "/api/tasks/{taskName}/runs/{runId}/log/raw": {
      "get": {
        "description": "Concatenates the rotated-away segment (`.log.prev`) and current segment so a single download captures the operator-visible byte stream.",
        "operationId": "getLogRaw",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          },
          {
            "description": "Run ULID",
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "description": "Run ULID",
              "maxLength": 26,
              "minLength": 26,
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "contentEncoding": "base64",
                  "type": "string"
                }
              }
            },
            "description": "OK",
            "headers": {
              "Content-Type": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Download the run's full log as text/plain",
        "tags": [
          "Logs"
        ]
      }
    },
    "/api/tasks/{taskName}/runs/{runId}/log/stream": {
      "get": {
        "description": "Server-Sent Events stream of absolute-line-numbered log entries. Replays history starting at `from` (or `Last-Event-ID + 1`), then follows live output until the run terminates.",
        "operationId": "streamLog",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          },
          {
            "description": "Run ULID",
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "description": "Run ULID",
              "maxLength": 26,
              "minLength": 26,
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
              "type": "string"
            }
          },
          {
            "description": "Anchor line number; 0 is the first line, negative values count from end (default -1000)",
            "explode": false,
            "in": "query",
            "name": "from",
            "schema": {
              "default": -1000,
              "description": "Anchor line number; 0 is the first line, negative values count from end (default -1000)",
              "format": "int64",
              "type": "integer"
            }
          },
          {
            "description": "Cap on backfilled lines (default 5000)",
            "explode": false,
            "in": "query",
            "name": "replay_limit",
            "schema": {
              "description": "Cap on backfilled lines (default 5000)",
              "format": "int64",
              "maximum": 50000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Native SSE resume cursor; takes precedence over the from query",
            "in": "header",
            "name": "Last-Event-ID",
            "schema": {
              "description": "Native SSE resume cursor; takes precedence over the from query",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "text/event-stream": {
                "schema": {
                  "description": "Each oneOf object in the array represents one possible Server Sent Events (SSE) message, serialized as UTF-8 text according to the SSE specification.",
                  "items": {
                    "oneOf": [
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/LogDoneEvent"
                          },
                          "event": {
                            "const": "done",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event done",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/LogDroppedEvent"
                          },
                          "event": {
                            "const": "dropped",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event dropped",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/LogLineSSEEvent"
                          },
                          "event": {
                            "const": "line",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event line",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/LogRegionSSEEvent"
                          },
                          "event": {
                            "const": "region",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event region",
                        "type": "object"
                      },
                      {
                        "properties": {
                          "data": {
                            "$ref": "#/components/schemas/LogRotatedEvent"
                          },
                          "event": {
                            "const": "rotated",
                            "description": "The event name.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The event ID.",
                            "type": "integer"
                          },
                          "retry": {
                            "description": "The retry time in milliseconds.",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "data",
                          "event"
                        ],
                        "title": "Event rotated",
                        "type": "object"
                      }
                    ]
                  },
                  "title": "Server Sent Events",
                  "type": "array"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Stream a run's log lines as SSE",
        "tags": [
          "Logs"
        ]
      }
    },
    "/api/tasks/{taskName}/runs/{runId}/stop": {
      "post": {
        "operationId": "stopRun",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          },
          {
            "description": "Run ULID",
            "in": "path",
            "name": "runId",
            "required": true,
            "schema": {
              "description": "Run ULID",
              "maxLength": 26,
              "minLength": 26,
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StopRunOutputBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Stop a running task",
        "tags": [
          "Runs"
        ]
      }
    },
    "/api/tasks/{taskName}/stop": {
      "post": {
        "description": "Cancels every live instance and marks the service stopped. The supervisor stops refilling slots until a restart is issued or the daemon is restarted.",
        "operationId": "stopService",
        "parameters": [
          {
            "description": "Task name",
            "in": "path",
            "name": "taskName",
            "required": true,
            "schema": {
              "description": "Task name",
              "maxLength": 100,
              "minLength": 1,
              "pattern": "^[a-zA-Z0-9._:-]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StopRunOutputBody"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Stop a service for the daemon's lifetime",
        "tags": [
          "Runs"
        ]
      }
    }
  },
  "servers": [
    {
      "url": "http://localhost:9477"
    }
  ]
}
