{
  "openapi": "3.1.0",
  "info": {
    "title": "Network Simulation API",
    "description": "Scala's public API for the network simulation platform",
    "contact": {
      "name": "Eric Barsalou",
      "email": "info@scalacomputing.com"
    },
    "license": {
      "name": "Proprietary"
    },
    "version": "1.2.0"
  },
  "servers": [
    {
      "url": "https://api.scalacomputing.com",
      "description": "Production API server"
    }
  ],
  "security": [
    {
      "bearer_auth": []
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Health check endpoint",
        "operationId": "health_check",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/ready": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Readiness check endpoint",
        "operationId": "readiness_check",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is ready",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadinessResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service is not ready",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadinessResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/models": {
      "get": {
        "summary": "List available models",
        "tags": [
          "models"
        ],
        "operationId": "list_models",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token to fetch results after a specific item",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Filter by model type (comma-separated for multiple)",
            "schema": {
              "$ref": "#/components/schemas/ModelType"
            }
          },
          {
            "name": "vendor",
            "in": "query",
            "description": "Filter by vendor identifier",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Full-text search across name and description fields (case-insensitive)",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of models",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelsListResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/models/{model_id}": {
      "get": {
        "summary": "Get model details",
        "tags": [
          "models"
        ],
        "operationId": "get_model",
        "parameters": [
          {
            "name": "model_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "query",
            "description": "Specific version to retrieve (defaults to latest stable)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Model details in ComponentDeclaration format - copy-paste ready for configuration components array",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComponentDeclaration"
                }
              }
            }
          },
          "404": {
            "description": "Model not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/models/{model_id}/versions": {
      "get": {
        "summary": "List model versions",
        "tags": [
          "models"
        ],
        "operationId": "list_model_versions",
        "parameters": [
          {
            "name": "model_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of versions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelVersionsResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/templates": {
      "get": {
        "summary": "List templates",
        "tags": [
          "templates"
        ],
        "operationId": "list_templates",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token to fetch results after a specific item",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "description": "Filter by template category",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Full-text search across name and description fields (case-insensitive)",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of templates",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplatesListResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "post": {
        "summary": "Create template",
        "tags": [
          "templates"
        ],
        "operationId": "create_template",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTemplateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/templates/{template_id}": {
      "get": {
        "summary": "Get template details",
        "tags": [
          "templates"
        ],
        "operationId": "get_template",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Template details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/templates/{template_id}/clone": {
      "post": {
        "summary": "Clone template to workspace",
        "tags": [
          "templates"
        ],
        "operationId": "clone_template",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloneRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Configuration created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/components": {
      "get": {
        "summary": "List component types",
        "tags": [
          "components"
        ],
        "operationId": "list_components",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token to fetch results after a specific item",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "description": "Filter by category",
            "schema": {
              "type": "string",
              "enum": [
                "model",
                "topology",
                "application"
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Filter by type within category",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of component types",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComponentsListResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/components/{component_id}": {
      "get": {
        "summary": "Get component schema",
        "tags": [
          "components"
        ],
        "operationId": "get_component",
        "parameters": [
          {
            "name": "component_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "query",
            "description": "Specific version (defaults to latest)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "notes",
            "in": "query",
            "description": "Include product notes in response (defaults to false)",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Component schema",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComponentSchema"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/topology/validate": {
      "post": {
        "summary": "Validate topology without saving",
        "description": "Validates the provided topology components, containers, applications, and links using the same validation path as stored configurations. This enables real-time validation in the UI wizard before a configuration is saved.",
        "tags": [
          "topology"
        ],
        "operationId": "validate_topology",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TopologyValidateRequest"
              },
              "example": {
                "components": [
                  {
                    "name": "FabricSwitch",
                    "type": "switch",
                    "model": "ScalaSwitch",
                    "version": "3.2.1",
                    "typedParameters": {
                      "NumUpLinks": {
                        "type": "uint",
                        "value": 1
                      },
                      "NumDownLinks": {
                        "type": "uint",
                        "value": 8
                      },
                      "SwitchingCapacity": {
                        "type": "datarate",
                        "unit": "Gbps",
                        "value": 3200
                      }
                    }
                  },
                  {
                    "name": "RackSwitch",
                    "type": "switch",
                    "model": "ScalaSwitch",
                    "version": "3.2.1",
                    "typedParameters": {
                      "NumUpLinks": {
                        "type": "uint",
                        "value": 2
                      },
                      "NumDownLinks": {
                        "type": "uint",
                        "value": 4
                      },
                      "SwitchingCapacity": {
                        "type": "datarate",
                        "unit": "Gbps",
                        "value": 1600
                      }
                    }
                  },
                  {
                    "name": "Nic",
                    "type": "nic",
                    "model": "ScalaNic",
                    "version": "3.1.1",
                    "typedParameters": {
                      "NetworkInterface": {
                        "UplinkNetworkInterface": {
                          "DataRate": {
                            "type": "datarate",
                            "unit": "Gbps",
                            "value": 100
                          }
                        }
                      }
                    }
                  },
                  {
                    "name": "Host",
                    "type": "server",
                    "model": "ScalaHost",
                    "version": "3.1.1",
                    "typedParameters": {},
                    "allowedComponents": [
                      "nic"
                    ],
                    "components": [
                      {
                        "name": "Nic",
                        "count": 1,
                        "type": "nic"
                      }
                    ]
                  }
                ],
                "containers": [
                  {
                    "type": "rack",
                    "name": "Rack",
                    "allowedComponents": [
                      "switch",
                      "server"
                    ],
                    "components": [
                      {
                        "name": "RackSwitch",
                        "count": 1,
                        "type": "switch",
                        "model": "ScalaSwitch"
                      },
                      {
                        "name": "Host",
                        "count": 4,
                        "type": "server",
                        "model": "ScalaHost"
                      }
                    ]
                  },
                  {
                    "type": "pod",
                    "name": "Pod",
                    "allowedComponents": [
                      "switch",
                      "rack"
                    ],
                    "components": [
                      {
                        "name": "FabricSwitch",
                        "count": 2,
                        "type": "switch",
                        "model": "ScalaSwitch"
                      },
                      {
                        "name": "Rack",
                        "count": 2,
                        "type": "rack"
                      }
                    ]
                  }
                ],
                "applications": [
                  {
                    "name": "TrafficGen",
                    "type": "application",
                    "model": "ScalaTrafficGeneratorApplication",
                    "version": "3.1.1",
                    "trafficType": "non-coordinated",
                    "typedParameters": {
                      "TrafficPattern": {
                        "type": "string",
                        "value": "uniform-random"
                      },
                      "MessageSize": {
                        "type": "bytes",
                        "unit": "KB",
                        "value": 16
                      }
                    }
                  }
                ],
                "links": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation result with topology-specific data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TopologyValidationResponse"
                },
                "example": {
                  "validation": {
                    "valid": true,
                    "status": "valid",
                    "errors": null,
                    "warnings": null,
                    "info": [
                      {
                        "message": "Preprocessor validation (PASS): Topology validated successfully",
                        "severity": "info",
                        "code": "PREPROCESSOR_VALIDATION_NOTE",
                        "path": null,
                        "component": null,
                        "parameter": null
                      }
                    ]
                  },
                  "simulationParameters": [
                    {
                      "label": "Total Hosts",
                      "name": "TotalHosts",
                      "value": 8
                    },
                    {
                      "label": "Total NICs",
                      "name": "TotalNics",
                      "value": 8
                    }
                  ],
                  "switchBandwidth": [
                    {
                      "model": "ScalaSwitch",
                      "name": "FabricSwitch",
                      "networkTier": 1,
                      "switchingCapacity": 3200,
                      "switchingCapacityUnit": "Gbps"
                    }
                  ],
                  "topologyMap": "",
                  "checksum": "abc123def456"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations": {
      "get": {
        "summary": "List configurations",
        "tags": [
          "configurations"
        ],
        "operationId": "list_configurations",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token to fetch results after a specific item",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by configuration status (comma-separated for multiple)",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "validated",
                "invalid"
              ]
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Full-text search across name and description fields (case-insensitive)",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            }
          },
          {
            "name": "createdAfter",
            "in": "query",
            "description": "Filter to items created on or after this timestamp (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "description": "Filter to items created before this timestamp (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of configurations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationsListResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "post": {
        "summary": "Create configuration",
        "tags": [
          "configurations"
        ],
        "operationId": "create_configuration",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfigurationRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Configuration created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}": {
      "get": {
        "summary": "Get configuration",
        "tags": [
          "configurations"
        ],
        "operationId": "get_configuration",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configuration details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "patch": {
        "summary": "Update configuration",
        "tags": [
          "configurations"
        ],
        "operationId": "update_configuration",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfigurationUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuration updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationDetails"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request: a malformed body, duplicate component or container names, a body that fails conversion or structural validation, a configuration in the template workspace, a body carrying activeMappingFile, which only the mapping-file attach and detach operations write, or, while a mapping file is attached, an activeTraceset naming no traceset (code VALIDATION_ERROR).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict, while a mapping file is attached and the body carries activeTraceset. Code TRACESET_CONFLICTS_WITH_MAPPING when that traceset's rank count differs from the mapping file's: detach the mapping file first, or use a traceset with its rank count.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity. Code MAPPING_PARAMS_LOCKED when a mapping file is attached and the updated configuration would leave a Chakra application without UseMapping true and MappingFileName chakra-mapping.txt: an edit of either parameter, an applications array that drops or changes them, or an application re-typed to Chakra. Detach the mapping file first, make the change, then attach it again. Code UNPROCESSABLE_ENTITY when a mapping file is attached, the body carries activeTraceset, and that traceset has no rank count: none was declared for it, none derives from its workloadMetadata, and none is recorded for its files. The refusal does not resolve on retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "delete": {
        "summary": "Delete configuration",
        "tags": [
          "configurations"
        ],
        "operationId": "delete_configuration",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Configuration deleted"
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/validate": {
      "post": {
        "summary": "Validate configuration",
        "tags": [
          "configurations"
        ],
        "operationId": "validate_configuration",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Validation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/traceset": {
      "get": {
        "summary": "List available tracesets for configuration",
        "description": "Returns tracesets that can be attached to configuration applications. Use scope=global to list all tracesets across all workspaces, or scope=workspace to filter by the configuration's workspace only.",
        "tags": [
          "configurations"
        ],
        "operationId": "list_configuration_tracesets",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by traceset status (completed, uploading, failed)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token for pagination",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "description": "Scope filter for tracesets. 'global' returns all tracesets across all workspaces (default). 'workspace' returns only tracesets in the configuration's workspace.",
            "schema": {
              "type": "string",
              "enum": [
                "global",
                "workspace"
              ],
              "default": "global"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of available tracesets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationTracesetsListResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "patch": {
        "summary": "Attach traceset to configuration",
        "description": "Sets the activeTraceset field on the configuration to reference the specified traceset. Requires at least one application with trafficType 'chakra' to exist in the configuration. Workspace-agnostic: any traceset can be attached regardless of workspace.",
        "tags": [
          "configurations"
        ],
        "operationId": "attach_traceset_to_configuration",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AttachTracesetRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Traceset attached successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachTracesetResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (traceset not found, no Chakra application in configuration)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict. Code TRACESET_CONFLICTS_WITH_MAPPING when a mapping file is attached to the configuration and its rank count differs from this traceset's: detach the mapping file first, or attach a traceset with its rank count.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity, code UNPROCESSABLE_ENTITY, in three cases, none of which resolves on retry. The traceset has no rank count: none was declared for it, none derives from its workloadMetadata, and none is recorded for its files. The traceset's rank count is zero or negative: the traceset data is malformed and cannot be used for a Chakra simulation. The traceset's rank count exceeds the platform maximum of 4,096.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/mapping-file": {
      "patch": {
        "summary": "Attach mapping file to configuration",
        "description": "Sets the activeMappingFile field on the configuration and writes UseMapping and MappingFileName into every application with trafficType 'chakra', as a new configuration version. Requires at least one Chakra application, an attached traceset, and a mapping file whose rank count equals the traceset's rank count.",
        "tags": [
          "mapping-files"
        ],
        "operationId": "attach_mapping_file_to_configuration",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AttachMappingFileRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mapping file attached successfully; returns the new configuration version",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationDetails"
                }
              }
            }
          },
          "400": {
            "description": "Malformed configuration ID or mapping file ID, a request body that fails validation, or a configuration in the template workspace (reserved for standard templates)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found, or mapping file not found, deleted, or held by another workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The configuration has no attached traceset (MAPPING_REQUIRES_TRACESET).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "The configuration has no Chakra application (MAPPING_REQUIRES_CHAKRA_APP), the attached traceset has no rank count, because none was declared for it, none derives from its workloadMetadata, and none is recorded for its files (UNPROCESSABLE_ENTITY, not resolved by retrying), or the mapping file's rank count differs from the traceset's (MAPPING_RANK_COUNT_MISMATCH).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "delete": {
        "summary": "Detach mapping file from configuration",
        "description": "Removes the activeMappingFile field and writes UseMapping false and an empty MappingFileName into every Chakra application, restoring default placement, as a new configuration version. The mapping file itself is untouched and stays attachable to other configurations.",
        "tags": [
          "mapping-files"
        ],
        "operationId": "detach_mapping_file_from_configuration",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "responses": {
          "200": {
            "description": "Mapping file detached successfully; returns the new configuration version",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationDetails"
                }
              }
            }
          },
          "400": {
            "description": "Malformed configuration ID, or a configuration in the template workspace (reserved for standard templates)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found, or no mapping file attached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/versions": {
      "get": {
        "summary": "List configuration versions",
        "tags": [
          "configurations"
        ],
        "operationId": "list_configuration_versions",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of version summaries",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationVersionsListResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/versions/{version}": {
      "get": {
        "summary": "Get specific configuration version",
        "tags": [
          "configurations"
        ],
        "operationId": "get_configuration_version",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configuration version details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationVersion"
                }
              }
            }
          },
          "404": {
            "description": "Version not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/versions/{version}/switch-bandwidth": {
      "get": {
        "summary": "Get switch bandwidth by tier for a configuration version",
        "description": "Serves the per-tier rollup of the native validator's switch-bandwidth records persisted for this version. A version with no recorded row returns 404, never an empty or zero rollup: the version did not validate, or it validated before the records were persisted and the boot back-fill has not reached it yet.",
        "tags": [
          "configurations"
        ],
        "operationId": "get_configuration_version_switch_bandwidth",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Per-tier switch bandwidth",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationSwitchBandwidth"
                }
              }
            }
          },
          "400": {
            "description": "Malformed configuration ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No switch bandwidth is recorded for this version: it did not validate, has not been back-filled yet, does not exist, or its configuration is deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Stored switch bandwidth could not be rolled up",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/components": {
      "get": {
        "summary": "List configuration components",
        "description": "Returns all components from the configuration's components array with optional type filtering",
        "tags": [
          "configurations"
        ],
        "operationId": "list_configuration_components",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Filter by component type (switch, nic, server, host)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token for pagination",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "withDetails",
            "in": "query",
            "description": "When true, includes full typedParameters for each component. Defaults to false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of components",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationComponentsListResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "post": {
        "summary": "Add component to configuration",
        "description": "Adds a component, container, or layer to the configuration by looking up the model from the database. For switch/nic/server: adds to components array. For rack/pod: adds to containers array. For layer: adds to links array.",
        "tags": [
          "configurations"
        ],
        "operationId": "add_configuration_component",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "modelId",
            "in": "query",
            "required": true,
            "description": "Model identifier — KSUID (model_xxx) or model name (e.g., ScalaSwitch). Server resolves version and default parameters.",
            "schema": {
              "type": "string"
            },
            "example": "ScalaSwitch"
          },
          {
            "name": "type",
            "in": "query",
            "required": true,
            "description": "Component type: switch, nic, server, rack, pod, or layer",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": true,
            "description": "Unique name for this component in the configuration",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "example": "my-spine-switch"
          },
          {
            "name": "version",
            "in": "query",
            "required": false,
            "description": "Optional model version. If omitted, uses latest stable version.",
            "schema": {
              "type": "string"
            },
            "example": "3.2.1"
          }
        ],
        "responses": {
          "201": {
            "description": "Component added",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComponentDeclaration"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (model not found, invalid parameters)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/components/{component_name}": {
      "delete": {
        "summary": "Remove component from configuration",
        "description": "Removes a component from the configuration's components array. Cascades removal to all container references, topology references, and child references in other components.",
        "tags": [
          "configurations"
        ],
        "operationId": "remove_configuration_component",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "component_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "responses": {
          "204": {
            "description": "Component removed from configuration"
          },
          "404": {
            "description": "Configuration or component not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/containers": {
      "get": {
        "summary": "List configuration containers",
        "description": "Returns all containers from the configuration with optional type filtering",
        "tags": [
          "configurations"
        ],
        "operationId": "list_configuration_containers",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Filter by container type (rack, pod)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token for pagination",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of containers",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationContainersListResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/containers/{container_name}": {
      "patch": {
        "summary": "Add component to container",
        "description": "Adds a component reference to the specified container. Validates that the component type is in the container's allowed list.",
        "tags": [
          "configurations"
        ],
        "operationId": "add_component_to_container",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "container_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddContainerComponentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Component added to container",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContainerDefinition"
                }
              }
            }
          },
          "400": {
            "description": "Component type not allowed in container",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or container not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/containers/{container_name}/components/{component_name}": {
      "delete": {
        "summary": "Remove component from container",
        "description": "Removes a component reference from the specified container",
        "tags": [
          "configurations"
        ],
        "operationId": "remove_component_from_container",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "container_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "component_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Component removed from container"
          },
          "404": {
            "description": "Configuration, container, or component not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "patch": {
        "summary": "Update component in container",
        "description": "Updates count and/or group on an existing component reference in the specified container. At least one of count or group must be provided.",
        "tags": [
          "configurations"
        ],
        "operationId": "update_container_component",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "container_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "component_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContainerComponentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Component updated in container",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContainerDefinition"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (empty patch, count < 1)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration, container, or component not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/containers/{container_name}/allowed": {
      "get": {
        "summary": "Get allowed component types for container",
        "description": "Returns the list of component types allowed in this container based on its type",
        "tags": [
          "configurations"
        ],
        "operationId": "get_container_allowed_types",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "container_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Allowed component types",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AllowedTypesResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or container not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/applications": {
      "get": {
        "summary": "List configuration applications",
        "description": "Returns all applications in the configuration's topology",
        "tags": [
          "configurations"
        ],
        "operationId": "list_configuration_applications",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "withDetails",
            "in": "query",
            "description": "When true, includes full typedParameters for each application. Defaults to false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of applications",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationApplicationsListResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "post": {
        "summary": "Add application to configuration",
        "description": "Adds an application to the configuration's topology by looking up the model from the database. Server resolves traffic type, version, and default parameters from the model.",
        "tags": [
          "configurations"
        ],
        "operationId": "add_configuration_application",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "modelId",
            "in": "query",
            "required": true,
            "description": "Application model identifier — KSUID (model_xxx) or model name (e.g., ScalaChakraGenerator). Server resolves traffic type, version, and default parameters.",
            "schema": {
              "type": "string"
            },
            "example": "ScalaChakraGenerator"
          },
          {
            "name": "name",
            "in": "query",
            "required": true,
            "description": "Unique name for this application in the configuration",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "example": "ChakraApp"
          },
          {
            "name": "version",
            "in": "query",
            "required": false,
            "description": "Optional model version. If omitted, uses latest stable version.",
            "schema": {
              "type": "string"
            },
            "example": "4.0.1"
          }
        ],
        "responses": {
          "201": {
            "description": "Application added",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApplicationDefinition"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (distribution sum exceeds 1.0)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity. Code MAPPING_PARAMS_LOCKED when a mapping file is attached and the new Chakra application does not carry UseMapping true and MappingFileName chakra-mapping.txt. Detach the mapping file first, add the application, then attach the mapping file again, which writes both parameters into every Chakra application.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/links": {
      "get": {
        "summary": "List configuration links",
        "description": "Returns all links (layer components) from the configuration",
        "tags": [
          "configurations"
        ],
        "operationId": "list_configuration_links",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "withDetails",
            "in": "query",
            "description": "When true, includes full typedParameters for each link. Defaults to false.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of links",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigurationLinksListResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/topology": {
      "patch": {
        "summary": "Add component to topology",
        "description": "Adds a component reference to the configuration's topology.components array. Validates the named entity exists in the correct collection by type (switch→components, layer→links, pod→containers).",
        "tags": [
          "configurations"
        ],
        "operationId": "add_component_to_topology",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddTopologyComponentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Component added to topology",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TopologyDefinition"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (type not allowed, duplicate, invalid type)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or referenced entity not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/topology/{component_name}": {
      "patch": {
        "summary": "Update topology component",
        "description": "Updates the count on an existing component reference in the topology.",
        "tags": [
          "configurations"
        ],
        "operationId": "update_topology_component",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "component_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTopologyComponentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Topology component updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TopologyDefinition"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (count < 1)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or component not found in topology",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "delete": {
        "summary": "Remove component from topology",
        "description": "Removes a component reference from the configuration's topology.",
        "tags": [
          "configurations"
        ],
        "operationId": "remove_topology_component",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "component_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "responses": {
          "204": {
            "description": "Component removed from topology"
          },
          "404": {
            "description": "Configuration or component not found in topology",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/distribution": {
      "patch": {
        "summary": "Update distribution entry value",
        "description": "Updates the value field of a specific entry in topology.appDistribution.randomApplicationDistribution[]. The entry is identified by parentApplication + distributionId.",
        "tags": [
          "configurations"
        ],
        "operationId": "update_distribution_value",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDistributionValueRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Distribution value updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppDistribution"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (value out of range, empty fields, no app_distribution)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or distribution entry not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Concurrent modification conflict, please retry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/applications/{app_name}": {
      "delete": {
        "summary": "Remove application from configuration",
        "description": "Removes an application from the configuration's topology. Remaining applications are auto-scaled to maintain distribution sum of 1.0.",
        "tags": [
          "configurations"
        ],
        "operationId": "remove_configuration_application",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "app_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Application removed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletionResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or application not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/parameters": {
      "patch": {
        "summary": "Update global parameters",
        "description": "Performs a validated merge of the provided TypedParameters patch into the configuration's global_parameters. Backend-managed sections (ComputeConfiguration, ParallelizationParameters, etc.), readonly sections (SoftwareVersion), and hidden parameters are rejected with 400.",
        "tags": [
          "configurations"
        ],
        "operationId": "update_global_parameters",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TypedParameters"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parameters updated successfully. Returns the full updated global TypedParameters (with backend params stripped).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TypedParameters"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (empty patch, unknown parameter key, type mismatch, structural mismatch, attempt to modify backend-managed/readonly/hidden params)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict (serialization failure from concurrent modification)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/components/{component_name}/parameters": {
      "patch": {
        "summary": "Update component parameters",
        "description": "Performs a validated merge of the provided TypedParameters patch into the named component's typed_parameters. Only existing parameter keys can be updated, and types must match.",
        "tags": [
          "configurations"
        ],
        "operationId": "update_component_parameters",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "component_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TypedParameters"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parameters updated successfully. Returns the full updated TypedParameters for the component.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TypedParameters"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (empty patch, unknown parameter key, type mismatch, structural mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or component not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict (serialization failure from concurrent modification)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/applications/{app_name}/parameters": {
      "patch": {
        "summary": "Update application parameters",
        "description": "Performs a validated merge of the provided TypedParameters patch into the named application's typed_parameters. Only existing parameter keys can be updated, and types must match.",
        "tags": [
          "configurations"
        ],
        "operationId": "update_application_parameters",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "app_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TypedParameters"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parameters updated successfully. Returns the full updated TypedParameters for the application.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TypedParameters"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (empty patch, unknown parameter key, type mismatch, structural mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or application not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict (serialization failure from concurrent modification)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity. Code MAPPING_PARAMS_LOCKED when a mapping file is attached and the patch would leave a Chakra application without UseMapping true and MappingFileName chakra-mapping.txt. Detach the mapping file first, make the change, then attach it again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/links/{link_name}/parameters": {
      "patch": {
        "summary": "Update link parameters",
        "description": "Performs a validated merge of the provided TypedParameters patch into the named link's typed_parameters. Only existing parameter keys can be updated, and types must match.",
        "tags": [
          "configurations"
        ],
        "operationId": "update_link_parameters",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "link_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TypedParameters"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parameters updated successfully. Returns the full updated TypedParameters for the link.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TypedParameters"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (empty patch, unknown parameter key, type mismatch, structural mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or link not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict (serialization failure from concurrent modification)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/configurations/{component_name}": {
      "patch": {
        "summary": "Add child to component",
        "description": "Adds a child component (NIC, GPU, or application) to the specified host (server) component. Validates that the child type is in the host's allowedComponents list.",
        "tags": [
          "configurations"
        ],
        "operationId": "add_child_to_component",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "component_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddComponentChildRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Child component added to host",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComponentDeclaration"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (child type not allowed, already attached)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or component not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/configurations/{component_name}/components/{child_name}": {
      "delete": {
        "summary": "Remove child from component",
        "description": "Removes a child component (NIC, GPU, or application) from the specified host (server) component.",
        "tags": [
          "configurations"
        ],
        "operationId": "remove_child_from_component",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "component_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "child_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "responses": {
          "204": {
            "description": "Child component removed from host"
          },
          "404": {
            "description": "Configuration, component, or child not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "patch": {
        "summary": "Update child in component",
        "description": "Updates count and/or group on an existing child component reference within the specified host (server) component. At least one of count or group must be provided.",
        "tags": [
          "configurations"
        ],
        "operationId": "update_child_in_component",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "component_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "child_name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ETag for optimistic concurrency control"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateChildComponentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Child component updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComponentDeclaration"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (empty patch, count < 1)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration, component, or child not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "412": {
            "description": "Precondition failed (ETag mismatch)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/configurations/{config_id}/software-version": {
      "get": {
        "summary": "Get software version",
        "description": "Returns the simulator software version from the SoftwareVersion section of globalParameters.",
        "tags": [
          "configurations"
        ],
        "operationId": "get_software_version",
        "parameters": [
          {
            "name": "config_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Software version retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SoftwareVersionResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/simulations": {
      "get": {
        "summary": "List simulations",
        "description": "Retrieves a paginated list of simulations with optional filtering by workspace, status, name search, and creation date. Results are sorted by creation date (newest first) by default.",
        "tags": [
          "simulations"
        ],
        "operationId": "list_simulations",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of items to return (default: 100, max: 100)",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token from previous response's `nextCursor` for pagination",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "description": "Filter by workspace ID (format: `workspace_xxx`)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by simulation status. Supports comma-separated values for OR logic (e.g., `running,completed,failed`). Valid values: `validating`, `provisioning`, `running`, `completed`, `failed`, `terminated`, `invalid`. Invalid values are silently ignored for forward compatibility.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Full-text search on simulation name (case-insensitive, max 100 characters)",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "createdAfter",
            "in": "query",
            "description": "Filter by creation date - items created on or after this time (ISO 8601, inclusive)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "description": "Filter by creation date - items created before this time (ISO 8601, exclusive)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sort order: a single `field:direction` pair (e.g., `created_at:desc`). Sortable fields: `name`, `created_at`, `status`. Default: `created_at:desc`. Compound (multi-field) sorts are not supported and return 400, because a cursor cannot express them.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of simulations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimulationsListResponse"
                },
                "example": {
                  "simulations": [
                    {
                      "id": "sim_abc123xyz",
                      "workspaceId": "workspace_def456",
                      "configurationId": "config_ghi789",
                      "configurationVersion": 1,
                      "name": "my-network-simulation",
                      "status": "running",
                      "createdAt": "2024-01-15T10:30:00Z"
                    }
                  ],
                  "pagination": {
                    "count": 1,
                    "hasMore": true,
                    "nextCursor": "eyJjcmVhdGVkIjoiMjAyNC0wMS0xNVQxMDozMDowMFoifQ=="
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - Invalid query parameters (e.g., malformed cursor, invalid workspaceId format, search query too long, a compound sort, or a cursor minted under a different sort)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid workspaceId format: expected 'workspace_' prefix"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "post": {
        "summary": "Start simulation",
        "description": "Creates and starts a new simulation based on the specified configuration. The simulation begins in `validating` status, or in `provisioning` for simulations that skip that status, then progresses to `running`. Poll the GET endpoint to monitor progress. `checkpointing` is accepted but not yet supported.",
        "tags": [
          "simulations"
        ],
        "operationId": "start_simulation",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimulationRequest"
              },
              "example": {
                "configurationId": "config_def456",
                "configurationVersion": 1,
                "name": "production-network-test",
                "duration": "1h"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Simulation started successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimulationDetails"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request; no simulation is created. Code VALIDATION_ERROR when the simulation parameters are invalid. Code LAUNCH_CONFIG_INVALID when the configuration could not be prepared for the simulator: the message says why, and resubmitting it unchanged fails again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required - the platform's credit balance is exhausted. Add credits before launching simulations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or workspace not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict; no simulation is created. Code CONFLICT when a simulation with this name already exists in the workspace: choose another name. Code MAPPING_FILE_DELETED_REFERENCE when the Chakra mapping file attached to the configuration has been deleted: the message names the file. Detach it, or attach another mapping file, and create the simulation again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "No simulation is created. Code UNPROCESSABLE_ENTITY when the configuration is not validated: it must have status `validated` before starting a simulation. Code LAUNCH_REJECTED when the simulator rejected the configuration: resubmitting it unchanged fails again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable - the simulation service could not start the simulation. No simulation is created, so the request can be retried.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/simulations/compare": {
      "post": {
        "summary": "Compare simulations",
        "description": "Compares two to four simulations and returns aligned summaries, per-metric deltas and a diff context. The result is returned inline as JSON rather than as a presigned download envelope.",
        "tags": [
          "simulations"
        ],
        "operationId": "compareSimulations",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompareSimulationsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Comparison result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComparisonResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body (simulationIds count outside 2..4, malformed simulation id, or unknown tier)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Simulation not found, or its workspace has been deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/simulations/{sim_id}": {
      "get": {
        "summary": "Get simulation status",
        "description": "Retrieves detailed information about a specific simulation, including its current status, timing information, and metrics (if available).",
        "tags": [
          "simulations"
        ],
        "operationId": "get_simulation",
        "parameters": [
          {
            "name": "sim_id",
            "in": "path",
            "required": true,
            "description": "Simulation ID in `sim_xxx` format (base32-encoded UUID with prefix)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Simulation details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimulationDetails"
                }
              }
            }
          },
          "404": {
            "description": "Simulation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "delete": {
        "summary": "Delete simulation and free storage",
        "description": "[Feature-gated: enable_simulation_delete] Permanently deletes a simulation and all associated data including results, logs, and checkpoints. This action cannot be undone. Running simulations must be terminated before deletion. This endpoint is only available on deployments where the enable_simulation_delete feature flag is enabled; callers may receive 404 on deployments where the flag is off.",
        "tags": [
          "simulations"
        ],
        "operationId": "delete_simulation",
        "parameters": [
          {
            "name": "sim_id",
            "in": "path",
            "required": true,
            "description": "Simulation ID in `sim_xxx` format",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Simulation scheduled for deletion",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimulationDeleteResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid simulation ID format",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Simulation or workspace not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/simulations/{sim_id}/terminate": {
      "post": {
        "summary": "Terminate simulation",
        "description": "Initiates termination of a simulation. There is no status pre-check: a simulation that has already finished is accepted and keeps its status; otherwise it transitions to `terminated`. Results generated up to the termination point will be available.",
        "tags": [
          "simulations"
        ],
        "operationId": "terminate_simulation",
        "parameters": [
          {
            "name": "sim_id",
            "in": "path",
            "required": true,
            "description": "Simulation ID in `sim_xxx` format",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Simulation termination initiated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimulationDetails"
                }
              }
            }
          },
          "202": {
            "description": "Termination dispatched for a simulation whose workspace has been deleted. Returned without a body: workspace deletion revokes the simulation's details, so the acknowledgement carries no SimulationDetails payload. Also returned when the backend refuses the request with a 4xx, whose message would describe the revoked simulation; a backend 5xx is reported as itself."
          },
          "400": {
            "description": "Bad Request - Invalid simulation ID format, or a scala-go simulation has no platform link and cannot be terminated. An orchestrator-backed simulation carries no link and is terminated through the gateway, so it never reaches this refusal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Simulation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error - A fault a retry cannot clear: the gateway or scala-go refused central's own request or credentials, or answered in a form central could not read",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable - The termination transport is unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/simulations/{sim_id}/results": {
      "get": {
        "summary": "Get simulation results",
        "description": "Retrieves results for a completed simulation including the run's duration and downloadable result files (pcap, traces, etc.).",
        "tags": [
          "simulations"
        ],
        "operationId": "get_simulation_results",
        "parameters": [
          {
            "name": "sim_id",
            "in": "path",
            "required": true,
            "description": "Simulation ID in `sim_xxx` format",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token from previous response's `nextCursor` for pagination",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of items to return (default: 100, min: 1, max: 100)",
            "schema": {
              "type": "integer",
              "default": 100,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Filter by result file type (pcap, csv, json, log, state, unknown)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "metrics",
            "in": "query",
            "description": "Filter by metrics query parameter",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Field to sort the result files by (default: createdAt)",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "size"
              ],
              "default": "createdAt"
            }
          },
          {
            "name": "order",
            "in": "query",
            "description": "Sort direction (default: desc)",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Simulation results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimulationResults"
                }
              }
            }
          },
          "400": {
            "description": "Invalid simulation ID format, invalid pagination cursor, limit out of range, or an unrecognized sort or order value",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Simulation not found or results not yet available",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable - The simulation's state could not be read from its backend: the backend's database is not configured, or it gave the read no connection within the read's time budget. The first persists until the backend is configured; the second usually clears on its own. The response body does not distinguish them, so a client should retry with backoff under a bounded attempt count rather than indefinitely.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "504": {
            "description": "Gateway Timeout - Reading the simulation's state from its backend's database exceeded the read's time budget. The request may be retried.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/simulations/{sim_id}/results/download-url": {
      "get": {
        "summary": "Generate presigned download URL for result file",
        "tags": [
          "simulations"
        ],
        "operationId": "get_simulation_result_download_url",
        "parameters": [
          {
            "name": "sim_id",
            "in": "path",
            "required": true,
            "description": "Simulation ID in sim_xxx format (base32-encoded UUID with prefix)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fileName",
            "in": "query",
            "required": true,
            "description": "Path of the result file to download, relative to the simulation's results prefix. Nested files use their subdirectory path (e.g. \"subdir/file.csv\").",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "metrics",
            "in": "query",
            "description": "Reserved for future use. Filter by metrics type (e.g., nd-stats, perf-stats, pfc-stats, post-annotated, logs)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Reserved for future use. File type filter (e.g., zstd)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File download URL generated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileDownloadUrlResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid simulation ID format or missing fileName",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Simulation or file not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable - The simulation's state could not be read from its backend: the backend's database is not configured, or it gave the read no connection within the read's time budget. The first persists until the backend is configured; the second usually clears on its own. The response body does not distinguish them, so a client should retry with backoff under a bounded attempt count rather than indefinitely.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "504": {
            "description": "Gateway Timeout - Reading the simulation's state from its backend's database exceeded the read's time budget. The request may be retried.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/simulations/{sim_id}/results/data": {
      "get": {
        "summary": "Get computed summary data for simulation results",
        "description": "Computes or retrieves cached summary statistics for simulation result CSV files using Polars. Returns a presigned URL to download the zstd-compressed JSON summary. For a run whose status is `completed`, `failed` or `terminated` and whose `completedAt` is at least 60 minutes old, and that has no rows for the requested metric (no data file for it, or only a header-only one), the response is 200 with a summary whose `totalRowsProcessed` is 0 and whose projection fields are absent. The one exception is a `completed` run whose only data for the PFC metric is a header-only shard: its `pfc` projection is present with five zero totals (`totalXoffRx`, `totalXoffTx`, `totalXonRx`, `totalXonTx`, `totalTimePausedUsec`) and `byTier` omitted. A run that is not yet settled, or whose status is `invalid`, keeps 404.",
        "tags": [
          "simulations"
        ],
        "operationId": "get_simulation_summary_data",
        "parameters": [
          {
            "name": "sim_id",
            "in": "path",
            "required": true,
            "description": "Simulation ID in sim_xxx format (base32-encoded UUID with prefix)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "metric",
            "in": "query",
            "required": true,
            "description": "Metric type to summarize. `rank-analysis` is published but returns 501 Not Implemented until its compute path ships. `uet-transport-stats` and `roce-transport-stats` serve `summary`, which carries the whole-run `transport` projection, and `timeSeries`. Both return 501 for `sampled` until that compute path ships. `scala-switch-agg-buff-stats` serves `summary`, which carries the whole-run `bufferPools` projection unless the run settled with no buffer rows, and `timeSeries`, one group per buffer pool. It returns 501 for `sampled` until that compute path ships.",
            "schema": {
              "type": "string",
              "enum": [
                "nd-stats",
                "perf",
                "pfc",
                "ranks",
                "chakra-perf",
                "collectives",
                "cdf",
                "rank-analysis",
                "uet-transport-stats",
                "roce-transport-stats",
                "scala-switch-agg-buff-stats"
              ]
            }
          },
          {
            "name": "mode",
            "in": "query",
            "description": "Output mode (default: summary). `timeSeries` is served for `nd-stats`, `pfc`, `uet-transport-stats`, `roce-transport-stats` and `scala-switch-agg-buff-stats` and returns 501 Not Implemented for the other metrics; `sampled` is published but returns 501 Not Implemented until its compute path ships. `utilizationBins` (a binned distribution of link utilization over time) is offered for `nd-stats` only: every other metric returns 400 with error code `UNSUPPORTED_COMBINATION`, a permanent answer that must not be retried, and for `nd-stats` the response's `file` presigns a `UtilizationBinsDocument`. `uplinkFairness` (uplink port fairness per switch over time) is offered for `nd-stats` only in the same way: every other metric returns 400 with error code `UNSUPPORTED_COMBINATION`, and for `nd-stats` the response's `file` presigns an `UplinkFairnessDocument`. `completionTimeBins` (a binned distribution of completion times over time) is offered on the Performance projection: `perf` returns the envelope whose presigned URL serves a `CompletionTimeBinsDocument`; `chakra-perf` returns 404 Not Found, as a run with no result shards does, because this shape does not bin its completions; and every other metric returns 400 with error code `UNSUPPORTED_COMBINATION`, a permanent answer that must not be retried.",
            "schema": {
              "type": "string",
              "enum": [
                "summary",
                "timeSeries",
                "sampled",
                "utilizationBins",
                "uplinkFairness",
                "completionTimeBins"
              ],
              "default": "summary"
            }
          },
          {
            "name": "tier",
            "in": "query",
            "description": "Tier filter for network device results (default: all)",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "ssw",
                "fsw",
                "rsw",
                "nic"
              ],
              "default": "all"
            }
          },
          {
            "name": "nodeId",
            "in": "query",
            "description": "Filter to these node ids. Comma-separated on the wire. An empty list is not accepted — omit the parameter instead.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "minItems": 1,
              "maxItems": 100,
              "items": {
                "type": "integer",
                "format": "int64",
                "minimum": 0
              }
            }
          },
          {
            "name": "ifid",
            "in": "query",
            "description": "Filter to these interface ids. Comma-separated on the wire. An empty list is not accepted — omit the parameter instead.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "minItems": 1,
              "maxItems": 100,
              "items": {
                "type": "integer",
                "format": "int64",
                "minimum": 0
              }
            }
          },
          {
            "name": "nicType",
            "in": "query",
            "description": "Filter to a NIC class.",
            "schema": {
              "$ref": "#/components/schemas/NicType"
            }
          },
          {
            "name": "metricName",
            "in": "query",
            "description": "Filter to these metric names. Comma-separated on the wire; values may not contain commas. An empty list is not accepted — omit the parameter instead.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "minItems": 1,
              "maxItems": 20,
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 256
              }
            }
          },
          {
            "name": "application",
            "in": "query",
            "description": "Filter to these application names. Comma-separated on the wire; values may not contain commas. An empty list is not accepted — omit the parameter instead.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "minItems": 1,
              "maxItems": 20,
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 256
              }
            }
          },
          {
            "name": "priority",
            "in": "query",
            "description": "Filter to these PFC priorities. Comma-separated on the wire. An empty list is not accepted — omit the parameter instead.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "minItems": 1,
              "maxItems": 8,
              "items": {
                "type": "integer",
                "format": "int32",
                "minimum": 0,
                "maximum": 7
              }
            }
          },
          {
            "name": "uldl",
            "in": "query",
            "description": "Filter to uplink or downlink direction.",
            "schema": {
              "type": "string",
              "enum": [
                "ul",
                "dl"
              ]
            }
          },
          {
            "name": "preset",
            "in": "query",
            "description": "Rank-analysis grouping preset (only consumed when metric=rank-analysis). Omit to get the server default, `balanced`. Carries no schema `default`: a schema default makes generated clients send the value on every request, which lists it in X-Ignored-Params on every mode and metric that does not consume it.",
            "schema": {
              "type": "string",
              "enum": [
                "balanced",
                "straggler",
                "network",
                "computeNetwork"
              ]
            }
          },
          {
            "name": "tolerance",
            "in": "query",
            "description": "Dimensionless multiplier on the per-dimension tolerance bands (only consumed when metric=rank-analysis). Omit to get the server default, 0.0. Carries no schema `default`: a schema default makes generated clients send the value on every request, which lists it in X-Ignored-Params on every mode and metric that does not consume it.",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": 0.0,
              "maximum": 5.0
            }
          },
          {
            "name": "outlierThreshold",
            "in": "query",
            "description": "Outlier deviation-score fraction (only consumed when metric=rank-analysis). Omit to get the server default, 0.10. Carries no schema `default`: a schema default makes generated clients send the value on every request, which lists it in X-Ignored-Params on every mode and metric that does not consume it.",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": 0.01,
              "maximum": 1.0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Summary data with presigned download URL. For a run whose status is `completed`, `failed` or `terminated` and whose `completedAt` is at least 60 minutes old, and that has no rows for the requested metric (no data file for it, or only a header-only one), this is a summary whose `totalRowsProcessed` is 0 and whose projection fields are absent. The one exception is a `completed` run whose only data for the PFC metric is a header-only shard: its `pfc` projection is present with five zero totals (`totalXoffRx`, `totalXoffTx`, `totalXonRx`, `totalXonTx`, `totalTimePausedUsec`) and `byTier` omitted. A run that is not yet settled, or whose status is `invalid`, keeps 404.",
            "headers": {
              "X-Ignored-Params": {
                "description": "Comma-separated, alphabetically ordered list of request params that do not apply to this (mode, metric) pair and were ignored. Absent — never empty — when nothing was ignored.",
                "required": false,
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SummaryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters (bad metric, mode, or tier value), with error code `VALIDATION_ERROR`; or, with error code `UNSUPPORTED_COMBINATION`, a result shape the requested projection does not offer (`mode=utilizationBins` or `mode=uplinkFairness` on any metric but `nd-stats`, or `mode=completionTimeBins` on any metric but `perf` and `chakra-perf`). `UNSUPPORTED_COMBINATION` is permanent for the request and must not be retried; its message names the result shape and the projection, and only it carries `X-Ignored-Params`.",
            "headers": {
              "X-Ignored-Params": {
                "description": "Comma-separated, alphabetically ordered list of request params that do not apply to this (mode, metric) pair and were ignored. Sent only with error code `UNSUPPORTED_COMBINATION`. Absent — never empty — when nothing was ignored.",
                "required": false,
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Simulation not found or no data files available for the specified metric for a simulation that is not yet settled, or is invalid. For `mode=utilizationBins` and `mode=uplinkFairness`, no data files answers 404 whether or not the simulation is settled. For `mode=completionTimeBins`, also a run with no perf result shards, settled or not, and every `metric=chakra-perf` request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Payload Too Large - The summarized result set exceeds one of the server's size limits: its row count is over the ceiling, summarizing it would exceed the memory budget, or, for `mode=utilizationBins` or `mode=uplinkFairness`, it spans more distinct sample times or more data files than that mode accepts, or, for `mode=uplinkFairness`, its switch uplinks hold more samples than the fold accepts, or, for `mode=completionTimeBins`, it lists more data files than that mode accepts. This condition is permanent for the request and must not be retried.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "501": {
            "description": "The requested mode or metric is recognized but its compute path has not shipped yet",
            "headers": {
              "X-Ignored-Params": {
                "description": "Comma-separated, alphabetically ordered list of request params that do not apply to this (mode, metric) pair and were ignored. Absent — never empty — when nothing was ignored.",
                "required": false,
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable - Several conditions render this status and they differ in whether a retry resolves them; the ones named here are the known ones rather than a closed set. The common one is a transient fault against the results object store on any mode - a network error, throttling, or a 5xx from the dependency - which is retriable: a client that backs off and retries will usually succeed. A second retriable one is a lost cache-write race the server could not recover from: a concurrent request stored the summary object first, and when this request went back to read it the object was no longer there, so a later attempt normally succeeds against the object the next writer stores. The last is a required backend dependency that is not available or not configured, so the simulation's artifact location could not be resolved. Retrying does not help if the dependency is unconfigured. The response body does not distinguish them, so a client should retry with backoff under a bounded attempt count rather than indefinitely.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "504": {
            "description": "Gateway Timeout - Summary computation, or reading the simulation's state from its backend's database, exceeded the server's time budget. The request may be retried.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/simulations/{sim_id}/logs": {
      "get": {
        "summary": "Get simulation logs",
        "description": "Retrieves paginated logs from a simulation with optional filtering by log level and component. Logs are returned in chronological order.",
        "tags": [
          "simulations"
        ],
        "operationId": "get_simulation_logs",
        "parameters": [
          {
            "name": "sim_id",
            "in": "path",
            "required": true,
            "description": "Simulation ID in `sim_xxx` format",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "level",
            "in": "query",
            "description": "Filter logs by minimum severity level",
            "schema": {
              "type": "string",
              "enum": [
                "debug",
                "info",
                "warning",
                "error"
              ]
            }
          },
          {
            "name": "component",
            "in": "query",
            "description": "Filter logs by component name (e.g., `simulator`, `flownizer`, `annotator`)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "since",
            "in": "query",
            "description": "Filter logs to entries at or after this time (ISO 8601 / RFC 3339)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of log entries to return (default: 100, max: 1000). A page may return up to two entries more than `limit`: the in-band truncation notice and the in-progress-log notice do not count against it.",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 1000
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token from previous response's `nextCursor` for pagination",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Simulation logs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogsListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - Invalid simulation ID format, invalid `since` timestamp, invalid `level` or `component`, or invalid pagination cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Simulation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable - The simulation's state could not be read from its backend: the backend's database is not configured, or it gave the read no connection within the read's time budget. The first persists until the backend is configured; the second usually clears on its own. The response body does not distinguish them, so a client should retry with backoff under a bounded attempt count rather than indefinitely.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "504": {
            "description": "Gateway Timeout - Reading the simulation's state from its backend's database exceeded the read's time budget. The request may be retried.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/workspaces": {
      "get": {
        "summary": "List workspaces",
        "tags": [
          "workspaces"
        ],
        "operationId": "list_workspaces",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "maximum": 100
            }
          },
          {
            "name": "next",
            "in": "query",
            "description": "Opaque cursor token to fetch results after a specific item",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "owner",
            "in": "query",
            "description": "Filter by owner user ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Full-text search across name and description fields (case-insensitive)",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            }
          },
          {
            "name": "createdAfter",
            "in": "query",
            "description": "Filter to items created on or after this timestamp (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "description": "Filter to items created before this timestamp (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "modifiedAfter",
            "in": "query",
            "description": "Filter to items modified on or after this timestamp (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "modifiedBefore",
            "in": "query",
            "description": "Filter to items modified before this timestamp (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of workspaces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspacesListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/workspaces/{workspace_id}": {
      "get": {
        "summary": "Get workspace details",
        "tags": [
          "workspaces"
        ],
        "operationId": "get_workspace",
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workspace details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Workspace not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/tracesets": {
      "get": {
        "summary": "List tracesets",
        "description": "List all tracesets. Supports pagination, filtering by workspace/status, full-text name search, and date range filtering. Results are sorted by creation date (newest first) by default.",
        "tags": [
          "tracesets"
        ],
        "operationId": "list_tracesets",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "description": "Filter by workspace ID (format: `workspace_xxx`). If not provided, returns all tracesets accessible to the authenticated user.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by traceset status. Valid values: `uploading`, `processing`, `ready`, `metadata_failed`, `upload_failed`, `deleted`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Full-text search on traceset name (case-insensitive)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort order: comma-separated list of `field:direction` pairs (e.g., `created:desc,name:asc`). Default: `created:desc`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "next",
            "in": "query",
            "required": false,
            "description": "Opaque cursor token from previous response's nextCursor field",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "createdAfter",
            "in": "query",
            "required": false,
            "description": "Filter by creation date — items created on or after this time (ISO 8601, inclusive)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "createdBefore",
            "in": "query",
            "required": false,
            "description": "Filter by creation date — items created before this time (ISO 8601, exclusive)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of tracesets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TracesetListResponse"
                },
                "example": {
                  "items": [
                    {
                      "id": "ts_abc123xyz",
                      "name": "GPT-175B Training Traces",
                      "status": "ready",
                      "fileCount": 4,
                      "createdAt": "2026-02-20T14:30:00Z"
                    }
                  ],
                  "pagination": {
                    "count": 1,
                    "hasMore": true,
                    "nextCursor": "eyJjcmVhdGVkIjoiMjAyNi0wMi0yMFQxNDozMDowMFoifQ=="
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — Invalid query parameters (bad cursor, invalid sort field)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Invalid sort field: 'unknown'. Valid fields: created, name, status"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/tracesets/{id}": {
      "get": {
        "summary": "Get traceset",
        "description": "Returns a traceset by ID including all file metadata, tags, and expiration information.",
        "tags": [
          "tracesets"
        ],
        "operationId": "get_traceset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Traceset ID (format: `ts_xxx`)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Traceset details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TracesetResponse"
                },
                "example": {
                  "id": "ts_abc123xyz",
                  "name": "GPT-175B Training Traces",
                  "description": "Chakra traces for GPT-175B on 256 ranks",
                  "status": "ready",
                  "files": [
                    {
                      "name": "rank_0.chakra.json",
                      "size": 1048576,
                      "role": "primary",
                      "metadataStatus": "complete"
                    }
                  ],
                  "totalSize": 4194304,
                  "tags": [
                    "gpt",
                    "training"
                  ],
                  "workspaceId": "workspace_def456",
                  "createdAt": "2026-02-20T14:30:00Z"
                }
              }
            }
          },
          "404": {
            "description": "Traceset not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Traceset 'ts_notfound' not found"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "delete": {
        "summary": "Delete traceset",
        "description": "Soft-deletes a traceset. Associated library files are reference-counted and cleaned up asynchronously. Excluded when trace_routes_read_only is enabled.",
        "tags": [
          "tracesets"
        ],
        "operationId": "delete_traceset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Traceset ID (format: `ts_xxx`)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Traceset deleted"
          },
          "404": {
            "description": "Traceset not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Traceset 'ts_notfound' not found"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/tracesets/{id}/download": {
      "get": {
        "summary": "Get traceset download URL",
        "description": "Returns a presigned S3 download URL for a specific file within a traceset, or for the entire traceset archive if no file is specified. The URL expires after a short TTL.",
        "tags": [
          "tracesets"
        ],
        "operationId": "get_download_url",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Traceset ID (format: `ts_xxx`)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "file",
            "in": "query",
            "required": false,
            "description": "Specific file name within the traceset. If omitted, returns a URL for the entire traceset archive.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Presigned download URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TracesetDownloadUrlResponse"
                },
                "example": {
                  "url": "https://scala-traces.s3.amazonaws.com/ts_abc123xyz/rank_0.chakra.json?X-Amz-Algorithm=...",
                  "expiresAt": "2026-02-23T20:30:00Z",
                  "file": "rank_0.chakra.json"
                }
              }
            }
          },
          "400": {
            "description": "File uses an external URL that cannot be downloaded via presigned URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "File 'external.dat' uses an external URL and cannot be downloaded via presigned URL"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Traceset not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Traceset 'ts_notfound' not found"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/tracesets/{id}/validate": {
      "post": {
        "summary": "Validate traceset",
        "description": "Runs validation checks on a traceset including file integrity and metadata completeness. Optionally accepts a topologyId for compatibility validation, but the topology_correlation check currently always returns passed (not yet implemented).",
        "tags": [
          "tracesets"
        ],
        "operationId": "validate_traceset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Traceset ID (format: `ts_xxx`)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TracesetValidateRequest"
              },
              "example": {
                "topologyId": "config_ghi789"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TracesetValidationResponse"
                },
                "example": {
                  "valid": true,
                  "checks": [
                    {
                      "name": "file_integrity",
                      "passed": true
                    },
                    {
                      "name": "metadata_complete",
                      "passed": true
                    },
                    {
                      "name": "topology_correlation",
                      "passed": true,
                      "message": "Not yet implemented — always passes"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Traceset not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Traceset 'ts_notfound' not found"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/tracesets/upload-url": {
      "post": {
        "summary": "Initiate multipart traceset upload",
        "description": "Creates a traceset record and returns presigned S3 multipart upload URLs for each file. Each file is split into parts based on size. PUT each part with its `size` bytes before `partUrlsExpireAt` (one hour by default); `expiresAt` is the 24-hour session lifetime, not the URLs'. After uploading all parts to their presigned URLs, call POST /api/v1/tracesets/upload-url/complete to finalize the upload. An upload with `primary` files must declare its rank count in `workloadMetadata`, as `shape.rankCount` or as parallelism degrees (`dp`, `tp`, `sp`, `ep`, `pp`, multiplied together); the declaration is checked before any upload URL is issued, and the traceset reports it as `rankCountDerived`. An upload of supporting files only needs no declaration.",
        "tags": [
          "tracesets"
        ],
        "operationId": "get_upload_urls",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TracesetUploadUrlRequest"
              },
              "example": {
                "workspaceId": "workspace_def456",
                "name": "GPT-175B Training Traces",
                "description": "Chakra traces for GPT-175B on 2 ranks",
                "tags": [
                  "gpt",
                  "training"
                ],
                "workloadMetadata": {
                  "shape": {
                    "rankCount": 2
                  }
                },
                "files": [
                  {
                    "name": "rank_0.chakra.json",
                    "size": 1048576,
                    "role": "primary"
                  },
                  {
                    "name": "rank_1.chakra.json",
                    "size": 1048576,
                    "role": "primary"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Presigned upload URLs for each file part",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TracesetUploadUrlResponse"
                },
                "example": {
                  "uploadId": "upload_ghi789",
                  "checksumAlgorithm": "SHA256",
                  "files": [
                    {
                      "name": "rank_0.chakra.json",
                      "parts": [
                        {
                          "partNumber": 1,
                          "size": 1048576,
                          "url": "https://scala-traces.s3.amazonaws.com/...?X-Amz-Algorithm=..."
                        }
                      ],
                      "partUrlsExpireAt": "2026-02-23T15:30:00Z"
                    }
                  ],
                  "expiresAt": "2026-02-24T14:30:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request: empty files list or missing required fields; `primary` files without a declared rank count; a `shape.rankCount` or parallelism degree that is not a whole number of at least 1; a `shape.rankCount` that differs from the parallelism product; a declared rank count above 2,147,483,647; or a `workloadMetadata`, `shape` or `parallelism` that is neither an object nor null. The message names the field at fault.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Uploads with primary trace files must declare a rank count: set workloadMetadata.shape.rankCount, or workloadMetadata.parallelism degrees (dp, tp, sp, ep, pp)"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/tracesets/upload-url/complete": {
      "post": {
        "summary": "Complete multipart traceset upload",
        "description": "Finalizes a multipart upload session by providing the ETags returned by S3 for all uploaded parts. The traceset is `ready` when this returns, every file reports `metadataStatus` `complete`, and the platform does not process the trace files: the rank count is the one declared at upload. With exactly one `primary` file, that file reports `rankRange` 0 to N−1 for N declared ranks. Returns 201 on first completion or 200 on idempotent retry. The completion keeps running if this request times out (408) or disconnects: retry the same request, which answers 409 while the completion runs, then 200 once it has finished or 400 if it failed.",
        "tags": [
          "tracesets"
        ],
        "operationId": "complete_upload",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TracesetCompleteUploadRequest"
              },
              "example": {
                "uploadId": "upload_ghi789",
                "files": [
                  {
                    "name": "rank_0.chakra.json",
                    "parts": [
                      {
                        "partNumber": 1,
                        "etag": "\"d41d8cd98f00b204e9800998ecf8427e\""
                      }
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Upload completed and traceset created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TracesetCompleteUploadResponse"
                },
                "example": {
                  "id": "ts_abc123xyz",
                  "name": "GPT-175B Training Traces",
                  "status": "ready",
                  "files": [
                    {
                      "name": "rank_0.chakra.json",
                      "size": 1048576,
                      "role": "primary"
                    }
                  ],
                  "totalSize": 1048576
                }
              }
            }
          },
          "200": {
            "description": "Idempotent retry — upload was already completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TracesetCompleteUploadResponse"
                },
                "example": {
                  "id": "ts_abc123xyz",
                  "name": "GPT-175B Training Traces",
                  "status": "ready",
                  "files": [
                    {
                      "name": "rank_0.chakra.json",
                      "size": 1048576,
                      "role": "primary"
                    }
                  ],
                  "totalSize": 1048576
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (missing parts, bad ETags, or an upload session minted by POST /api/v1/mapping-files/upload-url, which only POST /api/v1/mapping-files/upload-url/complete accepts)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Missing parts for file 'rank_0.chakra.json'"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Upload session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Upload session 'upload_notfound' not found"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The upload session is being completed by another request, or by an earlier request that timed out; retry until it answers 200, or 400 if the completion failed (open a new upload session)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Upload session is already being completed by another request"
                  }
                }
              }
            }
          },
          "410": {
            "description": "Upload session expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "message": "Upload session 'upload_ghi789' has expired"
                  }
                }
              }
            }
          },
          "413": {
            "description": "An uploaded file is larger than the size declared for it at upload-url; its staged object is deleted and the upload session fails, so open a new upload session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PAYLOAD_TOO_LARGE",
                    "message": "File rank_0.chakra.json is 2097152 bytes, larger than its declared size of 1048576 bytes"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/mapping-files": {
      "get": {
        "summary": "List mapping files",
        "description": "Lists the Chakra mapping files in a workspace, newest first, with cursor pagination. Deleted files are omitted.",
        "tags": [
          "mapping-files"
        ],
        "operationId": "list_mapping_files",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to list (format: `workspace_xxx`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return; at least 1. A value above the server's page cap but within the unsigned 32-bit range is clamped to the cap; a value outside that range is refused as not parsing.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "next",
            "in": "query",
            "required": false,
            "description": "Opaque cursor token from the previous response's nextCursor field.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of mapping files",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MappingFileList"
                },
                "example": {
                  "items": [
                    {
                      "id": "mapfile_2cVQ8f0YyQ3nT1hKpR7mBz4LsXd",
                      "name": "gpt-175b-256n.txt",
                      "workspaceId": "workspace_def456",
                      "sizeBytes": 4096,
                      "rankCount": 256,
                      "scaleUpGroupCount": 2,
                      "hasScaleUp": true,
                      "createdAt": "2026-09-16T14:30:00Z"
                    }
                  ],
                  "pagination": {
                    "count": 1,
                    "hasMore": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request — workspaceId is absent or blank (there is no tenant-wide fallback), limit is zero or does not parse as a positive unsigned 32-bit integer, or the cursor is invalid or expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "workspaceId is required"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/mapping-files/{mapping_file_id}": {
      "get": {
        "summary": "Get mapping file",
        "description": "Returns a mapping file's metadata, including the stored CRC64NVME checksum of its bytes.",
        "tags": [
          "mapping-files"
        ],
        "operationId": "get_mapping_file",
        "parameters": [
          {
            "name": "mapping_file_id",
            "in": "path",
            "required": true,
            "description": "Mapping file ID (format: `mapfile_xxx`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Mapping file details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MappingFileDetails"
                },
                "example": {
                  "id": "mapfile_2cVQ8f0YyQ3nT1hKpR7mBz4LsXd",
                  "name": "gpt-175b-256n.txt",
                  "workspaceId": "workspace_def456",
                  "sizeBytes": 4096,
                  "rankCount": 256,
                  "scaleUpGroupCount": 2,
                  "hasScaleUp": true,
                  "createdAt": "2026-09-16T14:30:00Z",
                  "description": "Reverse placement for the 256-rank study",
                  "hash": "crc64nvme:vK3Jd8Qm1pA",
                  "etag": "\"0\"",
                  "duplicateOfExisting": false
                }
              }
            }
          },
          "404": {
            "description": "Mapping file not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "Mapping file 'mapfile_notfound' not found"
                  }
                }
              }
            }
          },
          "410": {
            "description": "Mapping file has been deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "MAPPING_FILE_DELETED",
                    "message": "Mapping file 'gpt-175b-256n.txt' has been deleted"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      },
      "delete": {
        "summary": "Delete mapping file",
        "description": "Soft-deletes a mapping file. The delete succeeds whether or not a configuration refers to the file; a configuration that refers to it then reports it as deleted, and creating a simulation from that configuration is refused until the file is detached or another is attached. Simulations already created are unaffected.",
        "tags": [
          "mapping-files"
        ],
        "operationId": "delete_mapping_file",
        "parameters": [
          {
            "name": "mapping_file_id",
            "in": "path",
            "required": true,
            "description": "Mapping file ID (format: `mapfile_xxx`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Mapping file deleted"
          },
          "404": {
            "description": "Mapping file not found, or already deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "Mapping file 'mapfile_notfound' not found"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/mapping-files/{mapping_file_id}/download": {
      "get": {
        "summary": "Get mapping file download URL",
        "description": "Returns a presigned URL for the mapping file's stored bytes. The served bytes are byte-for-byte the uploaded bytes.",
        "tags": [
          "mapping-files"
        ],
        "operationId": "download_mapping_file",
        "parameters": [
          {
            "name": "mapping_file_id",
            "in": "path",
            "required": true,
            "description": "Mapping file ID (format: `mapfile_xxx`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Presigned download URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MappingFileDownloadUrlResponse"
                },
                "example": {
                  "url": "https://scala-traces.s3.amazonaws.com/library/crc64nvme:vK3Jd8Qm1pA/gpt-175b-256n.txt?X-Amz-Algorithm=...",
                  "expiresAt": "2026-09-16T15:30:00Z"
                }
              }
            }
          },
          "404": {
            "description": "Mapping file not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "Mapping file 'mapfile_notfound' not found"
                  }
                }
              }
            }
          },
          "410": {
            "description": "Mapping file has been deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "MAPPING_FILE_DELETED",
                    "message": "Mapping file 'gpt-175b-256n.txt' has been deleted"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/mapping-files/upload-url": {
      "post": {
        "summary": "Initiate mapping-file upload",
        "description": "Creates an upload session and returns presigned S3 multipart upload URLs for one Chakra mapping file. PUT each part with its `size` bytes (or fewer, since `sizeBytes` is an upper bound) before `partUrlsExpireAt` (one hour by default); `expiresAt` is the 24-hour session lifetime, not the URLs'. After PUTting every part, call POST /api/v1/mapping-files/upload-url/complete to validate and store it. Nothing is stored until that call succeeds.",
        "tags": [
          "mapping-files"
        ],
        "operationId": "create_mapping_file_upload_url",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MappingFileUploadUrlRequest"
              },
              "example": {
                "workspaceId": "workspace_def456",
                "name": "gpt-175b-256n.txt",
                "sizeBytes": 4096,
                "description": "Reverse placement for the 256-rank study"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Presigned upload URLs for each part",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MappingFileUploadUrlResponse"
                },
                "example": {
                  "uploadId": "upload_2cVQ8f0YyQ3nT1hKpR7mBz4LsXd",
                  "checksumAlgorithm": "crc64nvme",
                  "parts": [
                    {
                      "partNumber": 1,
                      "size": 4096,
                      "url": "https://scala-traces.s3.amazonaws.com/uploads/upload_2cVQ8f0YyQ3nT1hKpR7mBz4LsXd/gpt-175b-256n.txt?partNumber=1&X-Amz-Algorithm=..."
                    }
                  ],
                  "partUrlsExpireAt": "2026-09-16T15:30:00Z",
                  "expiresAt": "2026-09-17T14:30:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — name is not a single safe path segment or contains `..`, sizeBytes is outside 1..64000000, workspaceId is absent, blank, or padded with whitespace, or description exceeds 2048 characters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "sizeBytes must be between 1 and 64000000 bytes (the 64 MB per-file limit); got 64000001"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/mapping-files/upload-url/complete": {
      "post": {
        "summary": "Complete mapping-file upload",
        "description": "Finalises the multipart upload, validates the file against the simulator's grammar, stores it once under its content checksum, and creates the mapping file. A file whose bytes already exist as a live mapping file in the workspace returns that file with duplicateOfExisting set and creates nothing. A file that fails validation is refused with the offending line number and nothing is stored.",
        "tags": [
          "mapping-files"
        ],
        "operationId": "complete_mapping_file_upload",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MappingFileCompleteUploadRequest"
              },
              "example": {
                "uploadId": "upload_2cVQ8f0YyQ3nT1hKpR7mBz4LsXd",
                "parts": [
                  {
                    "partNumber": 1,
                    "etag": "\"d41d8cd98f00b204e9800998ecf8427e\""
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The uploaded bytes already exist as a live mapping file in this workspace; that file is returned with duplicateOfExisting true and no new mapping file was created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MappingFileDetails"
                },
                "example": {
                  "id": "mapfile_2cVQ8f0YyQ3nT1hKpR7mBz4LsXd",
                  "name": "gpt-175b-256n.txt",
                  "workspaceId": "workspace_def456",
                  "sizeBytes": 4096,
                  "rankCount": 256,
                  "scaleUpGroupCount": 2,
                  "hasScaleUp": true,
                  "createdAt": "2026-09-16T14:30:00Z",
                  "description": "Reverse placement for the 256-rank study",
                  "hash": "crc64nvme:vK3Jd8Qm1pA",
                  "etag": "\"0\"",
                  "duplicateOfExisting": true
                }
              }
            }
          },
          "201": {
            "description": "Mapping file stored and created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MappingFileDetails"
                },
                "example": {
                  "id": "mapfile_2cVQ8f0YyQ3nT1hKpR7mBz4LsXd",
                  "name": "gpt-175b-256n.txt",
                  "workspaceId": "workspace_def456",
                  "sizeBytes": 4096,
                  "rankCount": 256,
                  "scaleUpGroupCount": 2,
                  "hasScaleUp": true,
                  "createdAt": "2026-09-16T14:30:00Z",
                  "description": "Reverse placement for the 256-rank study",
                  "hash": "crc64nvme:vK3Jd8Qm1pA",
                  "etag": "\"0\"",
                  "duplicateOfExisting": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — the upload session is not a mapping-file upload, or the parts do not match the session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Expected 1 part(s), got 2"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Upload session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "Upload session not found"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The upload session named by uploadId is already being completed or was already completed or aborted (CONFLICT), or a different mapping file with this display name is already stored under this content checksum (MAPPING_FILE_HASH_COLLISION)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "MAPPING_FILE_HASH_COLLISION",
                    "message": "A different mapping file is already stored under this content checksum. Re-upload under a different display name."
                  }
                }
              }
            }
          },
          "410": {
            "description": "Upload session expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "GONE",
                    "message": "Upload session has expired"
                  }
                }
              }
            }
          },
          "413": {
            "description": "The staged object is larger than the declared sizeBytes, or above the 64 MB limit; staging is deleted and nothing is stored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PAYLOAD_TOO_LARGE",
                    "message": "Staged object is 70000000 bytes, above the declared 4096 bytes and/or the 64 MB per-file limit of 64000000 bytes"
                  }
                }
              }
            }
          },
          "422": {
            "description": "The file does not parse as a Chakra mapping file; the message names the offending line",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "MAPPING_FILE_INVALID",
                    "message": "line 3: expected an integer server id, found 'x'"
                  }
                }
              }
            }
          },
          "503": {
            "description": "Another upload of the same content held the content lock for too long. This upload session is closed and its staged object deleted, so the request is not safe to retry: open a new upload session and upload the file again. Because another upload of the same content was in progress, the new upload is most often answered 200 with duplicateOfExisting set.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Internal server error"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer_auth": []
          }
        ]
      }
    },
    "/api/v1/simple/simulations": {
      "post": {
        "tags": [
          "simple"
        ],
        "summary": "Submit a collective-operation workload for simple network simulation",
        "description": "Validates the workload against operation/algorithm compatibility rules, resolves or synthesizes a topology and traceset, creates a configuration, and launches a simulation. Returns immediately with status `accepted`; poll `GET /api/v1/simulations/{simulationId}` to track progress. Note: the poll response uses a different schema (`SimulationDetails`) — the simulation ID is returned as `id` (not `simulationId`), the workload is not echoed back, and the status transitions from `accepted` to `provisioning` on the next poll. Identical workloads are deduplicated via content-addressed tracesets.",
        "operationId": "createSimpleSimulation",
        "security": [
          {
            "bearer_auth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleSimulationRequest"
              },
              "examples": {
                "minimal": {
                  "summary": "128-rank AllReduce with default topology",
                  "value": {
                    "workload": {
                      "ranks": 128,
                      "phases": [
                        {
                          "operationType": "allReduce",
                          "dataSize": 1048576
                        }
                      ]
                    }
                  }
                },
                "with_constraints": {
                  "summary": "Custom topology with 192 ranks",
                  "value": {
                    "name": "custom-topology-test",
                    "topologyConstraints": {
                      "switchRadix": "128x400G",
                      "subscriptionRatio": "3:1"
                    },
                    "workload": {
                      "ranks": 192,
                      "phases": [
                        {
                          "operationType": "allReduce",
                          "algorithm": "ring",
                          "dataSize": 1048576
                        }
                      ]
                    }
                  }
                },
                "multi_phase": {
                  "summary": "Multiple phases in one submission",
                  "value": {
                    "workload": {
                      "ranks": 256,
                      "phases": [
                        {
                          "operationType": "allReduce",
                          "dataSize": 1024
                        },
                        {
                          "operationType": "allGather",
                          "dataSize": 1048576
                        },
                        {
                          "operationType": "reduceScatter",
                          "dataSize": 67108864
                        }
                      ]
                    }
                  }
                },
                "alltoall_with_algorithm": {
                  "summary": "AllToAll with sequential algorithm",
                  "value": {
                    "workload": {
                      "ranks": 128,
                      "phases": [
                        {
                          "operationType": "allToAll",
                          "algorithm": "sequential",
                          "dataSize": 524288
                        }
                      ]
                    }
                  }
                },
                "broadcast_scatter": {
                  "summary": "Broadcast followed by scatter",
                  "value": {
                    "workload": {
                      "ranks": 64,
                      "phases": [
                        {
                          "operationType": "broadcast",
                          "algorithm": "interleaved",
                          "dataSize": 2097152
                        },
                        {
                          "operationType": "scatter",
                          "algorithm": "direct",
                          "dataSize": 1048576
                        }
                      ]
                    }
                  }
                },
                "parallel_groups": {
                  "summary": "Parallel groups executing concurrently",
                  "value": {
                    "name": "multi-group-benchmark",
                    "groups": [
                      {
                        "count": 4,
                        "groupSize": 64,
                        "phases": [
                          {
                            "operationType": "allReduce",
                            "algorithm": "ring",
                            "dataSize": 1048576
                          }
                        ]
                      }
                    ]
                  }
                },
                "mixed_parallel_groups": {
                  "summary": "Multiple group specs with different operations",
                  "value": {
                    "name": "mixed-workload-benchmark",
                    "topologyConstraints": {
                      "switchRadix": "64x800G",
                      "subscriptionRatio": "1:1"
                    },
                    "groups": [
                      {
                        "count": 2,
                        "groupSize": 128,
                        "phases": [
                          {
                            "operationType": "allReduce",
                            "algorithm": "recursiveHalvingDoubling",
                            "dataSize": 4194304
                          }
                        ]
                      },
                      {
                        "count": 4,
                        "groupSize": 32,
                        "phases": [
                          {
                            "operationType": "allGather",
                            "dataSize": 1048576
                          },
                          {
                            "operationType": "reduceScatter",
                            "algorithm": "halving",
                            "dataSize": 2097152
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Simulation accepted for processing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SimpleSimulationResponse"
                },
                "example": {
                  "simulationId": "sim_abc123",
                  "status": "accepted",
                  "mode": "sequential",
                  "workload": {
                    "ranks": 128,
                    "phases": [
                      {
                        "operationType": "allReduce",
                        "algorithm": "ring",
                        "dataSize": 1048576
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error — invalid rank count, unsupported operation/algorithm combination, both topology and topologyConstraints set, or constraint solver cannot satisfy the request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "invalid_ranks": {
                    "summary": "Rank count not in reference set (no constraints)",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "ranks must be one of [4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096], got 100"
                      }
                    }
                  },
                  "incompatible_algorithm": {
                    "summary": "Algorithm not valid for operation",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "algorithm 'ring' is not compatible with operation 'allToAll'; allowed algorithms: sequential, interleaved"
                      }
                    }
                  },
                  "mutual_exclusivity": {
                    "summary": "Both topology and topologyConstraints provided",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "topologyConstraints and topology are mutually exclusive"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid authentication token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable - the simulation service could not start the simulation. No simulation is created, so the request can be retried.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/simple/simulations/preview": {
      "post": {
        "tags": [
          "simple"
        ],
        "summary": "Preview the derived topology for a simple simulation request",
        "description": "Runs the full validation and topology derivation pipeline against the provided workload or groups, then returns the physical network topology that would be produced — without creating a simulation, traceset, or configuration. The request body is identical to POST /api/v1/simple/simulations. The workload/groups payload is required because the total rank count drives topology derivation (rack count, tier selection, switch allocation), but no workload details are echoed in the response. The response describes only the physical network: tier structure, switch counts, link counts, data rates, and resolved constraint values.",
        "operationId": "previewSimpleTopology",
        "security": [
          {
            "bearer_auth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleSimulationRequest"
              },
              "examples": {
                "two_tier": {
                  "summary": "128-rank AllReduce — produces 2-tier topology",
                  "value": {
                    "workload": {
                      "ranks": 128,
                      "phases": [
                        {
                          "operationType": "allReduce",
                          "dataSize": 1048576
                        }
                      ]
                    }
                  }
                },
                "one_tier_with_constraints": {
                  "summary": "8 ranks with constraints — produces 1-tier (single rack)",
                  "value": {
                    "topologyConstraints": {
                      "switchRadix": "128x400G",
                      "subscriptionRatio": "1:1"
                    },
                    "workload": {
                      "ranks": 8,
                      "phases": [
                        {
                          "operationType": "allReduce",
                          "dataSize": 1024
                        }
                      ]
                    }
                  }
                },
                "three_tier_with_constraints": {
                  "summary": "16384 ranks — produces 3-tier pod topology",
                  "value": {
                    "topologyConstraints": {
                      "switchRadix": "128x400G",
                      "subscriptionRatio": "1:1"
                    },
                    "workload": {
                      "ranks": 16384,
                      "phases": [
                        {
                          "operationType": "allReduce",
                          "dataSize": 1048576
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Topology preview computed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TopologyPreviewResponse"
                },
                "examples": {
                  "two_tier": {
                    "summary": "2-tier topology (128 ranks, default constraints)",
                    "value": {
                      "topology": {
                        "tierCount": 2,
                        "totalHosts": 128,
                        "ranksPerHost": 1,
                        "ranksPerRack": 64,
                        "tiers": [
                          {
                            "name": "RSW",
                            "switchCount": 2,
                            "downlinksPerSwitch": 64,
                            "uplinksPerSwitch": 64,
                            "downlinkDataRateGbps": 400,
                            "uplinkDataRateGbps": 400,
                            "effectiveSubscriptionRatio": "1:1",
                            "switchCapacityUtilization": 100.0
                          },
                          {
                            "name": "FSW",
                            "switchCount": 1,
                            "downlinksPerSwitch": 128,
                            "uplinksPerSwitch": 0,
                            "downlinkDataRateGbps": 400,
                            "uplinkDataRateGbps": 0,
                            "switchCapacityUtilization": 100.0
                          }
                        ],
                        "links": {
                          "hostToRsw": 128,
                          "rswToFsw": 128,
                          "fswToSsw": 0
                        },
                        "resolvedConstraints": {
                          "switchRadix": "128x400G",
                          "subscriptionRatio": "1:1",
                          "nicNetworkPortSpeed": 400,
                          "effectiveNicSpeed": 400,
                          "switchLinkSpeed": 400,
                          "switchingCapacityGbps": 51200
                        }
                      }
                    }
                  },
                  "one_tier": {
                    "summary": "1-tier topology (8 ranks with constraints)",
                    "value": {
                      "topology": {
                        "tierCount": 1,
                        "totalHosts": 8,
                        "ranksPerHost": 1,
                        "ranksPerRack": 8,
                        "tiers": [
                          {
                            "name": "RSW",
                            "switchCount": 1,
                            "downlinksPerSwitch": 8,
                            "uplinksPerSwitch": 0,
                            "downlinkDataRateGbps": 400,
                            "uplinkDataRateGbps": 0,
                            "switchCapacityUtilization": 6.25
                          }
                        ],
                        "links": {
                          "hostToRsw": 8,
                          "rswToFsw": 0,
                          "fswToSsw": 0
                        },
                        "resolvedConstraints": {
                          "switchRadix": "128x400G",
                          "subscriptionRatio": "1:1",
                          "nicNetworkPortSpeed": 400,
                          "effectiveNicSpeed": 400,
                          "switchLinkSpeed": 400,
                          "switchingCapacityGbps": 51200
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error — identical to POST /api/v1/simple/simulations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "invalid_ranks": {
                    "summary": "Rank count not in reference set (no constraints)",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "ranks must be one of [4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096], got 100"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid authentication token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/simple/compatibility": {
      "get": {
        "tags": [
          "simple"
        ],
        "summary": "Get the operation/algorithm compatibility matrix",
        "description": "Returns the full compatibility matrix mapping each collective operation type to its allowed algorithms, platform default, and power-of-two constraints. This is a static reference endpoint — the matrix does not change between requests.",
        "operationId": "getSimpleCompatibility",
        "security": [
          {
            "bearer_auth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Compatibility matrix",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityMatrixResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid authentication token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/chart-definitions": {
      "get": {
        "tags": [
          "charts"
        ],
        "summary": "List chart definitions",
        "description": "Returns every chart definition stored on this platform as a bare body, ordered by id, under one schema version. The set is bounded server-side and is therefore unpaginated: a client needs all of it atomically under a single schemaVersion. A reader names the newest chart-definition schema version it parses in the schemaVersion query parameter; each chart is served at the highest stored body version that does not exceed it, and a request without the parameter is served chart-definition/v1.",
        "operationId": "list_chart_definitions",
        "parameters": [
          {
            "name": "schemaVersion",
            "in": "query",
            "required": false,
            "description": "The newest chart-definition schema version the reader parses, as chart-definition/v<N> with N a positive integer and no leading zero. Absent, the response is chart-definition/v1. Versions compare as integers, and a version newer than any body stored for a chart is served that chart's newest stored body. A value outside that grammar, or the parameter given more than once, is refused with 400.",
            "schema": {
              "type": "string",
              "pattern": "^chart-definition/v[1-9][0-9]*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The platform's chart definitions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChartDefinitionsResponse"
                }
              }
            }
          },
          "400": {
            "description": "The schemaVersion query parameter is malformed or repeated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Endpoint not served: this platform's release predates it, or it runs with enable_chart_definitions off. No handler is mounted on either path, so this status carries no body."
          },
          "500": {
            "description": "The definitions could not be read, or the set breached a served bound and was refused whole",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "504": {
            "description": "The read exceeded the server-side statement budget and was cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Pagination": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "description": "Number of items in this response"
          },
          "hasMore": {
            "type": "boolean",
            "description": "Whether more results are available"
          },
          "nextCursor": {
            "type": "string",
            "description": "Opaque cursor token for fetching the next page (only present if hasMore is true)"
          }
        },
        "required": [
          "count",
          "hasMore"
        ]
      },
      "ErrorDetail": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Machine-readable error code. Clients should switch on this field rather than parsing the message.",
            "default": "UNKNOWN",
            "enum": [
              "UNKNOWN",
              "VALIDATION_ERROR",
              "UNAUTHORIZED",
              "FORBIDDEN",
              "NOT_FOUND",
              "GONE",
              "CONFLICT",
              "PRECONDITION_FAILED",
              "INTERNAL_ERROR",
              "BAD_GATEWAY",
              "SERVICE_UNAVAILABLE",
              "RATE_LIMIT_EXCEEDED",
              "INVALID_CURSOR",
              "CURSOR_EXPIRED",
              "UNPROCESSABLE_ENTITY",
              "PAYMENT_REQUIRED",
              "PAYLOAD_TOO_LARGE",
              "NOT_IMPLEMENTED",
              "GATEWAY_TIMEOUT",
              "INVALID_IDEMPOTENCY_KEY",
              "IDEMPOTENCY_KEY_REUSE",
              "REQUEST_IN_PROGRESS",
              "PREVIOUS_REQUEST_FAILED",
              "RESPONSE_BODY_TOO_LARGE",
              "MAPPING_FILE_HASH_COLLISION",
              "MAPPING_FILE_DELETED",
              "MAPPING_REQUIRES_TRACESET",
              "MAPPING_REQUIRES_CHAKRA_APP",
              "MAPPING_RANK_COUNT_MISMATCH",
              "MAPPING_PARAMS_LOCKED",
              "TRACESET_CONFLICTS_WITH_MAPPING",
              "MAPPING_FILE_DELETED_REFERENCE",
              "MAPPING_FILE_MISSING",
              "MAPPING_PARAMS_INCONSISTENT",
              "MAPPING_FILE_INVALID",
              "UNSUPPORTED_COMBINATION",
              "LAUNCH_REJECTED",
              "LAUNCH_CONFIG_INVALID"
            ]
          },
          "details": {
            "description": "Additional error details (structure varies by error type)"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error description"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        }
      },
      "DeletionResponse": {
        "type": "object",
        "description": "Generic response confirming a resource has been deleted or scheduled for deletion.",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "status",
          "message"
        ]
      },
      "HealthResponse": {
        "type": "object",
        "required": [
          "status",
          "timestamp"
        ],
        "properties": {
          "status": {
            "type": "string"
          },
          "timestamp": {
            "type": "string"
          }
        }
      },
      "ReadinessResponse": {
        "type": "object",
        "required": [
          "status",
          "checks",
          "timestamp"
        ],
        "properties": {
          "checks": {
            "description": "Health check results by subsystem name"
          },
          "status": {
            "type": "string"
          },
          "timestamp": {
            "type": "string"
          }
        }
      },
      "ModelType": {
        "type": "string",
        "description": "Model category - hardware components, applications, topology layers, or topology containers (rack, pod)",
        "enum": [
          "switch",
          "nic",
          "server",
          "application",
          "layer",
          "rack",
          "pod"
        ]
      },
      "ModelStatus": {
        "type": "string",
        "description": "Model release status",
        "enum": [
          "stable",
          "beta",
          "deprecated"
        ]
      },
      "ModelDescription": {
        "type": "object",
        "description": "Summary model info for list responses",
        "properties": {
          "id": {
            "type": "string",
            "description": "Model KSUID (e.g., model_37w6uUurBkspg7voji4julJIPSP)"
          },
          "model": {
            "type": "string",
            "description": "Model name in PascalCase (e.g., ScalaSwitch)"
          },
          "name": {
            "type": "string",
            "description": "Internal model name (e.g., ScalaSwitch)"
          },
          "type": {
            "$ref": "#/components/schemas/ModelType"
          },
          "vendor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model vendor/owner (extracted from owner_subject)"
          },
          "latestVersion": {
            "type": "string",
            "description": "Latest available version (e.g., 3.2.1)"
          },
          "compatibility": {
            "type": [
              "string",
              "null"
            ],
            "description": "Platform compatibility (e.g., platform-v4.x)"
          },
          "status": {
            "$ref": "#/components/schemas/ModelStatus"
          }
        },
        "required": [
          "id",
          "model",
          "name",
          "type",
          "latestVersion"
        ]
      },
      "ModelVersion": {
        "type": "object",
        "description": "Version info for a model",
        "properties": {
          "version": {
            "type": "string",
            "description": "Semantic version (e.g., 3.2.1)"
          },
          "status": {
            "$ref": "#/components/schemas/ModelStatus"
          },
          "compatibility": {
            "type": [
              "string",
              "null"
            ],
            "description": "Platform compatibility for this version"
          }
        },
        "required": [
          "version",
          "status"
        ]
      },
      "ModelVersionsResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Model KSUID (e.g., model_37w6uUurBkspg7voji4julJIPSP)"
          },
          "model": {
            "type": "string",
            "description": "Model name in PascalCase (e.g., ScalaSwitch)"
          },
          "versions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModelVersion"
            }
          }
        },
        "required": [
          "id",
          "model",
          "versions"
        ]
      },
      "ModelsListResponse": {
        "type": "object",
        "properties": {
          "models": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModelDescription"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "models",
          "pagination"
        ]
      },
      "TemplateCategory": {
        "type": "string",
        "enum": [
          "getting-started",
          "generated-template",
          "topology",
          "traffic-pattern",
          "validation"
        ],
        "description": "Category of template"
      },
      "TemplateDescription": {
        "type": "object",
        "description": "Summary template info for list responses",
        "properties": {
          "id": {
            "type": "string",
            "description": "Template identifier"
          },
          "name": {
            "type": "string",
            "description": "Template name"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description"
          },
          "category": {
            "$ref": "#/components/schemas/TemplateCategory"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "category"
        ]
      },
      "TemplateDetails": {
        "type": "object",
        "description": "Full template details including configuration",
        "properties": {
          "id": {
            "type": "string",
            "description": "Template identifier"
          },
          "name": {
            "type": "string",
            "description": "Template name"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description"
          },
          "category": {
            "$ref": "#/components/schemas/TemplateCategory"
          },
          "configuration": {
            "$ref": "#/components/schemas/ConfigurationDetails",
            "description": "Full configuration details in V2 format with typedParameters"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "category",
          "configuration"
        ]
      },
      "TemplatesListResponse": {
        "type": "object",
        "properties": {
          "templates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateDescription"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "templates",
          "pagination"
        ]
      },
      "CloneRequest": {
        "type": "object",
        "description": "Request to clone a template to a new configuration",
        "properties": {
          "workspaceId": {
            "type": "string",
            "description": "Target workspace identifier"
          },
          "name": {
            "type": "string",
            "description": "Name for the new configuration",
            "minLength": 1,
            "maxLength": 64
          }
        },
        "required": [
          "name"
        ]
      },
      "CreateTemplateRequest": {
        "type": "object",
        "description": "Request body for creating a template (V2 format with typedParameters)",
        "properties": {
          "name": {
            "type": "string",
            "description": "Template name",
            "minLength": 1,
            "maxLength": 64
          },
          "description": {
            "type": "string",
            "description": "Human-readable description"
          },
          "category": {
            "$ref": "#/components/schemas/TemplateCategory"
          },
          "components": {
            "type": "array",
            "description": "Component declarations with typedParameters",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          },
          "containers": {
            "type": "array",
            "description": "Container definitions",
            "items": {
              "$ref": "#/components/schemas/ContainerDefinition"
            }
          },
          "topology": {
            "$ref": "#/components/schemas/TopologyDefinition",
            "description": "Topology definition with links as ComponentDeclaration (type: layer)"
          },
          "globalParameters": {
            "$ref": "#/components/schemas/TypedParameters",
            "description": "Global parameters in TypedParameters format"
          },
          "applications": {
            "type": "array",
            "description": "Traffic generator and workload applications",
            "items": {
              "$ref": "#/components/schemas/ApplicationDefinition"
            }
          },
          "links": {
            "type": "array",
            "description": "Layer components defining spine plane linking configuration (type='layer')",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          }
        },
        "required": [
          "name",
          "description",
          "category"
        ]
      },
      "ParameterValueSchema": {
        "type": "object",
        "description": "Parameter value with full metadata for component schema. Used in GET /api/v1/components/{id} response.",
        "properties": {
          "value": {
            "description": "Current parameter value (type varies based on 'type' field)"
          },
          "type": {
            "$ref": "#/components/schemas/ParameterType",
            "description": "Data type of the value"
          },
          "unit": {
            "type": "string",
            "description": "Unit for dimensional types (datarate, timeval, bytes, queuesize)"
          },
          "enum": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Allowed values for this parameter"
          },
          "default": {
            "description": "Default value for this parameter"
          },
          "defaultUnit": {
            "type": "string",
            "description": "Default unit for dimensional types"
          },
          "description": {
            "type": "string",
            "description": "Parameter description"
          },
          "min": {
            "$ref": "#/components/schemas/ParameterBound",
            "description": "Minimum value constraint"
          },
          "max": {
            "$ref": "#/components/schemas/ParameterBound",
            "description": "Maximum value constraint"
          },
          "readonly": {
            "type": "boolean",
            "description": "Whether parameter is read-only"
          }
        },
        "required": [
          "value",
          "type"
        ]
      },
      "ParameterBound": {
        "type": "object",
        "description": "One bound of a parameter's range. A dimensional type (datarate, timeval, bytes, queuesize) carries the bound's unit, which can differ from the unit of the parameter's value. A numeric type omits unit.",
        "properties": {
          "value": {
            "type": "number",
            "description": "The bound's numeric value, in unit when unit is present"
          },
          "unit": {
            "type": "string",
            "description": "Unit of value for dimensional types only. Omit for non-dimensional types."
          }
        },
        "required": [
          "value"
        ]
      },
      "TypedParameterSchemaEntry": {
        "description": "A parameter entry that can be either a leaf value (ParameterValueSchema), a nested parameters object (TypedParametersSchema), or a model component schema entry",
        "oneOf": [
          {
            "$ref": "#/components/schemas/ParameterValueSchema"
          },
          {
            "$ref": "#/components/schemas/TypedParametersSchema"
          },
          {
            "$ref": "#/components/schemas/ModelComponentSchemaEntry"
          }
        ]
      },
      "ModelComponentSchemaEntry": {
        "type": "object",
        "description": "A model component entry with schema metadata. Used for both application types (client/server) and device model components.",
        "properties": {
          "name": {
            "type": "string",
            "description": "Component instance name"
          },
          "typedParameters": {
            "$ref": "#/components/schemas/TypedParametersSchema",
            "description": "Optional component parameters schema (only present if component has attributes)"
          },
          "componentType": {
            "type": "string",
            "description": "V1 ComponentType (e.g., Container, AggregatedObjectFactory)"
          },
          "model": {
            "type": "string",
            "description": "Model reference (e.g., scala_roce_nic::ScalaRoceEventProcessingLayer)"
          }
        },
        "required": [
          "name"
        ]
      },
      "TypedParametersSchema": {
        "type": "object",
        "description": "Hierarchical parameters with full metadata. Leaf nodes are ParameterValueSchema objects, branch nodes are nested TypedParametersSchema. Hidden parameters are filtered out.",
        "additionalProperties": {
          "$ref": "#/components/schemas/TypedParameterSchemaEntry"
        }
      },
      "ComponentDescription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Model KSUID (e.g., model_37w6uUurBkspg7voji4julJIPSP)",
            "example": "model_37w6uUurBkspg7voji4julJIPSP"
          },
          "model": {
            "type": "string",
            "description": "Model name in PascalCase (e.g., ScalaSwitch)",
            "example": "ScalaSwitch"
          },
          "name": {
            "type": "string",
            "description": "Model name in PascalCase (e.g., ScalaSwitch)"
          },
          "category": {
            "type": "string",
            "enum": [
              "model",
              "topology",
              "application"
            ]
          },
          "type": {
            "type": "string",
            "description": "Component type (switch, nic, server, rack, pod, application)"
          },
          "description": {
            "type": "string"
          },
          "latestVersion": {
            "type": "string",
            "description": "Latest available version determined by semantic versioning (e.g., 3.2.1)"
          },
          "versions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Available versions sorted by semantic version (latest first)"
          }
        },
        "required": [
          "id",
          "model",
          "name",
          "category",
          "type",
          "description",
          "latestVersion",
          "versions"
        ]
      },
      "ComponentSchema": {
        "type": "object",
        "description": "Full schema for components. Model components include typedParameters; container types (rack, pod) include containerSchema.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Model KSUID"
          },
          "name": {
            "type": "string",
            "description": "Model name in PascalCase"
          },
          "category": {
            "type": "string",
            "enum": [
              "model",
              "topology",
              "application"
            ],
            "description": "Component category"
          },
          "type": {
            "type": "string",
            "description": "Component type (switch, nic, server, application, rack, pod)"
          },
          "trafficType": {
            "type": "string",
            "enum": [
              "chakra",
              "coordinated",
              "non-coordinated"
            ],
            "description": "Traffic pattern type. Only present for application components."
          },
          "description": {
            "type": "string",
            "description": "Model description"
          },
          "version": {
            "type": "string",
            "description": "Requested model version"
          },
          "latestVersion": {
            "type": "string",
            "description": "Latest available version of this model"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Version creation timestamp (ISO 8601)"
          },
          "typedParameters": {
            "$ref": "#/components/schemas/TypedParametersSchema",
            "description": "For model components (switch, nic, server, application). Typed hierarchical parameters with full metadata."
          },
          "containerSchema": {
            "$ref": "#/components/schemas/ContainerSchema",
            "description": "For container types (rack, pod). Describes structure and allowed component types."
          },
          "notes": {
            "type": "string",
            "description": "Product notes for this version. Only included when notes=true query parameter is set."
          }
        },
        "required": [
          "id",
          "name",
          "category",
          "type",
          "description",
          "version",
          "latestVersion",
          "createdAt"
        ]
      },
      "FieldSchema": {
        "type": "object",
        "description": "Schema definition for a field within a container",
        "properties": {
          "type": {
            "type": "string",
            "description": "Field type (string, integer, etc.)"
          },
          "description": {
            "type": "string",
            "description": "Field description"
          },
          "enum": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Allowed enum values (optional)"
          },
          "minimum": {
            "type": "integer",
            "description": "Minimum value for integers (optional)"
          }
        },
        "required": [
          "type",
          "description"
        ]
      },
      "ComponentRefSchema": {
        "type": "object",
        "description": "Schema definition for component reference items within a container",
        "properties": {
          "name": {
            "$ref": "#/components/schemas/FieldSchema"
          },
          "type": {
            "$ref": "#/components/schemas/FieldSchema"
          },
          "count": {
            "$ref": "#/components/schemas/FieldSchema"
          }
        },
        "required": [
          "name",
          "type",
          "count"
        ]
      },
      "ComponentsArraySchema": {
        "type": "object",
        "description": "Schema definition for the components array within a container",
        "properties": {
          "type": {
            "type": "string",
            "description": "Array type (always 'array')"
          },
          "description": {
            "type": "string",
            "description": "Description of the array"
          },
          "items": {
            "$ref": "#/components/schemas/ComponentRefSchema"
          }
        },
        "required": [
          "type",
          "description",
          "items"
        ]
      },
      "ContainerSchema": {
        "type": "object",
        "description": "Descriptive schema for container types (rack, pod) returned by GET /api/v1/components/{id}. Shows the structure and allowed values for a container type.",
        "properties": {
          "type": {
            "type": "string",
            "description": "Container type (rack or pod)",
            "enum": [
              "rack",
              "pod"
            ]
          },
          "name": {
            "$ref": "#/components/schemas/FieldSchema",
            "description": "Schema for the name field"
          },
          "allowed": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Allowed component types for this container. Rack: [switch, nic, server, application]. Pod: [rack, switch, layer]."
          },
          "components": {
            "$ref": "#/components/schemas/ComponentsArraySchema",
            "description": "Schema for the components array"
          }
        },
        "required": [
          "type",
          "name",
          "allowed",
          "components"
        ]
      },
      "ComponentsListResponse": {
        "type": "object",
        "properties": {
          "components": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComponentDescription"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "components",
          "pagination"
        ]
      },
      "ParameterType": {
        "type": "string",
        "enum": [
          "bool",
          "int",
          "uint",
          "int64",
          "uint64",
          "double",
          "float",
          "string",
          "bytes",
          "queuesize",
          "datarate",
          "timeval",
          "seconds",
          "milliseconds",
          "microseconds",
          "nanoseconds",
          "picoseconds",
          "femtoseconds"
        ],
        "description": "Data type of a parameter value"
      },
      "ParameterValue": {
        "type": "object",
        "description": "A fully-typed parameter value with explicit value, type, optional unit (for dimensional types), and optional enum",
        "properties": {
          "value": {
            "description": "The parameter value (type varies based on 'type' field)"
          },
          "unit": {
            "type": "string",
            "description": "Unit for dimensional types only (datarate, timeval, bytes, queuesize). Omit for non-dimensional types."
          },
          "type": {
            "$ref": "#/components/schemas/ParameterType"
          },
          "enum": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Optional list of allowed values for this parameter"
          }
        },
        "required": [
          "value",
          "type"
        ]
      },
      "TypedParameterEntry": {
        "description": "A parameter entry that can be either a leaf value, a nested parameters object, or a model component entry",
        "oneOf": [
          {
            "$ref": "#/components/schemas/ParameterValue"
          },
          {
            "$ref": "#/components/schemas/TypedParameters"
          },
          {
            "$ref": "#/components/schemas/ModelComponentEntry"
          }
        ]
      },
      "ModelComponentEntry": {
        "type": "object",
        "description": "A model component entry preserving structural metadata. Used for both application types (client/server) and device model components.",
        "properties": {
          "name": {
            "type": "string",
            "description": "Component instance name"
          },
          "typedParameters": {
            "$ref": "#/components/schemas/TypedParameters",
            "description": "Optional component parameters (only present if component has attributes)"
          },
          "componentType": {
            "type": "string",
            "description": "V1 ComponentType (e.g., Container, AggregatedObjectFactory)"
          },
          "model": {
            "type": "string",
            "description": "Model reference (e.g., scala_roce_nic::ScalaRoceEventProcessingLayer)"
          }
        },
        "required": [
          "name"
        ]
      },
      "TypedParameters": {
        "type": "object",
        "description": "Hierarchical parameters structure. Leaf nodes are ParameterValue objects, branch nodes are nested TypedParameters representing ModelComponents.",
        "additionalProperties": {
          "$ref": "#/components/schemas/TypedParameterEntry"
        }
      },
      "ComponentType": {
        "type": "string",
        "enum": [
          "switch",
          "nic",
          "server",
          "application",
          "layer",
          "rack",
          "pod",
          "gpu"
        ],
        "description": "Type of network component"
      },
      "ContainerType": {
        "type": "string",
        "enum": [
          "rack",
          "pod",
          "colo",
          "az",
          "dc",
          "region"
        ],
        "description": "Type of infrastructure container in the deployment hierarchy"
      },
      "TopologyType": {
        "type": "string",
        "enum": [
          "clos"
        ],
        "description": "Network topology architecture type"
      },
      "AppDistribution": {
        "type": "object",
        "description": "Application distribution settings for random placement of applications across hosts",
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Human-readable description of the distribution strategy"
          },
          "randomApplicationDistribution": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RandomApplicationDistribution"
            },
            "description": "List of applications with their distribution percentages"
          }
        },
        "required": [
          "randomApplicationDistribution"
        ]
      },
      "RandomApplicationDistribution": {
        "type": "object",
        "description": "Distribution settings for a single model component (client or server)",
        "properties": {
          "parentApplication": {
            "type": "string",
            "description": "Root application name (must match an entry in the applications array)"
          },
          "name": {
            "type": "string",
            "description": "Model component name (e.g., 'TrafficGeneratorClient', 'storageReader')"
          },
          "applicationType": {
            "type": "string",
            "enum": [
              "client",
              "server"
            ],
            "description": "Whether this is a client or server model component"
          },
          "distributionPercent": {
            "$ref": "#/components/schemas/DistributionPercent",
            "description": "Distribution percentage with identifier. Omit when prClientVariable is 'none' (e.g., co-located servers)"
          }
        },
        "required": [
          "parentApplication",
          "name",
          "applicationType"
        ]
      },
      "DistributionPercent": {
        "type": "object",
        "description": "Distribution percentage with identifier linking to V1 prClientVariable",
        "properties": {
          "distributionId": {
            "type": "string",
            "description": "Identifier linking to prClientVariable in V1 model components (e.g., 'prScalaTrafficGenerator')"
          },
          "value": {
            "type": "number",
            "description": "Percentage value (0.0 to 1.0)",
            "minimum": 0.0,
            "maximum": 1.0
          }
        },
        "required": [
          "distributionId",
          "value"
        ]
      },
      "TrafficType": {
        "type": "string",
        "enum": [
          "chakra",
          "non-coordinated"
        ],
        "x-enum-aliases": {
          "chakra": [
            "coordinated"
          ]
        },
        "description": "Traffic pattern type. The value 'coordinated' is accepted on input as a deprecated alias for 'chakra' but is never emitted in responses."
      },
      "ComponentDeclaration": {
        "type": "object",
        "description": "Declaration of a network component (switch, NIC, server, application, layer). Components can have typed children via allowedComponents + components.",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/ComponentType"
          },
          "trafficType": {
            "$ref": "#/components/schemas/TrafficType",
            "description": "Traffic pattern type. Only present for application components (chakra or non-coordinated)."
          },
          "model": {
            "type": "string",
            "description": "Model name in PascalCase (e.g., ScalaSwitch)",
            "example": "ScalaSwitch"
          },
          "name": {
            "type": "string",
            "description": "Unique customer-defined component instance name",
            "minLength": 1,
            "maxLength": 64,
            "example": "spine-switch-1"
          },
          "version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model version (e.g., 3.2.1)",
            "example": "3.2.1"
          },
          "typedParameters": {
            "$ref": "#/components/schemas/TypedParameters",
            "description": "Typed hierarchical parameters with {value, type, unit?, enum?} structure"
          },
          "allowedComponents": {
            "type": "array",
            "description": "Component types allowed as children (e.g. [\"gpu\", \"nic\", \"application\"])",
            "items": {
              "type": "string"
            }
          },
          "components": {
            "type": "array",
            "description": "Child component references with instance count",
            "items": {
              "$ref": "#/components/schemas/ComponentReference"
            }
          }
        },
        "required": [
          "type",
          "model",
          "name"
        ]
      },
      "ComponentReference": {
        "type": "object",
        "description": "Reference to a component or container with instance count",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the component or container to reference",
            "example": "spine-1"
          },
          "count": {
            "type": "integer",
            "description": "Number of instances",
            "minimum": 1,
            "maximum": 65536,
            "default": 1,
            "example": 4
          },
          "model": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model name (optional, for reference clarity)",
            "example": "ScalaSwitch"
          },
          "version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model version (optional)",
            "example": "3.2.1"
          },
          "type": {
            "type": "string",
            "description": "Component type (switch, nic, server, application, rack, pod)",
            "example": "switch"
          },
          "group": {
            "type": [
              "string",
              "null"
            ],
            "description": "Logical group for relating components (e.g., 'group1' pairs NICs with Hosts)"
          },
          "parentApplicationName": {
            "type": [
              "string",
              "null"
            ],
            "description": "For application type only: the 'name' field of the parent ApplicationDefinition in the root applications array"
          }
        },
        "required": [
          "name",
          "count",
          "type"
        ]
      },
      "ContainerDefinition": {
        "type": "object",
        "description": "Definition of a container grouping components in the infrastructure hierarchy",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/ContainerType",
            "description": "Container type in the infrastructure hierarchy"
          },
          "name": {
            "type": "string",
            "description": "Unique container name",
            "minLength": 1,
            "maxLength": 64,
            "example": "roce-rack"
          },
          "model": {
            "type": [
              "string",
              "null"
            ],
            "description": "Container model name (e.g., ScalaRack)",
            "example": "ScalaRack"
          },
          "version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model version (e.g., 4.0.0)",
            "example": "4.0.0"
          },
          "configuration": {
            "type": [
              "string",
              "null"
            ],
            "description": "Configuration description (e.g., 'Base Model Configuration')"
          },
          "allowedComponents": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Component types allowed in this container (e.g., ['Switch', 'Nic', 'Server', 'ApplicationProfile'])"
          },
          "components": {
            "type": "array",
            "description": "Included component references with counts and groups",
            "items": {
              "$ref": "#/components/schemas/ComponentReference"
            }
          }
        },
        "required": [
          "type",
          "name",
          "allowedComponents",
          "components"
        ]
      },
      "ApplicationDefinition": {
        "type": "object",
        "description": "Traffic generator or workload application definition",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/ComponentType",
            "description": "Component type (always 'application' for ApplicationDefinition)"
          },
          "trafficType": {
            "$ref": "#/components/schemas/TrafficType",
            "description": "Traffic pattern type (chakra or non-coordinated). Derived from CoordinatorType in V1."
          },
          "name": {
            "type": "string",
            "description": "Application instance name (maps to Name field in YAML)",
            "minLength": 1,
            "maxLength": 64,
            "example": "ScalaChakraGenerator"
          },
          "model": {
            "type": "string",
            "description": "Application model class name (e.g., ChakraWorkload, ScalaTrafficGenerator)",
            "example": "ChakraWorkload"
          },
          "version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model version",
            "example": "4.0.1"
          },
          "typedParameters": {
            "$ref": "#/components/schemas/TypedParameters",
            "description": "Typed hierarchical parameters (curated subset exposed to API)"
          }
        },
        "required": [
          "type",
          "trafficType",
          "name",
          "model"
        ]
      },
      "TopologyDefinition": {
        "type": "object",
        "description": "Active network topology definition",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Topology instance name (e.g., 'TestTopology')"
          },
          "type": {
            "$ref": "#/components/schemas/TopologyType"
          },
          "topologyTiers": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5,
            "description": "Number of tiers in CLOS topology (e.g., 3 for spine-fabric-rack)"
          },
          "allowedComponents": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Component types allowed at topology level (e.g., ['switch', 'layer', 'pod'])"
          },
          "components": {
            "type": "array",
            "description": "Top-level component references (spine switches, pods). Containers are referenced by name with type='rack' or type='pod'.",
            "items": {
              "$ref": "#/components/schemas/ComponentReference"
            }
          },
          "appDistribution": {
            "$ref": "#/components/schemas/AppDistribution",
            "description": "Application distribution settings for random placement"
          }
        },
        "required": [
          "type",
          "topologyTiers",
          "allowedComponents",
          "components"
        ]
      },
      "ValidationIssueSeverity": {
        "type": "string",
        "enum": [
          "error",
          "warning",
          "info"
        ],
        "description": "Severity level of a validation issue"
      },
      "ValidationIssue": {
        "type": "object",
        "description": "A single validation issue",
        "properties": {
          "path": {
            "type": "string",
            "description": "JSON path to the problematic element",
            "example": "$.components[2].typedParameters.numUpLinks"
          },
          "code": {
            "type": "string",
            "description": "Error code for programmatic handling",
            "example": "CONSTRAINT_VIOLATION"
          },
          "severity": {
            "$ref": "#/components/schemas/ValidationIssueSeverity"
          },
          "component": {
            "type": [
              "string",
              "null"
            ],
            "description": "Component name if applicable"
          },
          "parameter": {
            "type": [
              "string",
              "null"
            ],
            "description": "Parameter name if applicable"
          },
          "message": {
            "type": "string",
            "description": "Human-readable issue description"
          }
        },
        "required": [
          "severity",
          "message"
        ]
      },
      "ValidationStatus": {
        "type": "string",
        "enum": [
          "valid",
          "warning",
          "error"
        ],
        "description": "Overall validation status"
      },
      "ValidationResult": {
        "type": "object",
        "description": "Result of configuration validation",
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "Whether the configuration is valid"
          },
          "status": {
            "$ref": "#/components/schemas/ValidationStatus"
          },
          "errors": {
            "type": "array",
            "description": "List of validation errors",
            "items": {
              "$ref": "#/components/schemas/ValidationIssue"
            }
          },
          "warnings": {
            "type": "array",
            "description": "List of validation warnings",
            "items": {
              "$ref": "#/components/schemas/ValidationIssue"
            }
          },
          "info": {
            "type": "array",
            "description": "List of informational validation messages",
            "items": {
              "$ref": "#/components/schemas/ValidationIssue"
            }
          }
        },
        "required": [
          "valid",
          "status"
        ]
      },
      "TopologyValidateRequest": {
        "type": "object",
        "description": "Request body for real-time topology validation. Sent from the UI wizard during topology building.",
        "required": [
          "components",
          "containers",
          "applications"
        ],
        "properties": {
          "components": {
            "type": "array",
            "description": "Component declarations (switches, NICs, servers)",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          },
          "containers": {
            "type": "array",
            "description": "Container definitions (racks, pods)",
            "items": {
              "$ref": "#/components/schemas/ContainerDefinition"
            }
          },
          "applications": {
            "type": "array",
            "description": "Application definitions",
            "items": {
              "$ref": "#/components/schemas/ApplicationDefinition"
            }
          },
          "links": {
            "type": "array",
            "description": "Layer components defining spine plane linking configuration",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          }
        }
      },
      "TopologyValidationResponse": {
        "type": "object",
        "description": "Topology validation response reusing standard ValidationResult with topology-specific extensions (simulation parameters, switch bandwidth).",
        "required": [
          "validation",
          "checksum"
        ],
        "properties": {
          "validation": {
            "$ref": "#/components/schemas/ValidationResult",
            "description": "Standard validation result (errors, warnings, info, status, valid)"
          },
          "simulationParameters": {
            "type": "array",
            "description": "Simulation parameters extracted from preprocessor report",
            "items": {
              "$ref": "#/components/schemas/SimulationParameter"
            }
          },
          "switchBandwidth": {
            "type": "array",
            "description": "Switch bandwidth data extracted from preprocessor report",
            "items": {
              "$ref": "#/components/schemas/SwitchBandwidthItem"
            }
          },
          "topologyMap": {
            "type": "string",
            "description": "Topology map string from preprocessor"
          },
          "checksum": {
            "type": "string",
            "description": "Unique checksum for this validation response"
          }
        }
      },
      "SimulationParameter": {
        "type": "object",
        "description": "Simulation parameter extracted from preprocessor validation",
        "required": [
          "label",
          "name"
        ],
        "properties": {
          "label": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "value": {
            "description": "Parameter value - can be any JSON type (string, number, boolean, object, array)"
          }
        }
      },
      "SwitchBandwidthItem": {
        "type": "object",
        "description": "Switch bandwidth information from preprocessor",
        "required": [
          "model",
          "name",
          "networkTier"
        ],
        "properties": {
          "model": {
            "type": "string",
            "description": "Model name of the switch"
          },
          "name": {
            "type": "string",
            "description": "Instance name of the switch"
          },
          "networkTier": {
            "type": "integer",
            "description": "Network tier level"
          },
          "numOfUplinkConnections": {
            "type": "integer",
            "nullable": true
          },
          "numOfDownlinkConnections": {
            "type": "integer",
            "nullable": true
          },
          "switchingCapacity": {
            "type": "number",
            "nullable": true
          },
          "switchingCapacityUnit": {
            "type": "string",
            "nullable": true
          },
          "usedCapacity": {
            "type": "number",
            "nullable": true
          },
          "usedCapacityUnit": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "ConfigurationStatus": {
        "type": "string",
        "enum": [
          "draft",
          "validated",
          "invalid"
        ],
        "description": "Status of a configuration"
      },
      "ConfigurationDescription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "workspaceId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/ConfigurationStatus"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer"
          },
          "componentCount": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "workspaceId",
          "name",
          "status",
          "createdAt",
          "modifiedAt",
          "version"
        ]
      },
      "ConfigurationDetails": {
        "type": "object",
        "description": "Full configuration details including topology",
        "properties": {
          "id": {
            "type": "string",
            "description": "Configuration identifier",
            "example": "config_10045"
          },
          "workspaceId": {
            "type": "string",
            "description": "Workspace identifier"
          },
          "name": {
            "type": "string",
            "description": "Configuration name"
          },
          "status": {
            "$ref": "#/components/schemas/ConfigurationStatus"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer"
          },
          "componentCount": {
            "type": "integer"
          },
          "components": {
            "type": "array",
            "description": "Component declarations",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          },
          "containers": {
            "type": "array",
            "description": "Container definitions",
            "items": {
              "$ref": "#/components/schemas/ContainerDefinition"
            }
          },
          "applications": {
            "type": "array",
            "description": "Traffic generator and workload applications",
            "items": {
              "$ref": "#/components/schemas/ApplicationDefinition"
            }
          },
          "links": {
            "type": "array",
            "description": "Layer components defining spine plane linking configuration (type='layer')",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          },
          "topology": {
            "$ref": "#/components/schemas/TopologyDefinition"
          },
          "globalParameters": {
            "$ref": "#/components/schemas/TypedParameters"
          },
          "activeTraceset": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActiveTraceset"
              },
              {
                "type": "null"
              }
            ],
            "description": "Active traceset for chakra-based simulations. Required when any application has trafficType 'chakra'."
          },
          "activeMappingFile": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActiveMappingFileRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "Chakra mapping file attached to this configuration, or null. `deleted` is resolved at read time from the mapping file's own row, so a configuration that still refers to a deleted mapping file shows it as deleted."
          }
        },
        "required": [
          "id",
          "workspaceId",
          "name",
          "status",
          "createdAt",
          "modifiedAt",
          "version",
          "components",
          "containers",
          "applications",
          "links",
          "topology",
          "globalParameters"
        ]
      },
      "ConfigurationRequest": {
        "type": "object",
        "description": "Request body for creating or updating a configuration",
        "properties": {
          "workspaceId": {
            "type": "string",
            "description": "Workspace identifier. If omitted, defaults to the well-known default workspace."
          },
          "name": {
            "type": "string",
            "description": "Configuration name",
            "minLength": 1,
            "maxLength": 64
          },
          "components": {
            "type": "array",
            "description": "Component declarations",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          },
          "containers": {
            "type": "array",
            "description": "Container definitions",
            "items": {
              "$ref": "#/components/schemas/ContainerDefinition"
            }
          },
          "applications": {
            "type": "array",
            "description": "Traffic generator and workload applications",
            "items": {
              "$ref": "#/components/schemas/ApplicationDefinition"
            }
          },
          "links": {
            "type": "array",
            "description": "Layer components defining spine plane linking configuration (type='layer')",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          },
          "topology": {
            "$ref": "#/components/schemas/TopologyDefinition"
          },
          "globalParameters": {
            "$ref": "#/components/schemas/TypedParameters"
          },
          "activeTraceset": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActiveTraceset"
              },
              {
                "type": "null"
              }
            ],
            "description": "Active traceset for chakra-based simulations. Required when any application has trafficType 'chakra'."
          }
        },
        "required": [
          "name",
          "components",
          "containers",
          "applications",
          "links",
          "topology",
          "globalParameters"
        ]
      },
      "ConfigurationUpdateRequest": {
        "type": "object",
        "description": "Request body for partially updating a configuration",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Configuration name"
          },
          "components": {
            "type": "array",
            "description": "Component declarations",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          },
          "containers": {
            "type": "array",
            "description": "Container definitions",
            "items": {
              "$ref": "#/components/schemas/ContainerDefinition"
            }
          },
          "applications": {
            "type": "array",
            "description": "Traffic generator and workload applications",
            "items": {
              "$ref": "#/components/schemas/ApplicationDefinition"
            }
          },
          "links": {
            "type": "array",
            "description": "Layer components defining spine plane linking configuration (type='layer')",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          },
          "topology": {
            "$ref": "#/components/schemas/TopologyDefinition"
          },
          "globalParameters": {
            "$ref": "#/components/schemas/TypedParameters"
          },
          "activeTraceset": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActiveTraceset"
              },
              {
                "type": "null"
              }
            ],
            "description": "Active traceset for chakra-based simulations. Required when any application has trafficType 'chakra'."
          }
        }
      },
      "ConfigurationVersionSummary": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "version",
          "createdAt"
        ]
      },
      "ConfigurationVersion": {
        "type": "object",
        "description": "Full details of a specific configuration version",
        "properties": {
          "version": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "components": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          },
          "containers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContainerDefinition"
            }
          },
          "applications": {
            "type": "array",
            "description": "Traffic generator and workload applications",
            "items": {
              "$ref": "#/components/schemas/ApplicationDefinition"
            }
          },
          "links": {
            "type": "array",
            "description": "Layer components defining spine plane linking configuration (type='layer')",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          },
          "topology": {
            "$ref": "#/components/schemas/TopologyDefinition"
          },
          "globalParameters": {
            "$ref": "#/components/schemas/TypedParameters"
          },
          "activeTraceset": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ActiveTraceset"
              },
              {
                "type": "null"
              }
            ],
            "description": "Active traceset for chakra-based simulations. Required when any application has trafficType 'chakra'."
          }
        },
        "required": [
          "version",
          "createdAt",
          "components",
          "containers",
          "applications",
          "links",
          "topology",
          "globalParameters"
        ]
      },
      "ConfigurationSwitchBandwidth": {
        "type": "object",
        "description": "Per-tier switch bandwidth of a configuration version, rolled up from the native validator's switch-bandwidth records persisted when that version validated (ED-043 §12 \"S6 switch-bandwidth feed\").",
        "required": [
          "configurationId",
          "version",
          "tiers"
        ],
        "properties": {
          "configurationId": {
            "type": "string"
          },
          "version": {
            "type": "integer",
            "format": "int32",
            "minimum": 1
          },
          "tiers": {
            "type": "array",
            "description": "One entry per network tier present, ascending by networkTier",
            "items": {
              "$ref": "#/components/schemas/ConfigurationSwitchBandwidthTier"
            }
          }
        }
      },
      "ConfigurationSwitchBandwidthTier": {
        "type": "object",
        "required": [
          "networkTier",
          "switchCount",
          "switchingCapacityGbps",
          "usedCapacityGbps"
        ],
        "properties": {
          "networkTier": {
            "type": "integer",
            "format": "int32"
          },
          "switchCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "switchingCapacityGbps": {
            "type": [
              "number",
              "null"
            ],
            "format": "double",
            "description": "Sum of the tier's switching capacities in Gbps; null when any switch in the tier carries no positive, finite switching capacity. Always present."
          },
          "usedCapacityGbps": {
            "type": [
              "number",
              "null"
            ],
            "format": "double",
            "description": "Sum of the tier's provisioned link capacity in Gbps (downlinks × downlink rate + uplinks × uplink rate); null when any connected port of the tier's switches lacks a positive, finite data rate or a switch's used figure overflows, a switch with no connections contributing 0. Always present."
          }
        }
      },
      "ConfigurationVersionsListResponse": {
        "type": "object",
        "properties": {
          "versions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConfigurationVersionSummary"
            }
          }
        },
        "required": [
          "versions"
        ]
      },
      "ConfigurationsListResponse": {
        "type": "object",
        "properties": {
          "configurations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConfigurationDescription"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "configurations",
          "pagination"
        ]
      },
      "AddComponentChildRequest": {
        "type": "object",
        "description": "Request body for adding a child component to a host (server) component",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of an existing NIC, GPU, or application component in the configuration"
          },
          "type": {
            "type": "string",
            "enum": [
              "nic",
              "gpu",
              "application"
            ],
            "description": "Child component type (nic, gpu, application)"
          },
          "count": {
            "type": "integer",
            "description": "Number of instances (default 1)",
            "minimum": 1
          },
          "group": {
            "type": "string",
            "description": "Logical group for relating components"
          },
          "parentApplicationName": {
            "type": "string",
            "description": "Parent application name (required for application type children)"
          }
        },
        "required": [
          "name",
          "type"
        ]
      },
      "AddContainerComponentRequest": {
        "type": "object",
        "description": "Request body for adding a component to a container",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of an existing component or container in the configuration to add to this container",
            "example": "my-spine-switch"
          },
          "type": {
            "type": "string",
            "enum": [
              "switch",
              "nic",
              "server",
              "rack",
              "pod"
            ],
            "description": "Component type (switch, nic, server, rack, pod)"
          },
          "count": {
            "type": "integer",
            "description": "Number of instances (default 1)",
            "minimum": 1
          },
          "group": {
            "type": "string",
            "description": "Logical group for relating components"
          }
        },
        "required": [
          "name",
          "type"
        ]
      },
      "AddTopologyComponentRequest": {
        "type": "object",
        "description": "Request body for adding a component reference to the topology",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of existing component, container, or link to reference",
            "example": "my-spine-switch"
          },
          "type": {
            "type": "string",
            "enum": [
              "switch",
              "layer",
              "pod"
            ],
            "description": "Type of the referenced entity"
          },
          "count": {
            "type": "integer",
            "minimum": 1,
            "description": "Number of instances (default 1)"
          }
        },
        "required": [
          "name",
          "type"
        ]
      },
      "UpdateContainerComponentRequest": {
        "type": "object",
        "description": "Request body for updating a component reference in a container. At least one field must be provided.",
        "properties": {
          "count": {
            "type": "integer",
            "minimum": 1,
            "description": "Updated instance count"
          },
          "group": {
            "type": "string",
            "description": "Updated logical group assignment"
          }
        }
      },
      "UpdateChildComponentRequest": {
        "type": "object",
        "description": "Request body for updating a child component (NIC, GPU, application) on a host. At least one field must be provided.",
        "properties": {
          "count": {
            "type": "integer",
            "minimum": 1,
            "description": "Updated instance count"
          },
          "group": {
            "type": "string",
            "description": "Updated logical group assignment"
          }
        }
      },
      "UpdateTopologyComponentRequest": {
        "type": "object",
        "description": "Request body for updating a topology component reference",
        "properties": {
          "count": {
            "type": "integer",
            "minimum": 1,
            "description": "Updated instance count"
          }
        },
        "required": [
          "count"
        ]
      },
      "AllowedTypesResponse": {
        "type": "object",
        "description": "Response containing allowed component types for a container",
        "properties": {
          "containerName": {
            "type": "string",
            "description": "Name of the container"
          },
          "containerType": {
            "$ref": "#/components/schemas/ContainerType",
            "description": "Container type in the infrastructure hierarchy"
          },
          "allowedComponents": {
            "type": "array",
            "description": "List of allowed component types",
            "items": {
              "type": "string"
            },
            "example": [
              "switch",
              "nic",
              "server",
              "application",
              "layer"
            ]
          }
        },
        "required": [
          "containerName",
          "containerType",
          "allowedComponents"
        ]
      },
      "ConfigurationComponentItem": {
        "type": "object",
        "description": "Component item in configuration components list response",
        "properties": {
          "name": {
            "type": "string",
            "description": "Unique component instance name"
          },
          "type": {
            "$ref": "#/components/schemas/ComponentType"
          },
          "model": {
            "type": "string",
            "description": "Model name in PascalCase (e.g., ScalaSwitch)",
            "example": "ScalaSwitch"
          },
          "version": {
            "type": [
              "string",
              "null"
            ],
            "description": "Model version (e.g., 3.2.1)",
            "example": "3.2.1"
          },
          "typedParameters": {
            "$ref": "#/components/schemas/TypedParameters",
            "description": "Model-specific configuration parameters"
          },
          "container": {
            "type": [
              "string",
              "null"
            ],
            "description": "Name of the container this component belongs to (null if unassigned)"
          }
        },
        "required": [
          "name",
          "type",
          "model"
        ]
      },
      "ConfigurationComponentsListResponse": {
        "type": "object",
        "description": "Response for listing configuration components",
        "properties": {
          "components": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConfigurationComponentItem"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "components",
          "pagination"
        ]
      },
      "ConfigurationContainersListResponse": {
        "type": "object",
        "description": "Response for listing configuration containers",
        "properties": {
          "containers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContainerDefinition"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "containers",
          "pagination"
        ]
      },
      "ConfigurationApplicationsListResponse": {
        "type": "object",
        "description": "Response for listing configuration applications",
        "properties": {
          "applications": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationDefinition"
            }
          }
        },
        "required": [
          "applications"
        ]
      },
      "ConfigurationLinksListResponse": {
        "type": "object",
        "description": "Response for listing configuration links (layer components)",
        "properties": {
          "links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComponentDeclaration"
            }
          }
        },
        "required": [
          "links"
        ]
      },
      "TracesetItem": {
        "type": "object",
        "description": "Traceset item in configuration tracesets list response",
        "properties": {
          "id": {
            "type": "string",
            "description": "Traceset ID (ts_xxxx format)",
            "example": "ts_2RKHfGD5Z8vW9pL3NqM7TjX1YcB"
          },
          "name": {
            "type": "string",
            "description": "Traceset name"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional traceset description"
          },
          "hash": {
            "type": [
              "string",
              "null"
            ],
            "description": "Content hash (crc64nvme format). Null or omitted while ingest is in progress and the library row has not yet been written; clients must treat absence and explicit null as equivalent.",
            "example": "crc64nvme:abc123..."
          },
          "hashShort": {
            "type": [
              "string",
              "null"
            ],
            "description": "Short hash for display (12 Unicode scalar values from the start of `hash`). Null or omitted when `hash` is not yet available; clients must treat absence and explicit null as equivalent.",
            "example": "abc123def456"
          },
          "totalSize": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Total size in bytes. Null or omitted when the library row has not yet been written; clients must treat absence and explicit null as equivalent. Tracesets routinely exceed 2 GB, so this must be int64 (the generator only honors format:int64 with single-type integer + nullable:true, not the type-array form)."
          },
          "format": {
            "description": "Trace format. Null or omitted when the library row has not yet been written; clients must treat absence and explicit null as equivalent. Encoded as `oneOf` with explicit `type:'null'` because `nullable:true` on an enum is silently dropped by the openapi-python-client generator (it emits `Enum(value)` direct construction and crashes on JSON null). The `oneOf` form forces the codegen to emit a None-guarded `_parse_format` helper.",
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "chakra_json_v1",
                  "chakra_protobuf_v1",
                  "chakra_archive_zip"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "description": "Traceset status",
            "enum": [
              "uploading",
              "ready",
              "processing",
              "metadata_failed",
              "upload_failed",
              "deleted"
            ]
          },
          "metadataStatus": {
            "description": "Metadata extraction status. Null or omitted when the library row has not yet been written; clients must treat absence and explicit null as equivalent. Encoded as `oneOf` with explicit `type:'null'` for the same reason as `format` — to force null-safe Python codegen on a nullable enum.",
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "pending",
                  "running",
                  "complete",
                  "failed"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "createdAt",
          "updatedAt"
        ]
      },
      "ConfigurationTracesetsListResponse": {
        "type": "object",
        "description": "Response for listing tracesets available for a configuration",
        "properties": {
          "tracesets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TracesetItem"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "tracesets",
          "pagination"
        ]
      },
      "AttachTracesetRequest": {
        "type": "object",
        "description": "Request to attach a traceset to a configuration. Requires the configuration to have at least one application with trafficType 'chakra'.",
        "properties": {
          "tracesetId": {
            "type": "string",
            "description": "Traceset ID to attach (workspace-agnostic)",
            "example": "ts_2RKHfGD5Z8vW9pL3NqM7TjX1YcB"
          }
        },
        "required": [
          "tracesetId"
        ]
      },
      "AttachTracesetResponse": {
        "type": "object",
        "description": "Response after successfully attaching a traceset to a configuration. Returns the full ActiveTraceset object that was set on the configuration.",
        "properties": {
          "activeTraceset": {
            "$ref": "#/components/schemas/ActiveTraceset",
            "description": "The attached traceset reference containing both name and ID"
          }
        },
        "required": [
          "activeTraceset"
        ]
      },
      "UpdateDistributionValueRequest": {
        "type": "object",
        "description": "Request body for updating a distribution entry value",
        "properties": {
          "parentApplication": {
            "type": "string",
            "description": "Root application name (e.g., ScalaTrafficGeneratorApp)"
          },
          "distributionId": {
            "type": "string",
            "description": "Distribution identifier linking to prClientVariable (e.g., prScalaTrafficServer)"
          },
          "value": {
            "type": "number",
            "format": "double",
            "minimum": 0.0,
            "maximum": 1.0,
            "description": "New distribution percentage value (0.0 to 1.0 inclusive)"
          }
        },
        "required": [
          "parentApplication",
          "distributionId",
          "value"
        ]
      },
      "ActiveTraceset": {
        "type": "object",
        "description": "Active traceset reference for chakra-based simulations. Contains both the name (for human readability and V1 WorkloadName) and ID (for unambiguous identification).",
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable traceset name, used for V1 WorkloadName"
          },
          "id": {
            "type": "string",
            "description": "Unique traceset identifier (format: ts_xxx)"
          }
        },
        "required": [
          "name",
          "id"
        ]
      },
      "SoftwareVersionResponse": {
        "type": "object",
        "required": [
          "version"
        ],
        "properties": {
          "version": {
            "type": "string",
            "description": "Simulator software version (e.g. '4.6.0')"
          }
        }
      },
      "CheckpointingConfig": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "interval": {
            "type": "string"
          }
        }
      },
      "SimulationMetrics": {
        "type": "object",
        "properties": {
          "simulatedTime": {
            "type": "string",
            "description": "Maximum simulated network time reached. Format: '{value} {unit}' where unit is 'us', 'ms', or 's' (e.g., '1.50 ms', '0.42 us', '3.20 s')."
          },
          "eventsProcessed": {
            "type": "integer",
            "format": "int64",
            "description": "Total packets (tx + rx) across all network interfaces at the final simulated timestamp."
          },
          "throughput": {
            "type": "string",
            "description": "Average transmit throughput across all interfaces and timesteps. Format: '{value} Gbps' (e.g., '0.14 Gbps')."
          }
        }
      },
      "ResultFile": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "pcap",
              "csv",
              "json",
              "log",
              "state",
              "unknown"
            ]
          },
          "name": {
            "type": "string",
            "description": "File path relative to the simulation's results prefix. Nested files include their subdirectory (e.g. \"subdir/file.csv\"); top-level files are just the file name. SECURITY: this value can contain '/' and is NOT a safe basename — consumers that write results to the filesystem MUST NOT path-join it onto a destination directory without re-validating (reject '.'/'..' segments, absolute paths). Sanitize to a basename or apply an equivalent relative-path check before any filesystem operation."
          },
          "size": {
            "type": "string"
          },
          "downloadUrl": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "type",
          "name",
          "size",
          "downloadUrl"
        ]
      },
      "LogEntry": {
        "type": "object",
        "properties": {
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "level": {
            "type": "string",
            "enum": [
              "debug",
              "info",
              "warning",
              "error"
            ]
          },
          "component": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "timestamp",
          "level",
          "message"
        ]
      },
      "SimulationDescription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "workspaceId": {
            "type": "string"
          },
          "configurationId": {
            "type": "string"
          },
          "configurationVersion": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "validating",
              "provisioning",
              "running",
              "completed",
              "failed",
              "terminated",
              "invalid"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "workspaceId",
          "configurationId",
          "configurationVersion",
          "name",
          "status",
          "createdAt"
        ]
      },
      "SimulationDetails": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "workspaceId": {
            "type": "string"
          },
          "configurationId": {
            "type": "string"
          },
          "configurationVersion": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "validating",
              "provisioning",
              "running",
              "completed",
              "failed",
              "terminated",
              "invalid"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time"
          },
          "failureReason": {
            "type": "string",
            "description": "Reason the simulation failed. Only present when status is 'failed'."
          },
          "terminationRequestedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When a termination of this simulation was requested. Present once a request has been accepted for a simulation whose run had started; the status keeps reading 'running' while the run's output is collected, and becomes 'terminated' when it settles. Absent for a simulation nobody asked to terminate, and for one terminated before its run began."
          },
          "metrics": {
            "description": "Simulation metrics computed from nd-stats output. Only present for terminal simulations that produced simulation results. Null means either the simulation did not produce results (e.g., failed before running) or results are still being exported. Check the simulation status and startedAt field to distinguish.",
            "$ref": "#/components/schemas/SimulationMetrics"
          },
          "transportStats": {
            "type": "array",
            "description": "Transport protocols the simulation's pinned configuration declares a NIC for with that protocol's statistics enabled, derived from that configuration rather than from any produced output. This is the DECLARED set, which is an upper bound on what the run recorded: a NIC the configuration declares but the topology never instantiates produces no NIC and therefore no file, so a protocol listed here can still yield no data for its projection. A set rather than a single value: the two enable settings are independent, so a configuration can declare both, one, or neither. An empty array means neither protocol is declared, which is distinct from the field being absent - absent means the answer could not be derived, for example on a record whose configuration is no longer readable.",
            "items": {
              "$ref": "#/components/schemas/TransportProtocol"
            }
          },
          "networkTiers": {
            "type": "array",
            "description": "Network tiers the simulation's pinned configuration places, derived from that configuration's component tree rather than from any produced output, listed top-down. A switch the topology references is a spine switch (ssw), a switch in a pod or rack the topology references directly is a fabric switch (fsw), and a switch in a rack a pod references is a rack switch (rsw); a reference is classified by the declaration its name resolves to, and a reference with a count of 0 places nothing. The topologyTiers count is not read. The nic tier is always listed. A tree the walk cannot classify, such as one with a reference that resolves to nothing and carries no known type, or a container other than a pod or rack, lists every tier. Present exactly when transportStats is present, because both are derived from one read of the configuration; absent means the answer could not be derived, for example on a record whose configuration is no longer readable.",
            "items": {
              "$ref": "#/components/schemas/NetworkTierName"
            }
          },
          "appliedMappingFile": {
            "description": "Chakra mapping file this simulation was created with, recorded at creation. Absent when the configuration had no mapping file attached. Resolved whether or not the mapping file has since been deleted, so a simulation keeps naming the mapping it was created with; `deleted` reports that state.",
            "$ref": "#/components/schemas/ActiveMappingFileRef"
          }
        },
        "required": [
          "id",
          "workspaceId",
          "configurationId",
          "configurationVersion",
          "name",
          "status",
          "createdAt"
        ]
      },
      "SimulationRequest": {
        "type": "object",
        "properties": {
          "workspaceId": {
            "type": "string"
          },
          "configurationId": {
            "type": "string"
          },
          "configurationVersion": {
            "type": "integer"
          },
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,254}$",
            "maxLength": 255,
            "description": "Simulation name. SECURITY: this value is interpolated into command strings and Slurm entrypoints executed on cluster nodes, so it is restricted to letters, digits, '-' and '_' (1–255 characters), and must start with a letter or digit (no whitespace, other punctuation, or non-ASCII characters, and no leading '-' or '_')."
          },
          "duration": {
            "type": "string"
          },
          "checkpointing": {
            "$ref": "#/components/schemas/CheckpointingConfig"
          }
        },
        "required": [
          "configurationId",
          "name",
          "duration"
        ]
      },
      "SimulationResults": {
        "type": "object",
        "properties": {
          "simulationId": {
            "type": "string"
          },
          "duration": {
            "type": "string"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResultFile"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "simulationId",
          "duration",
          "pagination"
        ]
      },
      "LogsListResponse": {
        "type": "object",
        "properties": {
          "logs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LogEntry"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "logs",
          "pagination"
        ]
      },
      "SimulationsListResponse": {
        "type": "object",
        "properties": {
          "simulations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SimulationDescription"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "simulations",
          "pagination"
        ]
      },
      "SimulationDeleteResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "status",
          "message"
        ]
      },
      "FileDownloadUrlResponse": {
        "type": "object",
        "description": "Response containing a presigned download URL for a simulation result file",
        "properties": {
          "simulationId": {
            "type": "string",
            "description": "Simulation ID in sim_xxx format"
          },
          "fileName": {
            "type": "string",
            "description": "Path of the result file relative to the simulation's results prefix; nested files include their subdirectory (e.g. \"subdir/file.csv\"). Echoes the requested fileName. SECURITY: this value can contain '/' and is NOT a safe basename — consumers that write to the filesystem MUST re-validate (reject '.'/'..' segments, absolute paths) or sanitize to a basename before path-joining."
          },
          "contentType": {
            "type": "string",
            "description": "MIME type of the file"
          },
          "sizeBytes": {
            "type": "integer",
            "format": "int64",
            "description": "File size in bytes"
          },
          "checksum": {
            "type": "string",
            "description": "Algorithm-tagged checksum of the file (e.g. `md5:<hex>`, `crc64nvme:<base64url>`). Omitted when no verifiable whole-file checksum is available (multipart uploads without CRC64NVME, SSE-KMS/SSE-C objects). Integrity only — not a cryptographic authenticity mechanism."
          },
          "downloadUrl": {
            "type": "string",
            "format": "uri",
            "description": "Presigned S3 URL for downloading the file"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "Expiration time of the presigned URL (15 minutes from generation)"
          }
        },
        "required": [
          "simulationId",
          "fileName",
          "contentType",
          "sizeBytes",
          "downloadUrl",
          "expiresAt"
        ]
      },
      "SummaryResponse": {
        "type": "object",
        "description": "Response containing computed summary data for simulation results with a presigned download URL for the zstd-compressed JSON summary",
        "properties": {
          "simulationId": {
            "type": "string",
            "description": "Simulation ID"
          },
          "metric": {
            "type": "string",
            "description": "Metric type that was summarized",
            "enum": [
              "nd-stats",
              "perf",
              "pfc",
              "ranks",
              "chakra-perf",
              "collectives",
              "cdf",
              "uet-transport-stats",
              "roce-transport-stats",
              "scala-switch-agg-buff-stats"
            ]
          },
          "mode": {
            "type": "string",
            "description": "Output mode used: summary for the summary document, timeSeries for the time-series envelope, utilizationBins for the utilization-bins document, uplinkFairness for the uplink-fairness document, completionTimeBins for the completion-time-bins document.",
            "enum": [
              "summary",
              "timeSeries",
              "utilizationBins",
              "uplinkFairness",
              "completionTimeBins"
            ]
          },
          "tier": {
            "type": "string",
            "description": "Tier filter applied",
            "enum": [
              "all",
              "ssw",
              "fsw",
              "rsw",
              "nic"
            ]
          },
          "file": {
            "$ref": "#/components/schemas/SummaryFileInfo"
          },
          "metadata": {
            "$ref": "#/components/schemas/SummaryMetadata"
          }
        },
        "required": [
          "simulationId",
          "metric",
          "mode",
          "tier",
          "file",
          "metadata"
        ]
      },
      "SummaryFileInfo": {
        "type": "object",
        "description": "File information with presigned download URL for the summary data",
        "properties": {
          "name": {
            "type": "string",
            "description": "File name of the summary"
          },
          "size": {
            "type": "integer",
            "format": "int64",
            "description": "File size in bytes"
          },
          "contentType": {
            "type": "string",
            "description": "MIME type of the file (application/zstd)"
          },
          "downloadUrl": {
            "type": "string",
            "format": "uri",
            "description": "Presigned S3 URL for downloading the summary file"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "Expiration time of the presigned URL"
          }
        },
        "required": [
          "name",
          "size",
          "contentType",
          "downloadUrl",
          "expiresAt"
        ]
      },
      "SummaryMetadata": {
        "type": "object",
        "description": "Metadata about the summary computation",
        "properties": {
          "cached": {
            "type": "boolean",
            "description": "Whether this summary was served from cache"
          },
          "computedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the persisted summary object was written, from its S3 Last-Modified timestamp. Populated on both cache hits and fresh computes when the persisted object reports a Last-Modified value; omitted otherwise."
          },
          "rowsProcessed": {
            "type": "integer",
            "format": "int64",
            "description": "Number of CSV rows processed (omitted if cached or zero)"
          },
          "computeTimeMs": {
            "type": "integer",
            "format": "int64",
            "description": "Time taken to compute in milliseconds (omitted if cached or zero)"
          }
        },
        "required": [
          "cached"
        ]
      },
      "NicType": {
        "type": "string",
        "description": "NIC class a time series can be filtered to.",
        "enum": [
          "scaleUp",
          "scaleOut"
        ]
      },
      "NetworkTierName": {
        "type": "string",
        "description": "A network tier: spine, fabric and rack switches, and NICs. The values are the tier names the results tier filter accepts.",
        "enum": [
          "ssw",
          "fsw",
          "rsw",
          "nic"
        ]
      },
      "TransportProtocol": {
        "type": "string",
        "description": "A transport protocol whose per-NIC statistics a simulation records. The values are the protocol halves of the two transport metric tokens.",
        "enum": [
          "uet",
          "roce"
        ]
      },
      "CompareSimulationsRequest": {
        "type": "object",
        "description": "Request body for the simulation comparison endpoint.",
        "properties": {
          "simulationIds": {
            "type": "array",
            "minItems": 2,
            "maxItems": 4,
            "items": {
              "type": "string",
              "pattern": "^sim_[0-9A-Za-z]{27}$"
            }
          },
          "tier": {
            "type": "string",
            "enum": [
              "all",
              "ssw",
              "fsw",
              "rsw",
              "nic"
            ]
          }
        },
        "required": [
          "simulationIds",
          "tier"
        ]
      },
      "ComparisonResult": {
        "type": "object",
        "description": "Aligned summaries, per-metric deltas and diff context for a set of compared simulations.",
        "properties": {
          "simulations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AlignedSummary"
            }
          },
          "deltas": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MetricDelta"
            }
          },
          "diffContext": {
            "$ref": "#/components/schemas/DiffContext"
          },
          "confidence": {
            "$ref": "#/components/schemas/ComparisonConfidence"
          }
        },
        "required": [
          "simulations",
          "deltas",
          "diffContext",
          "confidence"
        ]
      },
      "SimulationSummary": {
        "type": "object",
        "description": "Full summary statistics computed from simulation output. Exactly the projections the requested metric produced are present; the other projection properties are omitted rather than sent as null.",
        "additionalProperties": false,
        "properties": {
          "simulationId": {
            "type": "string",
            "description": "Simulation identifier."
          },
          "metric": {
            "type": "string",
            "description": "Metric type that was summarized."
          },
          "tier": {
            "type": "string",
            "description": "Tier filter applied (or \"all\")."
          },
          "network": {
            "description": "Network statistics (for the nd-stats metric). Omitted when the summary carries no network projection.",
            "$ref": "#/components/schemas/NetworkSummary"
          },
          "performance": {
            "description": "Performance statistics (for the perf metric). Omitted when the summary carries no performance projection.",
            "$ref": "#/components/schemas/PerformanceSummary"
          },
          "pfc": {
            "description": "PFC statistics (for the pfc metric). Omitted when the summary carries no PFC projection.",
            "$ref": "#/components/schemas/PfcSummary"
          },
          "ranks": {
            "description": "Ranks projection (for the ranks metric). Omitted when the summary carries no ranks projection.",
            "$ref": "#/components/schemas/RanksProjection"
          },
          "collectives": {
            "description": "Collectives projection (for the collectives metric). Omitted when the summary carries no collectives projection.",
            "$ref": "#/components/schemas/CollectivesProjection"
          },
          "cdf": {
            "description": "CDF projection (for the cdf metric). Omitted when the summary carries no CDF projection.",
            "$ref": "#/components/schemas/CdfProjection"
          },
          "transport": {
            "description": "Whole-run transport statistics (for the uet-transport-stats and roce-transport-stats metrics). Omitted when the summary carries no transport projection.",
            "$ref": "#/components/schemas/TransportSummary"
          },
          "bufferPools": {
            "description": "Aggregate switch buffer pool statistics (for the scala-switch-agg-buff-stats metric). Omitted when the summary carries no buffer pool projection.",
            "$ref": "#/components/schemas/BufferPoolSummary"
          },
          "computedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this summary was computed."
          },
          "sourceFiles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Source files that were processed."
          },
          "totalRowsProcessed": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Total rows processed across all files."
          }
        },
        "required": [
          "simulationId",
          "metric",
          "tier",
          "computedAt",
          "sourceFiles",
          "totalRowsProcessed"
        ]
      },
      "NetworkSummary": {
        "type": "object",
        "description": "Network device statistics summary.",
        "additionalProperties": false,
        "properties": {
          "totalPacketsTx": {
            "type": "integer",
            "format": "int64",
            "description": "Total packets transmitted."
          },
          "totalPacketsRx": {
            "type": "integer",
            "format": "int64",
            "description": "Total packets received."
          },
          "totalPackets": {
            "type": "integer",
            "format": "int64",
            "description": "Total packets (tx + rx)."
          },
          "totalBytesTxGb": {
            "type": "number",
            "format": "double",
            "description": "Total bytes transmitted (GB)."
          },
          "totalBytesRxGb": {
            "type": "number",
            "format": "double",
            "description": "Total bytes received (GB)."
          },
          "totalTxDrops": {
            "type": "integer",
            "format": "int64",
            "description": "Total TX drops."
          },
          "totalRxDrops": {
            "type": "integer",
            "format": "int64",
            "description": "Total RX drops."
          },
          "dropRate": {
            "type": "number",
            "format": "double",
            "description": "Drop rate: (totalTxDrops + totalRxDrops) / totalPackets."
          },
          "throughput": {
            "description": "Throughput statistics.",
            "$ref": "#/components/schemas/ThroughputStats"
          },
          "linkUtilization": {
            "description": "Link utilization statistics.",
            "$ref": "#/components/schemas/UtilizationStats"
          },
          "linkCapacityGbps": {
            "type": [
              "number",
              "null"
            ],
            "format": "double",
            "description": "Estimated link capacity (Gbps): an estimate of the fastest per-link line rate in the run, derived link-consistently as the max over samples of rate / (utilization / 100) where 0 < utilization <= 100. Null when no sample carried an in-range utilization (an all-idle run). Always present."
          },
          "simTimeSec": {
            "type": [
              "number",
              "null"
            ],
            "format": "double",
            "description": "Maximum simulated time reached (seconds). Null for summaries computed before this field was added. Always present."
          },
          "byTier": {
            "description": "Per-tier breakdown (when tier=all). Omitted when the summary carries no per-tier breakdown.",
            "$ref": "#/components/schemas/TierSummaryMap"
          }
        },
        "required": [
          "totalPacketsTx",
          "totalPacketsRx",
          "totalPackets",
          "totalBytesTxGb",
          "totalBytesRxGb",
          "totalTxDrops",
          "totalRxDrops",
          "dropRate",
          "throughput",
          "linkUtilization",
          "linkCapacityGbps",
          "simTimeSec"
        ]
      },
      "TierSummaryMap": {
        "type": "object",
        "description": "Tier name to that tier's summary statistics.",
        "additionalProperties": {
          "$ref": "#/components/schemas/TierSummary"
        }
      },
      "TierSummary": {
        "type": "object",
        "description": "Per-tier summary statistics.",
        "additionalProperties": false,
        "properties": {
          "tier": {
            "type": "string",
            "description": "Tier name."
          },
          "totalPackets": {
            "type": "integer",
            "format": "int64",
            "description": "Total packets for this tier."
          },
          "totalDrops": {
            "type": "integer",
            "format": "int64",
            "description": "Total drops for this tier."
          },
          "dropRate": {
            "type": "number",
            "format": "double",
            "description": "Drop rate for this tier."
          },
          "throughput": {
            "description": "Throughput statistics for this tier.",
            "$ref": "#/components/schemas/ThroughputStats"
          }
        },
        "required": [
          "tier",
          "totalPackets",
          "totalDrops",
          "dropRate",
          "throughput"
        ]
      },
      "ThroughputStats": {
        "type": "object",
        "description": "Throughput statistics in Gbps.",
        "additionalProperties": false,
        "properties": {
          "avgGbps": {
            "type": "number",
            "format": "double",
            "description": "Average throughput (Gbps)."
          },
          "maxGbps": {
            "type": "number",
            "format": "double",
            "description": "Maximum throughput (Gbps)."
          },
          "minGbps": {
            "type": "number",
            "format": "double",
            "description": "Minimum throughput (Gbps)."
          },
          "p50Gbps": {
            "type": "number",
            "format": "double",
            "description": "50th percentile (median) throughput."
          },
          "p95Gbps": {
            "type": "number",
            "format": "double",
            "description": "95th percentile throughput."
          },
          "p99Gbps": {
            "type": "number",
            "format": "double",
            "description": "99th percentile throughput."
          }
        },
        "required": [
          "avgGbps",
          "maxGbps",
          "minGbps",
          "p50Gbps",
          "p95Gbps",
          "p99Gbps"
        ]
      },
      "UtilizationStats": {
        "type": "object",
        "description": "Link utilization statistics (percentage).",
        "additionalProperties": false,
        "properties": {
          "avgPercent": {
            "type": "number",
            "format": "double",
            "description": "Average utilization (0-100)."
          },
          "maxPercent": {
            "type": "number",
            "format": "double",
            "description": "Maximum utilization (0-100)."
          },
          "p95Percent": {
            "type": "number",
            "format": "double",
            "description": "95th percentile utilization."
          },
          "p99Percent": {
            "type": "number",
            "format": "double",
            "description": "99th percentile utilization."
          }
        },
        "required": [
          "avgPercent",
          "maxPercent",
          "p95Percent",
          "p99Percent"
        ]
      },
      "PerformanceSummary": {
        "type": "object",
        "description": "Performance/latency statistics summary.",
        "additionalProperties": false,
        "properties": {
          "count": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Number of samples."
          },
          "avgLatencyUsec": {
            "type": "number",
            "format": "double",
            "description": "Average latency (microseconds)."
          },
          "p50LatencyUsec": {
            "type": "number",
            "format": "double",
            "description": "50th percentile latency (microseconds)."
          },
          "p95LatencyUsec": {
            "type": "number",
            "format": "double",
            "description": "95th percentile latency (microseconds)."
          },
          "p99LatencyUsec": {
            "type": "number",
            "format": "double",
            "description": "99th percentile latency (microseconds)."
          },
          "p999LatencyUsec": {
            "type": "number",
            "format": "double",
            "description": "99.9th percentile latency (microseconds)."
          },
          "maxLatencyUsec": {
            "type": "number",
            "format": "double",
            "description": "Maximum latency (microseconds)."
          },
          "avgLatencyFormatted": {
            "type": "string",
            "description": "Formatted average latency string (e.g., \"1.234ms\")."
          },
          "byMetric": {
            "description": "Per-metric breakdown. Omitted when the summary carries no per-metric breakdown.",
            "$ref": "#/components/schemas/MetricPercentilesMap"
          }
        },
        "required": [
          "count",
          "avgLatencyUsec",
          "p50LatencyUsec",
          "p95LatencyUsec",
          "p99LatencyUsec",
          "p999LatencyUsec",
          "maxLatencyUsec",
          "avgLatencyFormatted"
        ]
      },
      "MetricPercentilesMap": {
        "type": "object",
        "description": "Metric name to that metric's percentile statistics.",
        "additionalProperties": {
          "$ref": "#/components/schemas/MetricPercentiles"
        }
      },
      "MetricPercentiles": {
        "type": "object",
        "description": "Percentile statistics for a specific metric.",
        "additionalProperties": false,
        "properties": {
          "metricName": {
            "type": "string",
            "description": "Metric name."
          },
          "count": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Number of samples."
          },
          "average": {
            "type": "number",
            "format": "double",
            "description": "Average value (microseconds)."
          },
          "p50": {
            "type": "number",
            "format": "double",
            "description": "50th percentile."
          },
          "p95": {
            "type": "number",
            "format": "double",
            "description": "95th percentile."
          },
          "p99": {
            "type": "number",
            "format": "double",
            "description": "99th percentile."
          },
          "p999": {
            "type": "number",
            "format": "double",
            "description": "99.9th percentile."
          },
          "p100": {
            "type": "number",
            "format": "double",
            "description": "Maximum value."
          },
          "unit": {
            "type": "string",
            "description": "Unit of measurement."
          }
        },
        "required": [
          "metricName",
          "count",
          "average",
          "p50",
          "p95",
          "p99",
          "p999",
          "p100",
          "unit"
        ]
      },
      "PfcSummary": {
        "type": "object",
        "description": "PFC (Priority Flow Control) statistics summary.",
        "additionalProperties": false,
        "properties": {
          "totalXoffRx": {
            "type": "integer",
            "format": "int64",
            "description": "Total XOFF received."
          },
          "totalXoffTx": {
            "type": "integer",
            "format": "int64",
            "description": "Total XOFF transmitted."
          },
          "totalXonRx": {
            "type": "integer",
            "format": "int64",
            "description": "Total XON received."
          },
          "totalXonTx": {
            "type": "integer",
            "format": "int64",
            "description": "Total XON transmitted."
          },
          "totalTimePausedUsec": {
            "type": "number",
            "format": "double",
            "description": "Total time paused (fractional microseconds)."
          },
          "byTier": {
            "description": "Per-tier breakdown. Omitted when the summary carries no per-tier breakdown.",
            "$ref": "#/components/schemas/PfcTierSummaryMap"
          }
        },
        "required": [
          "totalXoffRx",
          "totalXoffTx",
          "totalXonRx",
          "totalXonTx",
          "totalTimePausedUsec"
        ]
      },
      "PfcTierSummaryMap": {
        "type": "object",
        "description": "Tier name to that tier's PFC statistics.",
        "additionalProperties": {
          "$ref": "#/components/schemas/PfcTierSummary"
        }
      },
      "PfcTierSummary": {
        "type": "object",
        "description": "Per-tier PFC statistics.",
        "additionalProperties": false,
        "properties": {
          "tier": {
            "type": "string",
            "description": "Tier name."
          },
          "direction": {
            "type": "string",
            "description": "Direction (ul/dl)."
          },
          "xoffRx": {
            "type": "integer",
            "format": "int64",
            "description": "Total XOFF received."
          },
          "xoffTx": {
            "type": "integer",
            "format": "int64",
            "description": "Total XOFF transmitted."
          },
          "xonRx": {
            "type": "integer",
            "format": "int64",
            "description": "Total XON received."
          },
          "xonTx": {
            "type": "integer",
            "format": "int64",
            "description": "Total XON transmitted."
          },
          "timePausedUsec": {
            "type": "number",
            "format": "double",
            "description": "Time paused (fractional microseconds)."
          }
        },
        "required": [
          "tier",
          "direction",
          "xoffRx",
          "xoffTx",
          "xonRx",
          "xonTx",
          "timePausedUsec"
        ]
      },
      "RanksProjection": {
        "type": "object",
        "description": "Per-rank completion statistics. Unlike the network, performance and PFC summaries, which aggregate into statistics, this is a projection: one record per rank preserving the raw completion data.",
        "additionalProperties": false,
        "properties": {
          "rankCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Number of ranks in this projection."
          },
          "ranks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RankRecord"
            },
            "description": "Per-rank completion records, ordered by rankId ascending."
          },
          "p99CompletionTimeUs": {
            "type": "number",
            "format": "double",
            "minimum": 0,
            "description": "99th percentile of ranks[].completionTimeUs across ranks, computed server-side with the same interpolation method as PerformanceSummary.p99LatencyUsec. Absent when there are no ranks (a percentile over the empty set is undefined)."
          }
        },
        "required": [
          "rankCount",
          "ranks"
        ]
      },
      "RankRecord": {
        "type": "object",
        "description": "Completion statistics for a single rank.",
        "additionalProperties": false,
        "properties": {
          "rankId": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Rank identifier (chakra_app_logical_id from CSV)."
          },
          "completionTimeUs": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Time in microseconds from simulation start to trace completion."
          },
          "bytesSent": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Total bytes sent by this rank."
          },
          "bytesRecv": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Total bytes received by this rank."
          },
          "sendsCompleted": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Number of send operations completed."
          },
          "sendsAcked": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Number of send operations fully acknowledged by receiver."
          },
          "receivesCompleted": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Number of receive operations completed."
          },
          "computationsCompleted": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Number of compute operations completed."
          },
          "computationTimeUs": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Total computation time in microseconds."
          }
        },
        "required": [
          "rankId",
          "completionTimeUs",
          "bytesSent",
          "bytesRecv",
          "sendsCompleted",
          "sendsAcked",
          "receivesCompleted",
          "computationsCompleted",
          "computationTimeUs"
        ]
      },
      "CollectivesProjection": {
        "type": "object",
        "description": "Collective operation percentile statistics.",
        "additionalProperties": false,
        "properties": {
          "collectiveCount": {
            "type": "integer",
            "format": "int32",
            "minimum": 0,
            "description": "Number of collective operation entries."
          },
          "collectives": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CollectiveRecord"
            },
            "description": "Per-collective records sorted by (commType, expansionAlgo, commSize, pgSize)."
          }
        },
        "required": [
          "collectiveCount",
          "collectives"
        ]
      },
      "CollectiveRecord": {
        "type": "object",
        "description": "Statistics for a single collective operation type.",
        "additionalProperties": false,
        "properties": {
          "commType": {
            "type": "string"
          },
          "expansionAlgo": {
            "type": "string"
          },
          "commSize": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "pgSize": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "count": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "meanRunTimeUs": {
            "type": "number",
            "format": "double"
          },
          "p50RunTimeUs": {
            "type": "number",
            "format": "double"
          },
          "p99RunTimeUs": {
            "type": "number",
            "format": "double"
          },
          "p999RunTimeUs": {
            "type": "number",
            "format": "double"
          },
          "p100RunTimeUs": {
            "type": "number",
            "format": "double"
          },
          "meanIdealRatio": {
            "type": "number",
            "format": "double"
          },
          "p50IdealRatio": {
            "type": "number",
            "format": "double"
          },
          "p99IdealRatio": {
            "type": "number",
            "format": "double"
          },
          "p999IdealRatio": {
            "type": "number",
            "format": "double"
          },
          "p100IdealRatio": {
            "type": "number",
            "format": "double"
          }
        },
        "required": [
          "commType",
          "expansionAlgo",
          "commSize",
          "pgSize",
          "count",
          "meanRunTimeUs",
          "p50RunTimeUs",
          "p99RunTimeUs",
          "p999RunTimeUs",
          "p100RunTimeUs",
          "meanIdealRatio",
          "p50IdealRatio",
          "p99IdealRatio",
          "p999IdealRatio",
          "p100IdealRatio"
        ]
      },
      "CdfProjection": {
        "type": "object",
        "description": "CDF workload progress over simulation time.",
        "additionalProperties": false,
        "properties": {
          "sampleCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Number of time samples."
          },
          "series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CdfSample"
            },
            "description": "CDF series data sorted by simTimeSec ascending."
          }
        },
        "required": [
          "sampleCount",
          "series"
        ]
      },
      "CdfSample": {
        "type": "object",
        "description": "A single CDF time sample with progress fractions in [0, 1].",
        "additionalProperties": false,
        "properties": {
          "simTimeSec": {
            "type": "number",
            "format": "double"
          },
          "sendBytes": {
            "type": "number",
            "format": "double",
            "description": "CDF fraction of send bytes completed [0.0, 1.0] — not a raw byte count. Named after the source CSV column CDF_send_bytes."
          },
          "sendsCompleted": {
            "type": "number",
            "format": "double",
            "description": "CDF fraction of send operations completed [0.0, 1.0]."
          },
          "receivesCompleted": {
            "type": "number",
            "format": "double",
            "description": "CDF fraction of receive operations completed [0.0, 1.0]."
          },
          "sendsAcked": {
            "type": "number",
            "format": "double",
            "description": "CDF fraction of send operations fully acknowledged [0.0, 1.0]."
          },
          "computationsCompleted": {
            "type": "number",
            "format": "double",
            "description": "CDF fraction of compute operations completed [0.0, 1.0]."
          }
        },
        "required": [
          "simTimeSec",
          "sendBytes",
          "sendsCompleted",
          "receivesCompleted",
          "sendsAcked",
          "computationsCompleted"
        ]
      },
      "TransportSummary": {
        "type": "object",
        "description": "Whole-run transport statistics: one cross-NIC aggregate per whole-run column of the writer's row, reduced over each NIC's final row, and on RoCE one more, numPktsRcvdSum, the received-packet total the service sums from the writer's seven per-type received counters (connection packets, ACKs, SACKs, NACKs, writes, sends and CNPs), because the RoCE writer records no received total. Counters are summed, maxima maxed, minima minned, and means averaged unweighted over NICs, an idle NIC's 0.0 included.",
        "additionalProperties": false,
        "properties": {
          "nicCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "NICs the aggregates reduce. 0 on a switch tier, where the transport writers have no rows."
          },
          "columns": {
            "$ref": "#/components/schemas/TransportSummaryColumnMap"
          }
        },
        "required": [
          "nicCount",
          "columns"
        ]
      },
      "TransportSummaryColumnMap": {
        "type": "object",
        "description": "Whole-run output column name to its cross-NIC aggregate. Keys are emitted in ascending lexicographic order; the map is empty exactly when nicCount is 0.",
        "additionalProperties": {
          "type": "number",
          "format": "double"
        }
      },
      "BufferPoolSummary": {
        "type": "object",
        "description": "Aggregate switch buffer pool statistics.",
        "additionalProperties": false,
        "properties": {
          "pools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BufferPoolStats"
            },
            "description": "Pool groups sorted by tier, buffer class, direction and pool number."
          }
        },
        "required": [
          "pools"
        ]
      },
      "BufferPoolStats": {
        "type": "object",
        "description": "Statistics over rows for one tier, buffer class, direction and pool.",
        "additionalProperties": false,
        "properties": {
          "tier": {
            "type": "string",
            "description": "Network tier name."
          },
          "bufferClass": {
            "$ref": "#/components/schemas/BufferClass",
            "description": "Buffer class emitted by the switch writer."
          },
          "direction": {
            "$ref": "#/components/schemas/BufferDirection",
            "description": "Uplink or downlink; omitted for shared buffers."
          },
          "pool": {
            "type": "integer",
            "format": "int64",
            "description": "Pool number."
          },
          "peakBytes": {
            "type": "integer",
            "format": "int64",
            "description": "Maximum interval peak occupancy, bytes."
          },
          "minBytes": {
            "type": "integer",
            "format": "int64",
            "description": "Minimum interval occupancy, bytes."
          },
          "meanBytes": {
            "type": "number",
            "format": "double",
            "description": "Arithmetic mean of interval mean occupancy, bytes."
          },
          "peakUtilPct": {
            "type": "number",
            "format": "double",
            "description": "Maximum interval peak utilization, percent of the pool's buffer limit, computed from bytes and not clamped; a lossless egress pool can exceed 100."
          },
          "meanUtilPct": {
            "type": "number",
            "format": "double",
            "description": "Arithmetic mean interval utilization, percent of the pool's buffer limit, computed from bytes and not clamped; a lossless egress pool can exceed 100."
          },
          "bufferLimitBytes": {
            "type": "integer",
            "format": "int64",
            "description": "Maximum buffer limit, bytes."
          },
          "switchCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Number of distinct switch component names."
          },
          "rowCount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Number of source rows in the pool group."
          }
        },
        "required": [
          "tier",
          "bufferClass",
          "pool",
          "peakBytes",
          "minBytes",
          "meanBytes",
          "peakUtilPct",
          "meanUtilPct",
          "bufferLimitBytes",
          "switchCount",
          "rowCount"
        ]
      },
      "BufferClass": {
        "type": "string",
        "description": "Aggregate switch buffer class.",
        "enum": [
          "sharedBuffer",
          "ingressUsage",
          "egressQueue"
        ]
      },
      "BufferDirection": {
        "type": "string",
        "description": "Direction of an ingress or egress pool.",
        "enum": [
          "ul",
          "dl"
        ]
      },
      "AlignedSummaryMap": {
        "type": "object",
        "description": "Metric wire value (kebab-case) to that simulation's summary for that metric.",
        "additionalProperties": {
          "$ref": "#/components/schemas/SimulationSummary"
        }
      },
      "AlignedSummary": {
        "type": "object",
        "description": "One compared simulation's summaries, keyed by metric.",
        "properties": {
          "simulationId": {
            "type": "string"
          },
          "summaryByMetric": {
            "$ref": "#/components/schemas/AlignedSummaryMap"
          }
        },
        "required": [
          "simulationId",
          "summaryByMetric"
        ]
      },
      "DiffContext": {
        "type": "object",
        "description": "Which configuration parameters differ across the compared simulations and which are held constant.",
        "properties": {
          "changedParams": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChangedParam"
            }
          },
          "heldConstant": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "changedParams",
          "heldConstant"
        ]
      },
      "ChangedParam": {
        "type": "object",
        "description": "A single configuration parameter whose value differs between the baseline simulation and the comparison simulations.",
        "properties": {
          "path": {
            "type": "string",
            "description": "Path to the parameter within the configuration."
          },
          "baselineValue": {
            "description": "The baseline simulation's value for this parameter. Any JSON value."
          },
          "comparisonValues": {
            "type": "array",
            "items": {
              "description": "One comparison simulation's value for this parameter, positionally aligned with the request's simulationIds after the baseline. Any JSON value."
            }
          }
        },
        "required": [
          "path",
          "baselineValue",
          "comparisonValues"
        ]
      },
      "ComparisonConfidence": {
        "type": "string",
        "description": "How attributable the observed deltas are: exactly one changed parameter, several changed parameters, or configurations too dissimilar to compare.",
        "enum": [
          "singleChange",
          "multipleChanges",
          "incomparable"
        ]
      },
      "MetricDelta": {
        "type": "object",
        "description": "One metric field's baseline value alongside each comparison simulation's value and percent change.",
        "properties": {
          "metric": {
            "type": "string",
            "enum": [
              "nd-stats",
              "perf",
              "pfc",
              "ranks",
              "chakra-perf",
              "collectives",
              "cdf",
              "rank-analysis"
            ]
          },
          "fieldPath": {
            "type": "string",
            "description": "Path to the field within that metric's summary."
          },
          "baseline": {
            "type": [
              "number",
              "null"
            ],
            "format": "double"
          },
          "comparisonValues": {
            "type": "array",
            "items": {
              "type": [
                "number",
                "null"
              ],
              "format": "double"
            },
            "description": "Positionally aligned with the request's simulationIds after the baseline."
          },
          "percentChange": {
            "type": "array",
            "items": {
              "type": [
                "number",
                "null"
              ],
              "format": "double"
            },
            "description": "Percent change of each comparison value against the baseline, positionally aligned with comparisonValues."
          }
        },
        "required": [
          "metric",
          "fieldPath",
          "baseline",
          "comparisonValues",
          "percentChange"
        ]
      },
      "WorkspaceStats": {
        "type": "object",
        "properties": {
          "configurationCount": {
            "type": "integer"
          },
          "simulationCount": {
            "type": "integer"
          },
          "activeSimulations": {
            "type": "integer"
          }
        }
      },
      "WorkspaceDescription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "owner": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "owner",
          "createdAt",
          "modifiedAt"
        ]
      },
      "WorkspaceDetails": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "owner": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "stats": {
            "$ref": "#/components/schemas/WorkspaceStats"
          }
        },
        "required": [
          "id",
          "name",
          "owner",
          "createdAt",
          "modifiedAt",
          "stats"
        ]
      },
      "WorkspacesListResponse": {
        "type": "object",
        "properties": {
          "workspaces": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkspaceDescription"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "workspaces",
          "pagination"
        ]
      },
      "TracesetSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "uploading",
              "processing",
              "ready",
              "metadata_failed",
              "upload_failed",
              "deleted"
            ]
          },
          "fileCount": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "fileCount",
          "createdAt"
        ]
      },
      "TracesetPagination": {
        "type": "object",
        "description": "Cursor-based pagination for trace-service list endpoints.",
        "properties": {
          "count": {
            "type": "integer"
          },
          "hasMore": {
            "type": "boolean"
          },
          "nextCursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "count",
          "hasMore"
        ]
      },
      "TracesetListResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TracesetSummary"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/TracesetPagination"
          }
        },
        "required": [
          "items",
          "pagination"
        ]
      },
      "WorkloadMetadata": {
        "type": "object",
        "description": "Workload characterization metadata. On a traceset it is returned as stored: the object given at upload, or at the traceset's latest applied promotion that carried metadata. Upload accepts any JSON object and validates only the members UploadWorkloadMetadata describes. Promotion (the Python client's `promote_traceset`) applies its own validation, which this schema does not describe in full. Its member checks read the whole object, the one it is given or else the stored one, through a typed model whose members are spelled in snake_case, so a member that upload stored without checking can make promotion fail; among them, it requires `workload_family` and `workload_name` and checks several members against allowed values. Those checks also read `shape.rank_count` and refuse one that differs from the parallelism product. Separately, its guard against changing the declared rank count reads new metadata as upload does, through camelCase `shape.rankCount` and the parallelism degrees, where a `shape.rank_count` does not count as a declaration; it can refuse new metadata whose declaration is invalid or differs from the count the traceset holds, even when it holds none."
      },
      "UploadWorkloadMetadata": {
        "type": "object",
        "description": "Workload characterization metadata given at upload. This schema describes the members that declare the traceset's rank count, and they are the only members upload validates. Every member is optional, and the object may carry other members, which are stored and returned as given. Upload does not check them, but promotion may refuse them (see WorkloadMetadata).",
        "properties": {
          "shape": {
            "description": "Workload scale. `shape.rankCount` declares the rank count. JSON null counts as absent.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/WorkloadShape"
              },
              {
                "type": "null"
              }
            ]
          },
          "parallelism": {
            "description": "Parallelism degrees. When at least one of `dp`, `tp`, `sp`, `ep` and `pp` is given, their product declares the rank count. JSON null counts as absent.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/WorkloadParallelism"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "WorkloadShape": {
        "type": "object",
        "description": "Workload scale. This schema describes `rankCount`; other members of `shape` are stored and returned as given.",
        "properties": {
          "rankCount": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 2147483647,
            "description": "Total rank count: a whole number from 1 to 2,147,483,647. Declaring it alone is enough; parallelism degrees are optional. When parallelism degrees are also given, their product must equal it. JSON null counts as absent."
          }
        }
      },
      "WorkloadParallelism": {
        "type": "object",
        "description": "Parallelism degrees. When at least one of `dp`, `tp`, `sp`, `ep` and `pp` is given, the rank count is their product, with an absent degree counting as 1, and must not exceed 2,147,483,647. Each of those five degrees that is given must be a whole number of at least 1. Each of the five is an independent factor; some training frameworks count an axis differently, for example expert parallelism within data parallelism, and when the rank count is not this product, declare `shape.rankCount` and give degrees only if their product equals it. Other members, such as `cp` and `fsdp`, are not factors; upload stores them as given without checking them, and promotion checks `cp` and `fsdp`. `cp` is the context parallelism degree: the number of ranks that split the attention computation over a long sequence's context. `fsdp` is the fully sharded data parallel (FSDP) degree: the number of data-parallel ranks the model's parameters, gradients and optimizer state are sharded across; it divides `dp` rather than adding ranks. JSON null counts as absent.",
        "properties": {
          "dp": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "description": "Data parallelism degree: the number of data-parallel ranks, each processing its own share of the global batch and synchronizing gradients with the others. Without FSDP each holds a full replica of the model; with `fsdp`, each group of `fsdp` of them holds one replica between them, so there are `dp` ÷ `fsdp` replicas."
          },
          "tp": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "description": "Tensor parallelism degree: the number of ranks that split each layer's weight matrices, and the layer's computation, between them."
          },
          "sp": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "description": "Sequence parallelism degree: the number of ranks that split each input sequence along its length."
          },
          "ep": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "description": "Expert parallelism degree: the number of ranks a mixture-of-experts (MoE) model's experts are distributed across, each rank holding a subset of the experts and exchanging tokens with the others."
          },
          "pp": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "description": "Pipeline parallelism degree: the number of pipeline stages, each a contiguous group of the model's layers on its own ranks, that microbatches pass through in turn."
          }
        }
      },
      "RankRange": {
        "type": "object",
        "properties": {
          "start": {
            "type": "integer"
          },
          "end": {
            "type": "integer"
          }
        },
        "required": [
          "start",
          "end"
        ]
      },
      "TracesetFileResponse": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "hash": {
            "type": "string",
            "nullable": true
          },
          "size": {
            "type": "integer",
            "format": "int64"
          },
          "role": {
            "type": "string",
            "enum": [
              "primary",
              "topology",
              "mapping",
              "planning",
              "telemetry",
              "shard",
              "manifest"
            ],
            "description": "Role of the file in the traceset"
          },
          "contentType": {
            "type": "string",
            "nullable": true
          },
          "rankRange": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/RankRange"
              },
              {
                "type": "null"
              }
            ]
          },
          "metadataStatus": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "complete",
              "failed"
            ],
            "description": "`complete` means the metadata the platform uses for this file is recorded; for uploaded tracesets the platform does not read the trace files."
          }
        },
        "required": [
          "name",
          "size",
          "role",
          "metadataStatus"
        ]
      },
      "TracesetResponse": {
        "type": "object",
        "description": "Full traceset detail. On public-scope tracesets, the server intentionally omits tenant-identifying fields (workspaceId, promotedBy) per §5.1/§6.4 — clients must treat them as optional and tolerate absence.",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "uploading",
              "processing",
              "ready",
              "metadata_failed",
              "upload_failed",
              "deleted"
            ]
          },
          "scope": {
            "type": "string",
            "enum": [
              "workspace",
              "tenant",
              "public"
            ],
            "description": "Visibility scope of the traceset"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TracesetFileResponse"
            }
          },
          "totalSize": {
            "type": "integer",
            "format": "int64"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "workspaceId": {
            "type": "string",
            "nullable": true,
            "description": "Owning workspace ID. Omitted on public-scope tracesets per tenant-stripping rules; clients must treat the field as optional and tolerate its absence."
          },
          "workloadMetadata": {
            "description": "Workload characterization metadata: as given at upload, or as given at the traceset's latest applied promotion that carried metadata. Omitted when the traceset has none. Encoded as `oneOf` with explicit `type:'null'` because `nullable:true` adjacent to `$ref` is ignored by the OpenAPI Python generator (the $ref form short-circuits sibling keywords), causing it to emit `WorkloadMetadata.from_dict(value)` without a None guard and crash on JSON null. The `oneOf` form forces the codegen to emit the null branch.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/WorkloadMetadata"
              },
              {
                "type": "null"
              }
            ]
          },
          "rankCountDerived": {
            "type": "integer",
            "nullable": true,
            "description": "The traceset's rank count: the count declared when it was uploaded or, for a traceset uploaded before rank counts were declared, the count derived from workloadMetadata. Omitted when the traceset has no rank count."
          },
          "promotedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp at which the traceset was last promoted. Omitted for un-promoted tracesets."
          },
          "promotedBy": {
            "type": "string",
            "nullable": true,
            "description": "User who promoted the traceset. Omitted on public-scope tracesets per tenant-stripping rules."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "scope",
          "files",
          "totalSize",
          "tags",
          "createdAt"
        ]
      },
      "TracesetDownloadUrlResponse": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "file": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "url",
          "expiresAt"
        ]
      },
      "TracesetValidateRequest": {
        "type": "object",
        "properties": {
          "topologyId": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "ValidationCheck": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "passed": {
            "type": "boolean"
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "name",
          "passed"
        ]
      },
      "TracesetValidationResponse": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean"
          },
          "checks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationCheck"
            }
          }
        },
        "required": [
          "valid",
          "checks"
        ]
      },
      "UploadFileSpec": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "size": {
            "type": "integer",
            "format": "int64"
          },
          "role": {
            "type": "string",
            "enum": [
              "primary",
              "topology",
              "mapping",
              "planning",
              "telemetry",
              "shard",
              "manifest"
            ],
            "description": "Role of the file in the traceset"
          },
          "contentType": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "name",
          "size",
          "role"
        ]
      },
      "TracesetUploadUrlRequest": {
        "type": "object",
        "properties": {
          "workspaceId": {
            "type": "string",
            "nullable": true,
            "description": "Workspace ID. If not provided, uses the universal traceset workspace."
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "ttlDays": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Custom TTL in days (1-365). Uses server default if omitted.",
            "minimum": 1,
            "maximum": 365
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UploadFileSpec"
            }
          },
          "workloadMetadata": {
            "$ref": "#/components/schemas/UploadWorkloadMetadata",
            "description": "Workload characterization metadata, stored on the traceset as given. It declares the traceset's rank count, which an upload with primary files must declare: either shape.rankCount, or the parallelism degrees parallelism.dp, tp, sp, ep and pp, multiplied together, with an absent degree counting as 1 (cp and fsdp are not factors). When both are given they must be equal. Each value must be a whole number of at least 1. The traceset reports that count as rankCountDerived, and attaching the traceset to a configuration uses it; it cannot be changed after upload. UploadWorkloadMetadata describes the rank-count members; this field accepts any JSON object of at most 65,536 bytes when serialized whose rank-count members are valid, including members UploadWorkloadMetadata does not describe."
          }
        },
        "required": [
          "name",
          "files"
        ]
      },
      "PartUploadUrl": {
        "type": "object",
        "properties": {
          "partNumber": {
            "type": "integer"
          },
          "size": {
            "type": "integer",
            "format": "int64",
            "description": "Number of bytes to PUT for this part: the server's configured part size for every part but the last, and the rest of the declared size for the last. A mapping file's last part may be shorter, since its `sizeBytes` is an upper bound."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Presigned PUT URL for this part. Expires at `partUrlsExpireAt`, or sooner if the server's signing credentials expire first."
          }
        },
        "required": [
          "partNumber",
          "size",
          "url"
        ]
      },
      "FileUploadUrls": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "parts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PartUploadUrl"
            }
          },
          "partUrlsExpireAt": {
            "type": "string",
            "format": "date-time",
            "description": "When these part URLs expire at the latest (one hour after issue by default). Upload every part before then; this is shorter than `expiresAt`."
          }
        },
        "required": [
          "name",
          "parts",
          "partUrlsExpireAt"
        ]
      },
      "TracesetUploadUrlResponse": {
        "type": "object",
        "properties": {
          "uploadId": {
            "type": "string"
          },
          "checksumAlgorithm": {
            "type": "string"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FileUploadUrls"
            }
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the upload session expires (24 hours after creation). This is not the part URLs' expiry: see `partUrlsExpireAt`."
          }
        },
        "required": [
          "uploadId",
          "checksumAlgorithm",
          "files",
          "expiresAt"
        ]
      },
      "CompletedPart": {
        "type": "object",
        "properties": {
          "partNumber": {
            "type": "integer"
          },
          "etag": {
            "type": "string"
          }
        },
        "required": [
          "partNumber",
          "etag"
        ]
      },
      "CompletedFileInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "parts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompletedPart"
            }
          }
        },
        "required": [
          "name",
          "parts"
        ]
      },
      "TracesetCompleteUploadRequest": {
        "type": "object",
        "properties": {
          "uploadId": {
            "type": "string"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompletedFileInput"
            }
          }
        },
        "required": [
          "uploadId",
          "files"
        ]
      },
      "CompletedFileInfo": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "hash": {
            "type": "string",
            "nullable": true
          },
          "size": {
            "type": "integer",
            "format": "int64"
          },
          "role": {
            "type": "string",
            "enum": [
              "primary",
              "topology",
              "mapping",
              "planning",
              "telemetry",
              "shard",
              "manifest"
            ],
            "description": "Role of the file in the traceset"
          }
        },
        "required": [
          "name",
          "size",
          "role"
        ]
      },
      "TracesetCompleteUploadResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "uploading",
              "processing",
              "ready",
              "metadata_failed",
              "upload_failed",
              "deleted"
            ]
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompletedFileInfo"
            }
          },
          "totalSize": {
            "type": "integer",
            "format": "int64"
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "files",
          "totalSize"
        ]
      },
      "MappingFileSummary": {
        "type": "object",
        "additionalProperties": false,
        "description": "A Chakra mapping file as it appears in a list. The file maps each Chakra logical rank to a chakra-capable server and optionally declares scale-up groups.",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^mapfile_[0-9A-Za-z]{27}$",
            "description": "Mapping-file identifier."
          },
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Display name. Display metadata only: inside the simulator the file is always named chakra-mapping.txt."
          },
          "workspaceId": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "description": "Length in bytes of the stored object, measured at upload completion."
          },
          "rankCount": {
            "type": "integer",
            "minimum": 1,
            "description": "Number of Chakra logical ranks the file maps. Derived at upload and stored, so attach validation never re-reads the file."
          },
          "scaleUpGroupCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of scale-up groups the file's second section declares."
          },
          "hasScaleUp": {
            "type": "boolean",
            "description": "True when the file declares at least one scale-up group."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "workspaceId",
          "sizeBytes",
          "rankCount",
          "scaleUpGroupCount",
          "hasScaleUp",
          "createdAt"
        ]
      },
      "MappingFileDetails": {
        "type": "object",
        "additionalProperties": false,
        "description": "A Chakra mapping file with its stored checksum and concurrency tag. MappingFileSummary's fields are repeated rather than composed with allOf: the Rust server generator has no allOf path, so a composed schema fails the build.",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^mapfile_[0-9A-Za-z]{27}$",
            "description": "Mapping-file identifier."
          },
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Display name. Display metadata only: inside the simulator the file is always named chakra-mapping.txt."
          },
          "workspaceId": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "description": "Length in bytes of the stored object, measured at upload completion."
          },
          "rankCount": {
            "type": "integer",
            "minimum": 1,
            "description": "Number of Chakra logical ranks the file maps. Derived at upload and stored, so attach validation never re-reads the file."
          },
          "scaleUpGroupCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of scale-up groups the file's second section declares."
          },
          "hasScaleUp": {
            "type": "boolean",
            "description": "True when the file declares at least one scale-up group."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2048,
            "description": "Optional free-text description supplied at upload."
          },
          "hash": {
            "type": "string",
            "pattern": "^crc64nvme:[A-Za-z0-9_-]{11}$",
            "description": "The CRC64NVME full-object checksum reported at upload, canonicalised as `crc64nvme:` plus base64url without padding. The bytes served by download always carry this checksum."
          },
          "etag": {
            "type": "string",
            "description": "Optimistic-concurrency tag for this mapping file."
          },
          "duplicateOfExisting": {
            "type": "boolean",
            "description": "True only on the 200 an upload completion returns when the uploaded bytes already exist as a live mapping file in the workspace: the response then describes that existing file and no new one was created. False on every other response."
          }
        },
        "required": [
          "id",
          "name",
          "workspaceId",
          "sizeBytes",
          "rankCount",
          "scaleUpGroupCount",
          "hasScaleUp",
          "createdAt",
          "description",
          "hash",
          "etag",
          "duplicateOfExisting"
        ]
      },
      "MappingFileUploadUrlRequest": {
        "type": "object",
        "additionalProperties": false,
        "description": "Request for a presigned multipart upload of one Chakra mapping file.",
        "required": [
          "sizeBytes",
          "workspaceId"
        ],
        "properties": {
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._-]{1,255}$",
            "maxLength": 255,
            "default": "chakra-mapping.txt",
            "description": "Optional display name; absent, it is chakra-mapping.txt. Used verbatim as the final segment of the stored object's key, so it must be a single safe path segment of 1 to 255 bytes of [A-Za-z0-9._-], must not be `.`, and must not contain `..` anywhere (so `placement..v2.txt` is refused), because central's launch check and the legacy path's stager refuse `..` inside the path the name is part of. Display metadata only: inside the simulator the file is always named chakra-mapping.txt."
          },
          "sizeBytes": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "maximum": 64000000,
            "description": "Upper bound on the file's byte length. The 64,000,000-byte ceiling is the 64 MB per-file limit. The stored sizeBytes is the completed object's actual length, which may be smaller."
          },
          "workspaceId": {
            "type": "string",
            "minLength": 1,
            "pattern": "^\\S([\\s\\S]*\\S)?$",
            "description": "Workspace the file belongs to (format: `workspace_xxx`). Must not be blank or padded with whitespace; it is stored exactly as sent."
          },
          "description": {
            "type": "string",
            "maxLength": 2048
          }
        }
      },
      "MappingFileUploadUrlResponse": {
        "type": "object",
        "additionalProperties": false,
        "description": "Presigned URLs for each part of the upload. PUT every part, then call the complete operation.",
        "required": [
          "uploadId",
          "checksumAlgorithm",
          "parts",
          "partUrlsExpireAt",
          "expiresAt"
        ],
        "properties": {
          "uploadId": {
            "type": "string"
          },
          "checksumAlgorithm": {
            "type": "string",
            "enum": [
              "crc64nvme"
            ]
          },
          "parts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PartUploadUrl"
            }
          },
          "partUrlsExpireAt": {
            "type": "string",
            "format": "date-time",
            "description": "When these part URLs expire at the latest (one hour after issue by default). Upload every part before then; this is shorter than `expiresAt`."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the upload session expires (24 hours after creation). This is not the part URLs' expiry: see `partUrlsExpireAt`."
          }
        }
      },
      "MappingFileCompleteUploadRequest": {
        "type": "object",
        "additionalProperties": false,
        "description": "Finalises a mapping-file upload with the ETags returned for each uploaded part.",
        "required": [
          "uploadId",
          "parts"
        ],
        "properties": {
          "uploadId": {
            "type": "string"
          },
          "parts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompletedPart"
            }
          }
        }
      },
      "MappingFileDownloadUrlResponse": {
        "type": "object",
        "additionalProperties": false,
        "description": "Presigned URL for downloading a mapping file. The served bytes are the uploaded bytes.",
        "required": [
          "url",
          "expiresAt"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "MappingFileList": {
        "type": "object",
        "additionalProperties": false,
        "description": "One page of mapping files, newest first.",
        "required": [
          "items",
          "pagination"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MappingFileSummary"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "AttachMappingFileRequest": {
        "type": "object",
        "additionalProperties": false,
        "description": "Attaches a mapping file to a simulation configuration.",
        "required": [
          "mappingFileId"
        ],
        "properties": {
          "mappingFileId": {
            "type": "string",
            "pattern": "^mapfile_[0-9A-Za-z]{27}$"
          }
        }
      },
      "ActiveMappingFileRef": {
        "type": "object",
        "additionalProperties": false,
        "description": "The mapping file a configuration or a simulation refers to.",
        "required": [
          "id",
          "name",
          "deleted"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^mapfile_[0-9A-Za-z]{27}$"
          },
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "deleted": {
            "type": "boolean",
            "description": "True when the mapping file has since been deleted. A configuration keeps naming a deleted file; creating a simulation from it is refused until the file is detached or another is attached."
          }
        }
      },
      "SimpleOperationType": {
        "type": "string",
        "enum": [
          "allReduce",
          "reduce",
          "allGather",
          "reduceScatter",
          "reduceScatterBlock",
          "allToAll",
          "broadcast",
          "gather",
          "scatter",
          "barrier"
        ],
        "description": "MPI collective operation type for simple network simulation workloads.",
        "x-enum-aliases": {
          "allReduce": [
            "AllReduce"
          ],
          "reduce": [
            "Reduce"
          ],
          "allGather": [
            "AllGather"
          ],
          "reduceScatter": [
            "ReduceScatter"
          ],
          "reduceScatterBlock": [
            "ReduceScatterBlock"
          ],
          "allToAll": [
            "AllToAll"
          ],
          "broadcast": [
            "Broadcast"
          ],
          "gather": [
            "Gather"
          ],
          "scatter": [
            "Scatter"
          ],
          "barrier": [
            "Barrier"
          ]
        }
      },
      "SimpleAlgorithm": {
        "type": "string",
        "enum": [
          "ring",
          "binaryTree",
          "doubleBinaryTree",
          "recursiveHalvingDoubling",
          "sequential",
          "interleaved",
          "direct",
          "halving"
        ],
        "description": "Collective expansion algorithm. If omitted, the platform default for the selected operation is used. Names follow MPI/NCCL conventions where applicable. Domain synonyms are accepted on input: rabenseifner → recursiveHalvingDoubling, pairwiseExchange → sequential, pipelinedPairwise → interleaved, flat/linear → direct, recursiveHalving → halving.",
        "x-enum-aliases": {
          "ring": [
            "Ring",
            "ringAllreduce"
          ],
          "binaryTree": [
            "BinaryTree"
          ],
          "doubleBinaryTree": [
            "DoubleBinaryTree"
          ],
          "recursiveHalvingDoubling": [
            "RecursiveHalvingDoubling",
            "rabenseifner",
            "Rabenseifner"
          ],
          "sequential": [
            "Sequential",
            "pairwiseExchange",
            "PairwiseExchange"
          ],
          "interleaved": [
            "Interleaved",
            "pipelinedPairwise",
            "PipelinedPairwise"
          ],
          "direct": [
            "Direct",
            "flat",
            "linear"
          ],
          "halving": [
            "Halving",
            "recursiveHalving"
          ]
        }
      },
      "SimpleWorkloadPhase": {
        "type": "object",
        "description": "A single collective operation phase within a workload. Each phase specifies an operation type, optional algorithm override, and data size.",
        "properties": {
          "operationType": {
            "$ref": "#/components/schemas/SimpleOperationType"
          },
          "algorithm": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SimpleAlgorithm"
              },
              {
                "type": "null"
              }
            ],
            "description": "Algorithm for this phase. If omitted, the platform default for the operation is used."
          },
          "dataSize": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "description": "Data size in bytes for this phase."
          }
        },
        "required": [
          "operationType",
          "dataSize"
        ]
      },
      "SimpleWorkload": {
        "type": "object",
        "description": "Sequential workload specification. All ranks execute the same ordered phases. Mutually exclusive with groups. Not all algorithms are valid for every operation; see GET /api/v1/simple/compatibility for the full operation/algorithm compatibility matrix including defaults and power-of-two constraints.",
        "properties": {
          "ranks": {
            "type": "integer",
            "minimum": 1,
            "description": "Number of participating ranks. Without topologyConstraints, must be one of the reference topology sizes: 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096. Large sizes (8192, 16384, 32768, 65536) require the enable_large_simple_sim_topologies flag. With topologyConstraints, any count the constraint solver can satisfy is accepted; a count above 4096 still requires the enable_large_simple_sim_topologies flag."
          },
          "phases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SimpleWorkloadPhase"
            },
            "minItems": 1,
            "maxItems": 16,
            "description": "Ordered list of collective operation phases (1–16). Operations execute sequentially via ctrlDeps chaining."
          }
        },
        "required": [
          "ranks",
          "phases"
        ]
      },
      "SimpleGroupSpec": {
        "type": "object",
        "description": "Specification for a group of ranks running the same collective operations concurrently with other groups. Multiple groups with the same spec create independent process groups on disjoint rank ranges.",
        "properties": {
          "count": {
            "type": "integer",
            "minimum": 1,
            "maximum": 64,
            "description": "Number of identical groups to create."
          },
          "groupSize": {
            "type": "integer",
            "minimum": 1,
            "description": "Number of ranks per group."
          },
          "phases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SimpleWorkloadPhase"
            },
            "minItems": 1,
            "maxItems": 16,
            "description": "Operations each group executes (sequentially within group, parallel across groups)."
          }
        },
        "required": [
          "count",
          "groupSize",
          "phases"
        ]
      },
      "SimpleSimulationMode": {
        "type": "string",
        "enum": [
          "sequential",
          "parallel"
        ],
        "description": "Execution mode of a simple simulation. Sequential: all ranks execute the same phases via a single process group. Parallel: ranks are partitioned into independent groups that execute concurrently."
      },
      "TopologyConstraints": {
        "type": "object",
        "description": "Hardware constraints for topology derivation. The solver derives a valid CLOS topology from the specified switch radix and oversubscription ratio. A 2-tier topology is used when ranks fit within the radix capacity (ports × hosts_per_leaf); otherwise a 3-tier pod-based topology (RSW → FSW → SSW) is derived with all switches fully utilized. When present, rank count is not restricted to the reference values — any count satisfying the constraints is valid, and a count above 4096 still requires the enable_large_simple_sim_topologies flag.",
        "properties": {
          "switchRadix": {
            "type": "string",
            "enum": [
              "64x800G",
              "128x400G",
              "256x200G"
            ],
            "description": "Switch port configuration for TH5-class (51200 Gbps switching capacity). Format: PortsxSpeed (e.g. 128x400G). 64x800G: 64 ports at 800 Gbps. 128x400G: 128 ports at 400 Gbps (default). 256x200G: 256 ports at 200 Gbps."
          },
          "subscriptionRatio": {
            "type": "string",
            "enum": [
              "1:1",
              "2:1",
              "3:1",
              "4:1"
            ],
            "description": "Target oversubscription ratio (downlink BW : uplink BW) applied at every switch tier. 1:1: equal uplink and downlink bandwidth (default). 2:1, 3:1, and 4:1: more downlink capacity, fewer uplinks. The ratio is applied to both rack switches (RSW) and fabric switches (FSW) in 3-tier topologies. Actual ratios may differ slightly from the target due to integer port rounding."
          },
          "nicNetworkPortSpeed": {
            "type": "integer",
            "enum": [
              50,
              100,
              200,
              400,
              800
            ],
            "description": "NIC network port speed in Gbps. Determines the data rate of each host-to-switch connection. When omitted, defaults to the switch link speed from switchRadix (e.g. 400 for 128x400G). The effective link speed between a NIC and its rack switch is min(nicNetworkPortSpeed, switchLinkSpeed) — the lower of the two is used for both topology capacity planning and the generated configuration. PCIe generation is auto-selected to match the effective NIC speed. Allowed values: 50, 100, 200, 400, 800 Gbps."
          }
        }
      },
      "SimpleSimulationRequest": {
        "type": "object",
        "description": "Request to create a simple collective-operation simulation. Exactly one of workload or groups must be specified.",
        "properties": {
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,254}$",
            "maxLength": 255,
            "description": "Optional human-readable name for the simulation. Auto-generated when omitted. SECURITY: this value is interpolated into command strings and Slurm entrypoints executed on cluster nodes, so it is restricted to letters, digits, '-' and '_' (1–255 characters), and must start with a letter or digit (no whitespace, other punctuation, or non-ASCII characters, and no leading '-' or '_')."
          },
          "topology": {
            "type": "string",
            "description": "Optional topology reference (reserved for K2 orchestration)."
          },
          "topologyConstraints": {
            "$ref": "#/components/schemas/TopologyConstraints",
            "description": "Hardware constraints for topology derivation. Mutually exclusive with topology."
          },
          "workload": {
            "$ref": "#/components/schemas/SimpleWorkload",
            "description": "Sequential workload: all ranks execute the same phases. Mutually exclusive with groups."
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SimpleGroupSpec"
            },
            "minItems": 1,
            "maxItems": 16,
            "description": "Parallel groups: ranks partitioned into independent groups executing concurrently. Mutually exclusive with workload."
          }
        }
      },
      "SimpleSimulationStatus": {
        "type": "string",
        "enum": [
          "accepted"
        ],
        "description": "Status of a simple simulation submission."
      },
      "SimpleSimulationResponse": {
        "type": "object",
        "properties": {
          "simulationId": {
            "type": "string",
            "description": "Unique identifier for the submitted simulation."
          },
          "status": {
            "$ref": "#/components/schemas/SimpleSimulationStatus",
            "description": "Status of the submission."
          },
          "mode": {
            "$ref": "#/components/schemas/SimpleSimulationMode",
            "description": "Execution mode: sequential (workload) or parallel (groups)."
          },
          "workload": {
            "$ref": "#/components/schemas/SimpleWorkload",
            "description": "Resolved workload with algorithms filled in. Present when mode is sequential."
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SimpleGroupSpec"
            },
            "description": "Resolved groups with algorithms filled in. Present when mode is parallel."
          }
        },
        "required": [
          "simulationId",
          "status",
          "mode"
        ]
      },
      "TopologyTier": {
        "type": "object",
        "description": "Switch details for a single tier of the CLOS topology. Tiers are ordered bottom-up: RSW (rack), FSW (fabric), SSW (spine).",
        "properties": {
          "name": {
            "type": "string",
            "enum": [
              "RSW",
              "FSW",
              "SSW"
            ],
            "description": "Switch role at this tier. RSW = rack switch (leaf), FSW = fabric switch, SSW = spine switch (super-spine)."
          },
          "switchCount": {
            "type": "integer",
            "description": "Total number of switches at this tier."
          },
          "downlinksPerSwitch": {
            "type": "integer",
            "description": "Number of downlink ports per switch. For RSW: host-facing ports. For FSW: RSW-facing ports. For SSW: FSW-facing ports."
          },
          "uplinksPerSwitch": {
            "type": "integer",
            "description": "Number of uplink ports per switch. For RSW: FSW-facing ports. For FSW: SSW-facing ports. 0 for the top-of-tree tier."
          },
          "downlinkDataRateGbps": {
            "type": "integer",
            "description": "Data rate on each downlink in Gbps. For RSW downlinks, this is min(nicNetworkPortSpeed, switchLinkSpeed) — the effective host-to-switch speed."
          },
          "uplinkDataRateGbps": {
            "type": "integer",
            "description": "Data rate on each uplink in Gbps. 0 for the top-of-tree tier (no uplinks)."
          },
          "effectiveSubscriptionRatio": {
            "type": "string",
            "description": "Effective oversubscription ratio at this tier in N:1 notation (e.g., '1:1', '2:1', '1.91:1'), computed from actual port counts and data rates: (downlinks × downlinkRate) / (uplinks × uplinkRate). May differ from the target ratio due to integer port rounding. Null for the top-of-tree tier (no uplinks)."
          },
          "switchCapacityUtilization": {
            "type": "number",
            "format": "float",
            "description": "Percentage of the switch's total switching capacity consumed by connected links at this tier. Computed as (downlinks × downlinkRate + uplinks × uplinkRate) / switchingCapacityGbps × 100. For example, a fully packed 128×400G switch (51200 Gbps) shows 100.0. Under-packed switches or non-standard NIC speeds produce lower values."
          }
        },
        "required": [
          "name",
          "switchCount",
          "downlinksPerSwitch",
          "uplinksPerSwitch",
          "downlinkDataRateGbps",
          "uplinkDataRateGbps",
          "switchCapacityUtilization"
        ]
      },
      "TopologyLinks": {
        "type": "object",
        "description": "Aggregate link counts at each tier boundary of the topology.",
        "properties": {
          "hostToRsw": {
            "type": "integer",
            "description": "Total host-to-RSW links. Equals totalHosts (one NIC per host)."
          },
          "rswToFsw": {
            "type": "integer",
            "description": "Total RSW-to-FSW links (RSW count times uplinks per RSW). 0 for 1-tier topologies."
          },
          "fswToSsw": {
            "type": "integer",
            "description": "Total FSW-to-SSW links (FSW count times uplinks per FSW). 0 for 1-tier and 2-tier topologies."
          }
        },
        "required": [
          "hostToRsw",
          "rswToFsw",
          "fswToSsw"
        ]
      },
      "ResolvedConstraints": {
        "type": "object",
        "description": "The constraint values actually used for topology derivation, including defaults applied when the user omitted a field. For reference topologies (no topologyConstraints in request), shows the equivalent 128x400G / 1:1 defaults.",
        "properties": {
          "switchRadix": {
            "type": "string",
            "enum": [
              "64x800G",
              "128x400G",
              "256x200G"
            ],
            "description": "Switch port configuration used. Default: 128x400G."
          },
          "subscriptionRatio": {
            "type": "string",
            "enum": [
              "1:1",
              "2:1",
              "3:1",
              "4:1"
            ],
            "description": "Oversubscription ratio used. Default: 1:1."
          },
          "nicNetworkPortSpeed": {
            "type": "integer",
            "description": "Configured NIC network port speed in Gbps. This is the value the user requested, or the switch link speed if omitted."
          },
          "effectiveNicSpeed": {
            "type": "integer",
            "description": "Effective NIC-to-switch link speed in Gbps: min(nicNetworkPortSpeed, switchLinkSpeed). When the NIC speed exceeds the switch port speed, the link operates at the slower switch speed. This is the data rate used for RSW downlinks and topology capacity planning."
          },
          "switchLinkSpeed": {
            "type": "integer",
            "description": "Switch link speed in Gbps, derived from switchRadix (e.g., 400 for 128x400G)."
          },
          "switchingCapacityGbps": {
            "type": "integer",
            "description": "Total switching capacity per switch in Gbps. All current switch models are 51200 Gbps (TH5-class)."
          }
        },
        "required": [
          "switchRadix",
          "subscriptionRatio",
          "nicNetworkPortSpeed",
          "effectiveNicSpeed",
          "switchLinkSpeed",
          "switchingCapacityGbps"
        ]
      },
      "TopologyPreview": {
        "type": "object",
        "description": "Derived physical network topology details. Describes the CLOS fabric structure that would be produced for a simulation with the given inputs. This is a pure computation result — no simulation or configuration is created.",
        "properties": {
          "tierCount": {
            "type": "integer",
            "enum": [
              1,
              2,
              3
            ],
            "description": "Number of switch tiers. 1 = single rack (RSW only), 2 = leaf-spine (RSW + FSW), 3 = pod-based (RSW + FSW + SSW)."
          },
          "totalHosts": {
            "type": "integer",
            "description": "Total host count in the topology. Equals total ranks for sequential mode or sum of (count * groupSize) for parallel mode."
          },
          "ranksPerHost": {
            "type": "integer",
            "description": "Number of ranks mapped to each host. Currently always 1."
          },
          "ranksPerRack": {
            "type": "integer",
            "description": "Number of ranks (hosts) per rack. Equals the RSW downlink count — each host connects to its rack switch via one NIC port."
          },
          "tiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TopologyTier"
            },
            "description": "Per-tier switch details, ordered bottom-up (RSW first, then FSW, then SSW). Array length equals tierCount."
          },
          "links": {
            "$ref": "#/components/schemas/TopologyLinks",
            "description": "Aggregate link counts at each tier boundary."
          },
          "resolvedConstraints": {
            "$ref": "#/components/schemas/ResolvedConstraints",
            "description": "The constraint values used for derivation, including defaults applied for omitted fields."
          },
          "pods": {
            "type": "integer",
            "description": "Number of pods in the topology. Present only for 3-tier topologies (tierCount = 3)."
          },
          "racksPerPod": {
            "type": "integer",
            "description": "Number of racks per pod. Present only for 3-tier topologies (tierCount = 3)."
          },
          "spinePlanes": {
            "type": "integer",
            "description": "Number of independent spine planes. The preprocessor divides SSWs across planes and assigns FSWs round-robin. Present only for 3-tier topologies (tierCount = 3)."
          }
        },
        "required": [
          "tierCount",
          "totalHosts",
          "ranksPerHost",
          "ranksPerRack",
          "tiers",
          "links",
          "resolvedConstraints"
        ]
      },
      "TopologyPreviewResponse": {
        "type": "object",
        "description": "Response from the topology preview endpoint. Contains the derived physical network topology without creating a simulation or persisting any state.",
        "properties": {
          "topology": {
            "$ref": "#/components/schemas/TopologyPreview",
            "description": "The derived physical network topology."
          }
        },
        "required": [
          "topology"
        ]
      },
      "CompatibilityEntry": {
        "type": "object",
        "description": "Compatibility entry for a single MPI collective operation, listing allowed algorithms, the platform default, and which combinations require a power-of-two rank count.",
        "properties": {
          "operationType": {
            "$ref": "#/components/schemas/SimpleOperationType",
            "description": "MPI collective operation type this entry describes."
          },
          "allowedAlgorithms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SimpleAlgorithm"
            },
            "description": "Algorithms valid for this operation type."
          },
          "defaultAlgorithm": {
            "$ref": "#/components/schemas/SimpleAlgorithm",
            "description": "Platform default algorithm used when the caller omits the algorithm field."
          },
          "powerOfTwoRequired": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SimpleAlgorithm"
            },
            "description": "Algorithms in this list require the rank count to be a power of two. Empty array if no such constraint exists for this operation."
          }
        },
        "required": [
          "operationType",
          "allowedAlgorithms",
          "defaultAlgorithm",
          "powerOfTwoRequired"
        ]
      },
      "CompatibilityMatrixResponse": {
        "type": "object",
        "description": "The full operation/algorithm compatibility matrix. Each entry describes which algorithms are valid for a given collective operation type, the platform default, and power-of-two constraints.",
        "properties": {
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompatibilityEntry"
            },
            "description": "One entry per supported operation type, in enum declaration order."
          }
        },
        "required": [
          "entries"
        ]
      },
      "ChartDefinitionsResponse": {
        "type": "object",
        "description": "The chart definitions stored on this platform, served under one schema version",
        "required": [
          "schemaVersion",
          "definitions"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "description": "The chart-definition schema version every body in this response conforms to: the version the request named, or chart-definition/v1 when it named none. Each body is the chart's stored body with the highest version not above it. A client refuses the whole document when this is a version it does not parse.",
            "pattern": "^chart-definition/v[1-9][0-9]*$"
          },
          "definitions": {
            "type": "array",
            "description": "The stored definition bodies, verbatim and ordered by id. There is no per-element wrapper: each body carries its own top-level id.",
            "items": {
              "description": "One stored chart-definition body, served as-is. The server interprets only its top-level id and reads nothing else in it for meaning. The absence of a type is deliberate — a described type-less schema is what the Rust generators carry through as a raw JSON value — so this description is required and must not be removed."
            }
          }
        }
      }
    },
    "securitySchemes": {
      "bearer_auth": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  },
  "tags": [
    {
      "name": "health",
      "description": "Health and monitoring endpoints"
    },
    {
      "name": "models",
      "description": "Model catalog and discovery"
    },
    {
      "name": "components",
      "description": "Component schema discovery"
    },
    {
      "name": "templates",
      "description": "Curated example configurations"
    },
    {
      "name": "topology",
      "description": "Real-time topology validation"
    },
    {
      "name": "configurations",
      "description": "Workload configuration management"
    },
    {
      "name": "simulations",
      "description": "Simulation execution and results"
    },
    {
      "name": "workspaces",
      "description": "Workspace management"
    },
    {
      "name": "tracesets",
      "description": "Trace file management (feature-gated: enable_trace_routes)"
    },
    {
      "name": "mapping-files",
      "description": "Chakra mapping files. The six mapping-file resource operations are served by the trace-service router behind enable_trace_routes; the two configuration attach and detach operations are served by central unconditionally."
    },
    {
      "name": "simple",
      "description": "Simple collective-operation simulation"
    },
    {
      "name": "charts",
      "description": "Chart definitions served to the simulation UI (feature-gated: enable_chart_definitions)"
    }
  ]
}
