{
  "openapi": "3.1.1",
  "info": {
    "title": "Fallen-8 REST API",
    "description": "A Fallen-8 hosts isolated graph namespaces. Every namespace-scoped path exists twice: bare, aliasing the reserved \"default\" namespace, and prefixed with /ns/{ns} to address a named namespace. A request naming an unknown namespace answers 404 application/problem+json with a \"namespace\" extension member. Fallen-8-level paths (the /ns management routes, save games, delegate validation) exist once and concern the whole collection of namespaces. Two scoped paths have no bare alias: /generate and /benchmark act on exactly one graph and never pick one for you, so their bare form answers 400 naming the /ns/{ns} URL.",
    "version": "0.1"
  },
  "servers": [
    {
      "url": "http://localhost:5000/"
    }
  ],
  "paths": {
    "/analytics/algorithms": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Lists the discovered analytics algorithm plugins",
        "description": "The five built-ins are PAGERANK, WCC, LABELPROPAGATION, DEGREE and TRIANGLECOUNT;\nIGraphAnalyticsAlgorithm plugins compiled into the shipped assemblies appear here too\n(the same discovery as path and subgraph algorithms), as do the addressed namespace's\nruntime-registered analytics plugins (POST /plugins/algorithm). Every name listed here\nis invocable through POST /analytics/{algorithmName}.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The available algorithms with their descriptions",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/analytics/{algorithmName}": {
      "post": {
        "tags": [
          "Analytics"
        ],
        "summary": "Runs an analytics algorithm over the graph",
        "description": "Runs synchronously under the wall-clock budget (default 30 s). Score algorithms\nreturn the top-K vertices by score (descending, ascending id tie-break); partition\nalgorithms return partition summaries (largest first). The FULL per-vertex result's\ndelivery vehicle is the opt-in property write-back (\"writeBack\": true), which lands\nthrough chunked plugin write transactions; write-back durability is SNAPSHOT-ONLY -\na WAL-only replay with no intervening save loses the written properties (re-run to\nrestore, overwrite is idempotent).\n\nReaching the iteration cap is a NORMAL 200 (converged=false, values usable), as is\nbudget exhaustion after at least one completed pass (budgetExhausted=true).\n\nSample request:\n\n    POST /analytics/PAGERANK\n    {\n       \"vertexLabel\": \"person\",\n       \"maxResults\": 10,\n       \"parameters\": { \"DampingFactor\": 0.85 }\n    }",
        "parameters": [
          {
            "name": "algorithmName",
            "in": "path",
            "description": "The plugin name (e.g. PAGERANK, WCC, LABELPROPAGATION, DEGREE, TRIANGLECOUNT)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Scoping, budgets, algorithm parameters, result bound and the optional write-back",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The run's result (including converged=false / budgetExhausted=true partials that carry usable values)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsResultREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsResultREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsResultREST"
                }
              }
            }
          },
          "400": {
            "description": "Unknown direction/parameter values, out-of-ceiling maxIterations/maxResults/timeBudgetSeconds, or a bad write-back property key",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Unknown algorithm name",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "408": {
            "description": "The wall-clock budget exhausted with no usable result",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "All concurrent-run slots are taken",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/analytics/{algorithmName}/partition/{partitionId}": {
      "post": {
        "tags": [
          "Analytics"
        ],
        "summary": "Returns one partition's membership page from a fresh run of a partition algorithm",
        "description": "Analytics runs are one-shot (no job store), so the page comes from a FRESH run with\nthe same specification - deterministic for a quiescent graph. Use offset+maxResults\nto page; the page ceiling is 10000 rows.",
        "parameters": [
          {
            "name": "algorithmName",
            "in": "path",
            "description": "A partition algorithm (WCC or LABELPROPAGATION)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "partitionId",
            "in": "path",
            "description": "The partition id from a previous run's summaries",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The same run specification, plus the page offset",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The membership page",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PartitionMembersREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PartitionMembersREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PartitionMembersREST"
                }
              }
            }
          },
          "400": {
            "description": "Invalid specification, a negative offset, writeBack (not supported here), or a score algorithm",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Unknown algorithm or a partition id the run did not produce (including an empty scope)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "408": {
            "description": "The wall-clock budget exhausted with no usable result",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "All concurrent-run slots are taken",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/benchmark": {
      "get": {
        "tags": [
          "Benchmark"
        ],
        "summary": "Runs the edge-traversal benchmark and returns structured statistics",
        "description": "Traverses the ADDRESSED namespace, and like GET /ns/{ns}/generate it has no bare-URL\nalias to \"default\" (feature graph-namespaces): measuring a graph the caller did not name\nwould report the wrong graph's throughput as if it were theirs. It follows every outgoing\nedge of every vertex regardless of edge-property-id, so it works on any loaded graph and\nreports edges traversed per second (not query latency).",
        "parameters": [
          {
            "name": "iterations",
            "in": "query",
            "description": "Number of timed iterations (default 1000, at most\n    Fallen8:Security:BenchmarkMaxIterations; the default is clamped to that ceiling)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Always: this route names no namespace, and the operation acts on one graph. Call the /ns/{ns} form instead.",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        },
        "deprecated": true
      }
    },
    "/bulk/export": {
      "get": {
        "tags": [
          "Bulk"
        ],
        "summary": "Streams the graph (or a filtered subset) as newline-delimited JSON.",
        "description": "The stream is fallen8-jsonl version 2: one meta line (format version + exact counts),\nthen vertex lines, then edge lines. Edges whose endpoints are not both in the exported\nvertex set are omitted, so EVERY exported file is internally consistent and importable\nby construction. Element embeddings export as their reserved System.Single[]\nproperties (the version-2 type).\n\nCONSISTENCY (honest): this is data interchange, not a crash-consistent backup. Reads\nare lock-free; a write committed during the export may or may not appear. The\nguarantee is internal consistency plus \"everything committed before the export began\nis present\" (subject to the filters). For a point-in-time backup, quiesce writes\nor use the save-game machinery. The same contract covers a property that an\nembedded/plugin writer adds DURING the stream: if it is not exportable it is omitted\nfrom its element rather than aborting the response (the REST write path cannot create\nsuch properties; the pre-stream 422 covers everything present at capture).",
        "parameters": [
          {
            "name": "vertexLabel",
            "in": "query",
            "description": "Optional: export only vertices with exactly this label",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "edgeLabel",
            "in": "query",
            "description": "Optional: export only edges with exactly this label",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "edgePropertyId",
            "in": "query",
            "description": "Optional: export only edges of exactly this type (their edgePropertyId); combines with edgeLabel as AND",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The NDJSON stream (application/x-ndjson)",
            "content": {
              "application/x-ndjson": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/x-ndjson; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/x-ndjson": { }
            }
          },
          "422": {
            "description": "An element carries a property that cannot be exported: a null\n     value, a runtime type outside the exportable allow-list, or a String/Char holding an\n     unpaired surrogate (invalid UTF-16). The body names the element, the property and which\n     of the three it was. Sent BEFORE any streaming, so a failed export is never a\n     half-written file",
            "content": {
              "application/x-ndjson; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/x-ndjson": { }
            }
          }
        }
      }
    },
    "/bulk/import": {
      "post": {
        "tags": [
          "Bulk"
        ],
        "summary": "Imports a fallen8-jsonl stream into an EMPTY graph, assigning fresh engine ids.",
        "description": "The body is read as a stream and processed line by line; lines batch into large\ncreate transactions (Fallen8:BulkIO:ImportBatchSize per transaction = one WAL entry +\none fsync each). File ids are remapped unconditionally: they are references within the\nfile, resolved for edge endpoints, never preserved as engine ids. A leading meta line\nis optional (grep-filtered subset files stay valid); when present, its counts act as a\ntruncation guard.\n\nFAIL-FAST (honest): the first invalid line aborts the import with its exact line\nnumber. Batches committed before the failure STAY COMMITTED (each batch is atomic and\nWAL-logged; the file is not one transaction) - the error body reports the committed\ncounts, and because import requires an empty graph, recovery is always \"/tabularasa,\nfix the line, retry\".\n\nNOTE on the body cap: when Fallen8:BulkIO:MaxImportRequestBytes is configured, a real\nKestrel host may enforce it at the transport layer and answer 413 before this action's\nown check runs - the status is the same, but the problem body with committed counts is\nonly guaranteed when the application-level check fires first.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The import completed; the body carries created counts",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportResultREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportResultREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportResultREST"
                }
              }
            }
          },
          "400": {
            "description": "A line was invalid (malformed JSON, unknown fields, bad property\n     type/value, duplicate file id, unresolved edge endpoint, over-long line, meta-count\n     mismatch) - the problem body carries lineNumber and the committed counts",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The graph is not empty (import requires an empty target; use\n     /tabularasa or a fresh instance)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "The request body exceeds the configured Fallen8:BulkIO:MaxImportRequestBytes",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "A batch transaction faulted internally; committed counts are reported"
          }
        }
      }
    },
    "/changefeed": {
      "get": {
        "tags": [
          "ChangeFeed"
        ],
        "summary": "Streams committed graph mutations as Server-Sent Events, with declarative server-side filtering and catch-up.",
        "description": "The stream format per event:\n\n    id: &lt;epoch-guid&gt;:&lt;seq&gt;\n    event: &lt;kind&gt;\n    data: {\"seq\":4712,\"ts\":\"2026-07-15T12:34:56.789Z\",\"kind\":\"propertySet\",\"element\":\"vertex\",\"id\":42,\"label\":\"person\",\"key\":\"name\"}\n\nDelivery: events arrive in commit order (ascending seq), at most once per connection.\nA comment line (\": keepalive\") is written every KeepAliveSeconds so proxies do not idle\nthe stream out. Filters combine with AND across dimensions and OR within one dimension;\nresync events bypass every filter (continuity loss must always reach the client). On\nany resync, re-fetch the state you display; for reason trim/tabulaRasa/load, treat all\nheld element ids as invalid.\n\nThe feed compiles no C# at all - filters are declarative parameters, never compiled\ncode. Payloads never contain property values;\nre-fetch the element when the value is needed.",
        "parameters": [
          {
            "name": "kinds",
            "in": "query",
            "description": "Event kinds to include (repeatable or comma-separated): vertexCreated, vertexRemoved, edgeCreated, edgeRemoved, propertySet, propertyRemoved. Unset = all kinds. resync events always pass.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "elements",
            "in": "query",
            "description": "Element types to include: vertex, edge. Unset = both.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "labels",
            "in": "query",
            "description": "Element labels to include (exact, case-sensitive). Unset = any label. An unlabeled element never matches a labels filter.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "keys",
            "in": "query",
            "description": "Property keys to include (exact, case-sensitive). Only property events carry a key, so setting this excludes create/remove events.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "since",
            "in": "query",
            "description": "Catch-up position: the last seen SSE id (\"&lt;epoch&gt;:&lt;seq&gt;\") or a bare sequence number. Buffered missed events replay first; a position outside the buffered window (or from another process epoch) starts the stream with resync(seekOutOfRange). The Last-Event-ID header (native EventSource reconnect) is honoured when this parameter is unset.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The SSE stream (text/event-stream); it stays open until the client disconnects",
            "content": {
              "text/event-stream": { }
            }
          },
          "400": {
            "description": "An unknown kind/element value or a malformed since position",
            "content": {
              "text/event-stream; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/event-stream": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/event-stream; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/event-stream": { }
            }
          },
          "503": {
            "description": "The change feed is disabled (Fallen8:ChangeFeed:Enabled=false), the concurrent subscriber limit (Fallen8:ChangeFeed:MaxSubscribers) is reached, or the addressed namespace is not loaded in this process (namespaceState \"notLoaded\")",
            "content": {
              "text/event-stream": { }
            }
          }
        }
      }
    },
    "/chat": {
      "post": {
        "tags": [
          "Chat"
        ],
        "summary": "Runs a chat completion against the instance's configured model backend",
        "description": "The instance proxies to its Ollama sidecar (feature instance-config). The model\n    is server-owned (Fallen8:Chat:Ollama:Model); clients cannot choose it on this path. A\n    custom endpoint is a browser-direct concern, never proxied here.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the backend call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/ChatSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/ChatSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The completion, with the backend's generation stats",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ChatResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Empty message list or a message missing content",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "The chat provider is disabled (Fallen8:Chat:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "429": {
            "description": "The sensitive-endpoint rate limit was exceeded",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The backend returned no usable content",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The backend is unavailable (failed to init, or the sidecar is down)",
            "content": {
              "application/json": { }
            }
          },
          "504": {
            "description": "The backend did not respond within Fallen8:Chat:TimeoutSeconds",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/config": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "Gets the instance's read-only configuration (semantic providers + observability)",
        "description": "The operator view behind the Studio Configuration section (feature\n    instance-config). Fallen-8-level and API-key gated like /statistics; config is\n    startup-bound, so this is display-only. Secrets are never emitted - only the boolean\n    apiKeyRequired reports the security posture, and the OTLP endpoint (operator config, not\n    a secret) is shown as configured.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The configuration view",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied (when an API key is configured)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/delegates/validate": {
      "post": {
        "tags": [
          "Delegates"
        ],
        "summary": "Validates a single delegate fragment without executing it",
        "description": "The fragment is wrapped and compiled exactly as the path (POST /path/{from}/to/{to})\nand subgraph (PUT /subgraph) endpoints would wrap it, but nothing is emitted, loaded,\nor executed - validation is side-effect free.\n\nDiagnostic positions are already mapped back to the submitted fragment (1-based; line 1\nis the fragment's first line), so an editor renders markers without further mapping.\nA null/empty fragment is valid by definition (it means \"match everything\" / \"no custom\ncost\"). Warnings are reported but do not make the fragment invalid.\n\nThe endpoint carries the same authentication as the query endpoints (required whenever an\nAPI key is configured); dynamic code execution itself is always on. Validation is only\nuseful where fragment submission is possible at all.\n\nSample request:\n\n    POST /delegates/validate\n    {\n       \"delegateKind\": \"VertexFilter\",\n       \"fragment\": \"return (v) =&gt; v.TryGetProperty(out int age, \\\"age\\\") &amp;&amp; age &gt; 30;\"\n    }",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The delegate kind and the fragment to compile-check",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/ValidateDelegateSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/ValidateDelegateSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The validation result (also for invalid fragments - inspect \"valid\")",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DelegateValidationREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Unknown delegateKind or malformed request",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "Authentication required but missing/invalid",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "429": {
            "description": "Rate limit for sensitive endpoints exceeded",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/document": {
      "post": {
        "tags": [
          "Document"
        ],
        "summary": "Ingests a document file into the graph",
        "description": "Asynchronous (feature semantic-layer): the Document vertex is created first (status\n`processing`, visible on the change feed) and the pipeline - convert, chunk,\nembed, write, then additive NLP enrichment into the entity graph - runs off the request\nthread on a single global queue; the row flips to `indexed` when it finishes. Any\nfailure leaves exactly one failed Document vertex and zero chunks.\nOnly what is knowable BEFORE the hand-off can answer with an HTTP status. Everything the\nworker discovers later - the page cap (`Fallen8:Ingestion:MaxPages`), the per-document\nchunk cap (`MaxChunksPerDocument`), a conversion that yields no text, and any\nembedding-backend fault - cannot, because this call has already answered 202. Those\noutcomes flip the queued document to `failed` with the reason on its status, so a\ncaller learns them from the change feed or from GET /document/{documentId}, never from\nthis response.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts conversion/embedding when the request is cancelled",
          "content": {
            "multipart/form-data; ver=0.1": {
              "schema": {
                "type": "object",
                "allOf": [
                  {
                    "type": "object",
                    "properties": {
                      "file": {
                        "$ref": "#/components/schemas/IFormFile"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "embed": {
                        "type": "boolean"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "sourceUri": {
                        "type": "string"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "replaceDocumentId": {
                        "pattern": "^-?(?:0|[1-9]\\d*)$",
                        "type": [
                          "integer",
                          "string"
                        ],
                        "format": "int32"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "propertiesJson": {
                        "type": "string"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "linkJson": {
                        "type": "string"
                      }
                    }
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "The document was accepted for asynchronous ingestion; the stub starts `processing` and flips to `indexed` on the change feed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSummaryREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Unsupported format, a reserved tag key, or an invalid link allowlist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled), or embed=true while the embedding provider is off",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The replace target does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "Duplicate content hash, or an index shape/model conflict",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "413": {
            "description": "The upload exceeds Fallen8:Ingestion:MaxUploadBytes",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "428": {
            "description": "The semantic layer is not bound; create the required indices first (POST /document/binding/ensure)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "503": {
            "description": "No docling endpoint is configured for a binary format, or the ingestion queue is full",
            "content": {
              "application/json": { }
            }
          },
          "507": {
            "description": "The namespace chunk ceiling is reached (Fallen8:Ingestion:MaxChunksPerNamespace)",
            "content": {
              "application/json": { }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Document"
        ],
        "summary": "Lists the namespace's documents",
        "description": "Summaries plus the chunk budget (FR-14) and the active embedding model,\n    so stale documents (FR-16) are visible in one call.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The documents, chunk usage and ceiling",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentListREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/document/binding": {
      "get": {
        "tags": [
          "Document"
        ],
        "summary": "Reports the semantic layer's index binding state",
        "description": "The three indices the layer uses (vector, fulltext, entity), whether each\n    exists and is usable, and whether ingestion is ready. The layer never creates an index\n    implicitly (FR-7); bind them with POST /document/binding/ensure.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The binding state",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentBindingREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/document/binding/ensure": {
      "post": {
        "tags": [
          "Document"
        ],
        "summary": "Creates the required indices, binding the semantic layer",
        "description": "The explicit, idempotent bind (FR-7): creates the vector, fulltext and entity\n    indices the configuration requires and that do not yet exist, then reports the state.\n    This is the only path that creates a bound index; ingestion answers 428 until it runs.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The binding state after creation (Ready when all required indices exist)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentBindingREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "An index with a bound id exists but is the wrong shape",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/document/entities": {
      "get": {
        "tags": [
          "Document"
        ],
        "summary": "Lists the entities the corpus mentions",
        "description": "Deduplicated Entity vertices (feature semantic-layer) ranked by mention count.\n    Each id is a valid /path or /subgraph seed. A bounded page; `total` reports the full\n    match count.",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "description": "Optional filter on the raw NLP label, compared case-insensitively (e.g. PERSON/ORG/GPE)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contains",
            "in": "query",
            "description": "Optional case-insensitive substring the entity text must contain",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Page cap (default 200, max 10000)",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 200
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The entity page and the total match count",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentEntityListREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/document/search": {
      "post": {
        "tags": [
          "Document"
        ],
        "summary": "Fused chunk search: dense kNN plus lexical fulltext, reciprocal rank fusion",
        "description": "The default mode fuses both sides with RRF (k=60, candidate depth max(50, 4k));\nwhen one side is unavailable (provider off, index absent) the answer degrades and\n`modeUsed` says so. Hits are live Chunk vertices - use them directly as\n/path or /subgraph seeds. Scores: RRF when fused, raw kNN when dense, match count\nwhen lexical.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the query embedding when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/DocumentSearchSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/DocumentSearchSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The hits (flat, or grouped per document)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSearchResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid k/window/mode, no usable query, a dimension mismatch, or the requested side is unavailable",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The vector index's dimension or declared model identity conflicts with the active provider",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The embedding backend produced invalid output",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The embedding backend is unavailable",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/document/text": {
      "post": {
        "tags": [
          "Document"
        ],
        "summary": "Ingests raw text or markdown into the graph",
        "description": "The sidecar-free path (FR-3): markdown chunks along its headings, plain\n    text as one bounded section. Same lifecycle and failure semantics as the file route.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts embedding when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IngestTextSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IngestTextSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "The document was accepted for asynchronous ingestion; the stub starts `processing` and flips to `indexed` on the change feed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSummaryREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Missing name/text, an unknown format, a reserved tag key, or an invalid link allowlist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled, or embed=true while the embedding provider is off",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The replace target does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "Duplicate content hash, or an index shape/model conflict",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "413": {
            "description": "The text exceeds Fallen8:Ingestion:MaxUploadBytes",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "428": {
            "description": "The semantic layer is not bound; create the required indices first (POST /document/binding/ensure)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "503": {
            "description": "The ingestion queue is full",
            "content": {
              "application/json": { }
            }
          },
          "507": {
            "description": "The namespace chunk ceiling is reached",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/document/{documentId}": {
      "get": {
        "tags": [
          "Document"
        ],
        "summary": "Gets one document with its chunks",
        "description": "Chunks carry previews and provenance; the full text stays one home, the\n    chunk vertex's `text` property (graph element routes).",
        "parameters": [
          {
            "name": "documentId",
            "in": "path",
            "description": "The document vertex id",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document and its chunks in document order",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetailREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The id is not a Document vertex",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No vertex with this id",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Document"
        ],
        "summary": "Deletes a document, its chunks and all their edges",
        "description": "One transactional removal (FR-7): edges (including `mentions` and\n    user-drawn ones onto chunks) cascade with the vertices; the fulltext mirror is\n    cleaned alongside.",
        "parameters": [
          {
            "name": "documentId",
            "in": "path",
            "description": "The document vertex id",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "Wait for the removal to commit",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "The removal was enqueued (and committed when waitForCompletion)",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "The id is not a Document vertex",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No vertex with this id",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/edge": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Creates a new edge between two vertices in the graph",
        "description": "Sample request (edgePropertyId is the edge's type - the adjacency group traversals\nkey on; label is an optional, orthogonal category tag):\n\n    PUT /edge\n    {\n       \"sourceVertex\": 1,\n       \"targetVertex\": 2,\n       \"edgePropertyId\": \"knows\",\n       \"label\": \"friendship\",\n       \"creationDate\": 0,\n       \"properties\": [\n         {\n           \"propertyId\": \"since\",\n           \"propertyValue\": \"2024-01-01\",\n           \"fullQualifiedTypeName\": \"System.DateTime\"\n         }\n       ]\n    }",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The edge specification containing source, target and property information",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EdgeSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EdgeSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Edge creation accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Invalid edge specification",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "A referenced source or target vertex does not exist (only when waitForCompletion is true)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      }
    },
    "/edge/count": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "Gets the total number of edges in the database",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the number of edges",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              },
              "application/json": { }
            }
          }
        },
        "security": [ ]
      }
    },
    "/edge/{edgeIdentifier}": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Retrieves an edge from the graph by its identifier",
        "parameters": [
          {
            "name": "edgeIdentifier",
            "in": "path",
            "description": "The ID of the edge to retrieve",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the edge object",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/Edge"
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "Edge with the specified ID was not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/edge/{edgeIdentifier}/source": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the source vertex ID for a specific edge",
        "parameters": [
          {
            "name": "edgeIdentifier",
            "in": "path",
            "description": "The ID of the edge",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the source vertex ID",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Edge with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/edge/{edgeIdentifier}/target": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the target vertex ID for a specific edge",
        "parameters": [
          {
            "name": "edgeIdentifier",
            "in": "path",
            "description": "The ID of the edge",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the target vertex ID",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Edge with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/edges": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Creates many edges in ONE atomic transaction (feature mcp-followups)",
        "description": "The batch write path. If any referenced source/target vertex is missing, the WHOLE batch\nrolls back atomically and answers 404 (nothing is wired). A waited-on call returns the\nassigned edge ids. Edges reference vertices that already exist; to link vertices created in\nthe same session, create the vertices first, read their ids, then create the edges.",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits and returns the assigned ids in input order",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The edges to create (each references existing source/target vertex ids)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EdgeSpecification"
                }
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EdgeSpecification"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the assigned edge ids in input order (waitForCompletion=true)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "202": {
            "description": "Batch accepted (waitForCompletion=false)",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "A null list, or a null/invalid edge specification",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "A referenced source or target vertex does not exist (only when waited)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waited)",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/embedding/element": {
      "post": {
        "tags": [
          "Embedding"
        ],
        "summary": "Embeds a text and stores it as the element's named embedding",
        "description": "The generated vector is written through the element-embeddings surface together\nwith the provider's model-identity stamp (one atomic transaction); a vector index\nbound to the name updates its projection on commit.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the provider call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedElementSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedElementSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The embedding was generated and committed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Missing/oversized text or an invalid embedding name",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "The embedding provider is disabled (Fallen8:Embedding:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The graph element does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The provider's dimension or model identity conflicts with a vector index bound to this embedding name",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The embedding backend produced invalid output",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The embedding backend is unavailable (failed to load, or the Ollama sidecar is down)",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/embedding/elements": {
      "post": {
        "tags": [
          "Embedding"
        ],
        "summary": "Embeds a batch of texts onto elements - one provider batch, one transaction",
        "description": "The bulk-ingestion path: every vector plus its model stamp commits atomically.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the provider call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedElementsSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedElementsSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The batch was generated and committed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Empty/oversized batch, missing text, or an invalid embedding name",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "The embedding provider is disabled (Fallen8:Embedding:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "A referenced graph element does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The provider's dimension or model identity conflicts with a bound vector index",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The embedding backend produced invalid output",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The embedding backend is unavailable",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/embedding/search": {
      "post": {
        "tags": [
          "Embedding"
        ],
        "summary": "Semantic search: embeds a query text and runs kNN against a vector index",
        "description": "The text is embedded ONCE (with the configured query prefix); scores and ordering\nare exactly those of POST /scan/index/vector for the same vector.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the provider call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingSearchSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingSearchSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The hits, best first, with raw scores",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/VectorSearchResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Missing text, invalid k/kind, or the index is not a vector index",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "The embedding provider is disabled (Fallen8:Embedding:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No index with the given name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The index's dimension or declared model identity conflicts with the active provider",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The embedding backend produced invalid output",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The embedding backend is unavailable",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/embedding/text": {
      "post": {
        "tags": [
          "Embedding"
        ],
        "summary": "Embeds raw texts and returns the vectors",
        "description": "For clients driving the raw vector surfaces themselves (external pipelines,\n    semantic path queries with a client-held vector, debugging).",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the provider call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedTextSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedTextSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The vectors, in input order, plus the model identity",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/EmbeddingVectorsREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Empty/oversized batch or a missing text",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "The embedding provider is disabled (Fallen8:Embedding:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "429": {
            "description": "The sensitive-endpoint rate limit was exceeded",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The embedding backend produced invalid output",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The embedding backend is unavailable",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/generate": {
      "get": {
        "tags": [
          "Benchmark"
        ],
        "summary": "Generates a random benchmark graph on top of the current one",
        "description": "Writes into the ADDRESSED namespace, and names it in the response. This is one of the\ntwo operations with no bare-URL alias to \"default\" (feature graph-namespaces): it grows\nexactly one graph, so a URL that names no namespace is a 400 rather than a silent write\ninto \"default\". The generated vertices are unlabeled and the edges carry edge property\n\"A\". A convenience for conjuring a graph to measure - GET /ns/{ns}/benchmark follows\nevery out-edge regardless of edge-property-id, so it benchmarks any loaded graph, not\nonly generated ones.",
        "parameters": [
          {
            "name": "nodeCount",
            "in": "query",
            "description": "Vertices to create (default 200)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "edgeCount",
            "in": "query",
            "description": "Out-edges added per vertex (default 5)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "distribution",
            "in": "query",
            "description": "Edge-target distribution: \"uniform\" (default) or\n    \"preferential\" (Barabási–Albert-style attachment — heavy-tailed in-degrees, so\n    PageRank/degree analytics at scale show real hubs)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "400": {
            "description": "Always: this route names no namespace, and the operation acts on one graph. Call the /ns/{ns} form instead.",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        },
        "deprecated": true
      }
    },
    "/graph": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Retrieves the complete graph data including vertices and edges",
        "parameters": [
          {
            "name": "maxElements",
            "in": "query",
            "description": "Maximum number of elements to return (default: 1000)",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 1000
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the graph data with vertices and edges",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/Graph"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/graphelement/{graphElementIdentifier}": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Retrieves a graph element (vertex or edge) by its identifier",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element to retrieve",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the graph element object",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/AGraphElement"
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "Graph element with the specified ID was not found",
            "content": {
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes a graph element (vertex or edge) from the graph",
        "description": "Sample request:\n\n    DELETE /graphelement/123",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element to remove",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Graph element removal accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Malformed request (e.g. a non-integer element id). (A non-existent graph element is NOT a 400: an out-of-range id → 500, an in-range/absent id is a no-op → 202.)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      }
    },
    "/graphelement/{graphElementIdentifier}/embedding/{embeddingName}": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Sets (or replaces) a named embedding on a graph element",
        "description": "The element is the source of truth for its embedding (feature element-embeddings):\nthe write is WAL-durable element state, and every vector index BOUND to this\nembedding name updates its projection on commit - no separate index add. Replace\nsemantics: one current vector per name.\n\nSample request:\n\n    PUT /graphelement/42/embedding/default\n    { \"vector\": [0.12, -0.5, 0.33] }",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "embeddingName",
            "in": "path",
            "description": "The embedding name (letters, digits, '_', '-'; max 64 chars)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The embedding vector",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingWriteSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingWriteSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Embedding write accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Invalid embedding name, missing/empty vector, non-finite components, a dimension conflicting with a vector index bound to this name, or a zero-norm vector while a bound Cosine index exists",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The graph element does not exist",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      },
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes a named embedding from a graph element",
        "description": "Bound vector indices purge the element's projection on commit. Removing an absent\nembedding is a committed no-op, matching the property surface.",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "embeddingName",
            "in": "path",
            "description": "The embedding name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Embedding removal accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Invalid embedding name",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The graph element does not exist",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      },
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets a named embedding of a graph element",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "embeddingName",
            "in": "path",
            "description": "The embedding name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The stored embedding",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ElementEmbeddingREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid embedding name",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The graph element does not exist or carries no embedding of that name",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/graphelement/{graphElementIdentifier}/{propertyIdString}": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Sets a property on a graph element (vertex or edge), adding it or replacing its value",
        "description": "REPLACE semantics (feature platform-integrity-audit W2): writing a key that already exists\noverwrites it. Until W2 this route ran on the add path, which is \"insert, or verify the\nexisting value is equal\" and rolls back a value CHANGE - so this route, documented as\n\"adds or updates\", could not update: it answered 500 when waited and, at the default\nwaitForCompletion=false, 202 Accepted while discarding the write. Re-writing the value the\nelement already holds is a TRUE no-op (no modification-date bump, no change-feed event), so\nre-asserting unchanged state costs nothing observable. To change several properties\natomically, use PUT /graphelements/properties.\n\nSample request:\n\n    PUT /graphelement/123/age\n    {\n       \"propertyValue\": 35,\n       \"fullQualifiedTypeName\": \"System.Int32\"\n    }",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "propertyIdString",
            "in": "path",
            "description": "The ID/key of the property",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Property value specification",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Property write accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Malformed request body / invalid property specification. (A non-existent graph element is NOT a 400: an out-of-range id rolls back with an internal error → 500, and an in-range/absent id is a no-op → 202.)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      },
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes a property from a graph element (vertex or edge)",
        "description": "Sample request:\n\n    DELETE /graphelement/123/age",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "propertyIdString",
            "in": "path",
            "description": "The ID/key of the property to remove",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Property removal accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Malformed request (e.g. a non-integer element id). (A non-existent element/property is NOT a 400: an out-of-range id → 500, an in-range/absent id is a no-op → 202.)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      }
    },
    "/graphelements": {
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes many graph elements in ONE atomic transaction (feature platform-integrity-audit)",
        "description": "The batch removal path. The whole batch is range-checked before anything is removed, so an\nout-of-range id removes nothing; an in-range but already-removed id is a committed no-op,\nmatching the single-element route. Removing a vertex cascades to its edges exactly as the\nsingle route does.\n\nSample request:\n\n    DELETE /graphelements\n    [1, 2, 3]",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The ids to remove",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Batch accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "A null list",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waited)"
          }
        }
      }
    },
    "/graphelements/get": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Reads many graph elements by id in ONE request (feature platform-integrity-audit)",
        "description": "The read-side companion to the batch write path. Every scan and every batch write returns IDS\nONLY, and the only other many-element reads are a whole-namespace dump (GET /graph) and a\nwhole-namespace export - so a caller holding several hundred resolved ids that needs their\ncurrent property values, which is what \"write only if something actually changed\" requires,\npreviously had one sequential request per element or a full dump per poll.\n\nEach element is returned WITHOUT its adjacency: this answers \"what does it hold now\", and\nshipping every edge id of every element would dominate the payload. Ask GET /vertex/{id} for\none element's adjacency.\n\nProperty values use the same invariant string form as every other read, so a value returned\nhere can be written straight back unchanged - which is what makes a value-level comparison\nmeaningful rather than a source of spurious differences.\n\nIds that resolve to no live element come back in \"notFound\" rather than being silently\nabsent, because \"gone\" and \"has no properties\" are different conclusions.\n\nSample request:\n\n    POST /graphelements/get\n    [1, 2, 3]",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The ids to read",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The elements that exist, plus the ids that do not",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/GraphElementBatchREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "A null list, or more ids than the page cap allows",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/graphelements/properties": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Sets and/or removes many properties across many elements in ONE atomic transaction (feature platform-integrity-audit)",
        "description": "The batch write path for properties, and the only ATOMIC way to change a value: the\nsingle-element routes are one transaction each, so a reconciliation spanning several\nproperties could previously be interrupted half-applied, leaving the element in a state no\nsource describes. REPLACE semantics: an existing key is overwritten, and the last write for\nan (element, key) pair in one batch wins.\n\nA semantically empty write is a TRUE no-op - setting a key to the value it already holds, or\nremoving one that is already absent, bumps no modification date and publishes no change-feed\nevent - so re-asserting unchanged state produces no observable mutation and a replayed batch\nis idempotent.\n\nSample request:\n\n    PUT /graphelements/properties\n    [\n      { \"graphElementId\": 42, \"propertyId\": \"ip\", \"fullQualifiedTypeName\": \"System.String\", \"propertyValue\": \"10.0.0.9\" },\n      { \"graphElementId\": 42, \"propertyId\": \"stale\", \"remove\": true }\n    ]",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The property writes. Each is a set, or a removal when `remove` is true.",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PropertyWriteSpecification"
                }
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PropertyWriteSpecification"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Batch accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "A null list, a null write, an unknown type name, or an unconvertible value. Nothing is enqueued.",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waited)"
          }
        }
      }
    },
    "/index": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Creates a new index for the graph",
        "description": "Sample request:\n\n    POST /index\n    {\n       \"uniqueId\": \"nameIndex\",\n       \"pluginType\": \"DictionaryIndex\",\n       \"pluginOptions\": {\n          \"propertyId\": \"name\",\n          \"type\": \"System.String\"\n       }\n    }",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Plugin specification with index type and configuration options",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns true if the index was created; false if the index type is unknown, the name already exists, or initialization failed (see server logs)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/index/backfill/{indexId}": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Repopulates an index from a property's values across the live elements (feature platform-integrity-audit)",
        "description": "Index content is DERIVED state with no durability of its own: index writes are neither\nsingle-writer transactions nor WAL-logged, so index state is snapshot-only. After a hard crash\nthe elements replay from the WAL but every index key added since the last checkpoint is gone,\nand three ORDINARY operations drop an index while a client is running - a tabula rasa, loading\na save game, and a per-index serialization failure that drops it from the checkpoint manifest.\nThis is the repair path, and it is the only one available to a client that is not in-process.\n\nDefault mode is a REPAIR: add-only and idempotent, so it is safe to run on every start and\nnothing is ever briefly missing. It does not remove keys that element state no longer\njustifies. Pass \"replace\": true for an EXACT rebuild, which wipes the index first and\ntherefore has a window in which a concurrent scan sees nothing.\n\nThe route is literal-first (/index/backfill/{indexId}, not /index/{indexId}/backfill) because\nPUT /index/vector/{indexId} already occupies three segments and index names are unvalidated\ncaller strings: an index legitimately named \"vector\" would otherwise be unreachable here.\n\nPass \"prefix\": true when propertyId is a KEY PREFIX rather than one exact key: every property\nwhose key starts with it is then indexed by its value, so one element can contribute several\nentries. That is the mode a client needs whose values are spread across dense ordinal keys\n($identity:0, $identity:1, ...), because the property surface accepts scalars and no array: an\nexact-key repair would restore only the first value of each element, leaving it findable by\none and invisible by the rest.\n\nSample request:\n\n    POST /index/backfill/claimIndex\n    {\n       \"propertyId\": \"$identity\",\n       \"replace\": false\n    }\n\nSample request, prefix mode:\n\n    POST /index/backfill/claimIndex\n    {\n       \"propertyId\": \"$identity:\",\n       \"prefix\": true\n    }",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The registered index to repopulate",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Which property supplies the keys, and whether to rebuild exactly",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexBackfillSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexBackfillSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The outcome: how many live elements were scanned and indexed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/IndexRebuildREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "No such index, a missing property id, or an index that cannot take arbitrary keys (vector, spatial, or a bound vector index that maintains itself)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/index/vector/{indexId}": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Adds (or replaces) an element's embedding vector in a vector index",
        "description": "One vector per element: adding again replaces. The generic PUT /index/{indexId} add\npath cannot express a float[] key, which is why the vector family has this typed\nendpoint (like fulltext and spatial have theirs).\n\nSample request (explicit mode):\n\n    PUT /index/vector/myEmbeddings\n    {\n       \"graphElementId\": 42,\n       \"vector\": [0.12, -0.5, 0.33]\n    }\n\nSample request (property mode - reads the element's float[] property):\n\n    PUT /index/vector/myEmbeddings\n    {\n       \"graphElementId\": 42,\n       \"propertyId\": \"embedding\"\n    }",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The ID of the vector index",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The element and its vector - explicit (\"vector\") or read from a float[] property (\"propertyId\")",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VectorIndexAddSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VectorIndexAddSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The vector was indexed (add-again replaced the previous vector)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Not a vector index, neither/both modes supplied, wrong dimension, NaN/Infinity components, zero-norm vector under Cosine, or the named property is missing / not a float[]",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The index or the graph element does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/index/{indexId}": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Adds a graph element to an existing index",
        "description": "Sample request:\n\n    PUT /index/nameIndex\n    {\n       \"graphElementId\": 123,\n       \"key\": {\n         \"propertyValue\": \"John Smith\",\n         \"fullQualifiedTypeName\": \"System.String\"\n       }\n    }",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The ID of the index",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Specification containing graph element ID and key information",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexAddToSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexAddToSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns true if the element was added; false if the index or the graph element does not exist (a miss is reported as 200 with a false body, not a 404)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Deletes an index from the system",
        "description": "Sample request:\n\n    DELETE /index/nameIndex",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The ID of the index to delete",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns true if the index was deleted; false if no index with that name exists (a miss is reported as 200 with a false body, not a 404)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/index/{indexId}/propertyValue": {
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes a key from an index",
        "description": "Sample request:\n\n    DELETE /index/nameIndex/propertyValue\n    {\n       \"propertyValue\": \"John Smith\",\n       \"fullQualifiedTypeName\": \"System.String\"\n    }",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The ID of the index",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The property specification representing the key to remove",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns true if the key was removed; false if the index does not exist (a miss is reported as 200 with a false body)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The property specification was missing or malformed, or the index is a vector index bound to an embedding (it maintains its own content)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/index/{indexId}/{graphElementId}": {
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes a graph element from an index",
        "description": "Sample request:\n\n    DELETE /index/nameIndex/123",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The ID of the index",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "graphElementId",
            "in": "path",
            "description": "The ID of the graph element to remove",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns true if the element was removed; false if the index or the graph element does not exist (a miss is reported as 200 with a false body, not a 404)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The index is a vector index bound to an embedding (it maintains its own content; remove the element embedding instead)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/integrations/job": {
      "post": {
        "tags": [
          "Integrations"
        ],
        "summary": "Runs one integration job and returns its report (feature integrations)",
        "description": "A job carries everything one run needs: which provider, the identity it asserts\n    as, the namespace to write into, the provider's settings, and its credentials as VALUES in\n    credentialValues. The runtime stores none of them: it holds a credential for the run that\n    needs it and drops it when the run ends, keeps no job history, and no route reads a job\n    back. Those values travel through here in the request body, so serve this API over TLS.\n    The call is synchronous: the source is read, what it\n    said is written, the report comes back, and the runtime keeps nothing. A job that ran and\n    failed still answers 200 with the failure on its report; one that could not be run at all\n    is the runtime's 400 or its 409 (one job at a time per identity).\n    The request and response bodies are the RUNTIME's own contract and are deliberately\n    untyped here, so there is exactly one definition of them:\n    https://docs.fallen-8.com/integrations/. The caller owns the stability of the\n    integration instance id, which nothing can validate: a run under an identity that\n    integration has not always used withdraws and deletes what the real one claimed.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the proxied call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/JsonElement"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/JsonElement"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The job report, including a run that failed",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "The runtime refused the job as written, its own message saying why",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Integrations are disabled (Fallen8:Integrations:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "A job is already running under this identity",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "503": {
            "description": "No runtime is configured, or it did not answer",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/integrations/providers": {
      "get": {
        "tags": [
          "Integrations"
        ],
        "summary": "Lists the integrations this instance's runtime can run (feature integrations)",
        "description": "Each entry is a provider descriptor: its id, what it reads, its settings as data\n    (key, label, kind, required, help), the entity kinds, claim types and relation types it\n    produces, and whether it can observe complete state. A settings form renders from that\n    data, so adding an integration needs no client change.\n    The response body is the RUNTIME's own contract and is deliberately untyped here, so\n    there is exactly one definition of it: see\n    https://docs.fallen-8.com/integrations/. A provider is C# compiled into the\n    runtime, so this list changes only when that deployable does.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The provider catalog, as the runtime describes it",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "The runtime refused the request, its own message saying why",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Integrations are disabled (Fallen8:Integrations:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The runtime reported a conflict",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "503": {
            "description": "No runtime is configured, or it did not answer",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/integrations/snapshot/validate": {
      "post": {
        "tags": [
          "Integrations"
        ],
        "summary": "Validates a snapshot document without running anything (feature integrations)",
        "description": "An authoring aid: it says which envelope errors would refuse the whole document\n    and which entities would be skipped, with the diagnostic code for each, so somebody writing\n    a provider gets the verdict on a document before wiring a source to it. Nothing is written\n    and no source is read.\n    The request and response bodies are the RUNTIME's own contract and are deliberately\n    untyped here, so there is exactly one definition of them:\n    https://docs.fallen-8.com/integrations/.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the proxied call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/JsonElement"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/JsonElement"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The validation verdict and its diagnostics",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "The runtime refused the request, its own message saying why",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Integrations are disabled (Fallen8:Integrations:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The runtime reported a conflict",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "503": {
            "description": "No runtime is configured, or it did not answer",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/integrations/vocabulary": {
      "get": {
        "tags": [
          "Integrations"
        ],
        "summary": "Returns the identifier vocabulary the runtime resolves claims against (feature integrations)",
        "description": "One entry per identifier type: its strength (only a strong one may resolve), its\n    uniqueness scope, how a value is canonicalised and what values are accepted. It is data a\n    provider author reads before declaring a claim type, and it is embedded in the runtime\n    rather than mounted, so a deployment cannot silently change whether a claim resolves.\n    The response body is the RUNTIME's own contract and is deliberately untyped here, so\n    there is exactly one definition of it: see\n    https://docs.fallen-8.com/integrations/.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The vocabulary, as the runtime describes it",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "The runtime refused the request, its own message saying why",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Integrations are disabled (Fallen8:Integrations:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The runtime reported a conflict",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "503": {
            "description": "No runtime is configured, or it did not answer",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/load": {
      "put": {
        "tags": [
          "Admin"
        ],
        "summary": "Loads a Fallen-8 database from a saved file",
        "description": "Sample request:\n\n    PUT /load\n    {\n       \"startServices\": true,\n       \"saveGameLocation\": \"C:/Fallen8/database.f8s\"\n    }",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Load specification including file path and service start options",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/LoadSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/LoadSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Database loaded successfully"
          },
          "400": {
            "description": "Invalid load specification or file not found",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The load transaction was rolled back and did not complete"
          }
        }
      }
    },
    "/ns": {
      "get": {
        "tags": [
          "Namespaces"
        ],
        "summary": "Lists all namespaces with their counts and the configured ceiling",
        "description": "A namespace that is cataloged but NOT loaded in this process is listed too, with state\n\"notLoaded\" and absent (null) vertex/edge counts (feature namespace-startup-load) - the\nlist is the inventory, not the residency filter.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the namespace list (always includes \"default\")",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespacesREST"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{name}": {
      "get": {
        "tags": [
          "Namespaces"
        ],
        "summary": "Gets one namespace",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The namespace name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the namespace",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespaceREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespaceREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespaceREST"
                }
              }
            }
          },
          "404": {
            "description": "No namespace with this name exists",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Namespaces"
        ],
        "summary": "Creates a new, empty namespace",
        "description": "The namespace is immediately ready: it owns a fresh Fallen-8 engine with its own\nvertices, edges, indices, subgraphs, stored queries, and change feed. Its routes live\nunder /ns/{name}/… . The 422 body carries the configured limit as the \"maxNamespaces\"\nextension member.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The namespace name (permissive: up to 63 chars, any case/spaces/Unicode; not \".\"/\"..\" or containing \"/\" \"\\\" or control chars — it is a URL path segment)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "The namespace was created",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespaceREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespaceREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespaceREST"
                }
              }
            }
          },
          "400": {
            "description": "The name is empty/whitespace-padded, too long, \".\"/\"..\", or contains \"/\", \"\\\", or a control character",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "A namespace with this name already exists",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "The configured Fallen8:Namespaces:MaxNamespaces ceiling is reached",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "The sensitive-endpoint rate limit was exceeded",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Namespaces"
        ],
        "summary": "Updates a namespace: rename it and/or set its plugin-registration or startup-load override",
        "description": "Rename is a pure metadata operation: the engine, its data, and its on-disk locations\n(keyed by the immutable namespace id) are untouched - only the URL address changes. The\nreserved \"default\" namespace cannot be RENAMED, but its plugin-registration override CAN\nbe set. Both overrides take \"enabled\"/\"disabled\"/\"inherit\" (\"inherit\" clears them):\n\"pluginRegistration\" overrides Fallen8:Security:EnableDynamicPluginLoading for this\nnamespace (feature plugin-registration), and \"loadOnStartup\" overrides\nFallen8:Namespaces:LoadOnStartup, i.e. whether the NEXT boot loads this namespace at all\n(feature namespace-startup-load) - it takes effect on restart and never loads or unloads\nthe running process's engine. The reserved \"default\" namespace is always loaded and\nrefuses \"loadOnStartup\" with 409. The whole update is applied atomically: every field is\nvalidated first, then all of them are persisted by one catalog write. Supply at least one\nfield.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The current namespace name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The update: an optional new name and/or either override",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/NamespaceUpdateSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/NamespaceUpdateSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The namespace was updated",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespaceREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespaceREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespaceREST"
                }
              }
            }
          },
          "400": {
            "description": "No field supplied, an invalid new name, or an unrecognized \"pluginRegistration\"/\"loadOnStartup\" value",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No namespace with this name exists",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The new name is already in use, or a rename or \"loadOnStartup\" of the reserved \"default\" namespace",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "The sensitive-endpoint rate limit was exceeded",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Namespaces"
        ],
        "summary": "Drops a namespace irreversibly",
        "description": "The namespace's in-memory graph, indices, and stored queries are gone and its live\non-disk state (the write-ahead log) is deleted — there is no undo. Checkpoint files are\nNOT deleted: they belong to save-game entries, which remain valid restore points\n(delete them via DELETE /savegames/{id}?deleteFiles=true). The reserved \"default\"\nnamespace cannot be dropped.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The namespace name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The namespace was dropped"
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No namespace with this name exists",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The namespace is \"default\"",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "The sensitive-endpoint rate limit was exceeded",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/ns/{name}/activate": {
      "post": {
        "tags": [
          "Namespaces"
        ],
        "summary": "Loads a cataloged namespace into the running process",
        "description": "The way back from an exclusion without a restart (feature namespace-startup-load): the\nnamespace's engine is constructed, its newest registered save game is restored and its\nwrite-ahead-log tail replayed on top, and only then does it start serving requests - so a\nfailed restore leaves it exactly as not-loaded as it was, and no request ever sees a\nhalf-loaded graph.\n\nIdempotent: activating a namespace that is already loaded is a 200 with\n\"activated\": false, never a conflict.\n\nIt does NOT change the persisted startup-load policy, because the two answer different\nquestions: this call answers for the running process, the policy answers for the next\nboot, which still honours it. To make it stick, PATCH /ns/{name} with \"loadOnStartup\":\n\"enabled\" as well.\n\nNamed \"activate\" because /ns/{name}/load already means \"restore a checkpoint into a\nnamespace\".",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The namespace name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The namespace is loaded (whether by this call or already)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/NamespaceActivationREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No namespace with this name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "It has checkpoint files no registered save game contains; the body names how to adopt them",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "429": {
            "description": "The sensitive-endpoint rate limit was exceeded",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "Its checkpoint could not be restored; it stays not loaded and its files are untouched",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/analytics/algorithms": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Lists the discovered analytics algorithm plugins",
        "description": "The five built-ins are PAGERANK, WCC, LABELPROPAGATION, DEGREE and TRIANGLECOUNT;\nIGraphAnalyticsAlgorithm plugins compiled into the shipped assemblies appear here too\n(the same discovery as path and subgraph algorithms), as do the addressed namespace's\nruntime-registered analytics plugins (POST /plugins/algorithm). Every name listed here\nis invocable through POST /analytics/{algorithmName}.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The available algorithms with their descriptions",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/analytics/{algorithmName}": {
      "post": {
        "tags": [
          "Analytics"
        ],
        "summary": "Runs an analytics algorithm over the graph",
        "description": "Runs synchronously under the wall-clock budget (default 30 s). Score algorithms\nreturn the top-K vertices by score (descending, ascending id tie-break); partition\nalgorithms return partition summaries (largest first). The FULL per-vertex result's\ndelivery vehicle is the opt-in property write-back (\"writeBack\": true), which lands\nthrough chunked plugin write transactions; write-back durability is SNAPSHOT-ONLY -\na WAL-only replay with no intervening save loses the written properties (re-run to\nrestore, overwrite is idempotent).\n\nReaching the iteration cap is a NORMAL 200 (converged=false, values usable), as is\nbudget exhaustion after at least one completed pass (budgetExhausted=true).\n\nSample request:\n\n    POST /analytics/PAGERANK\n    {\n       \"vertexLabel\": \"person\",\n       \"maxResults\": 10,\n       \"parameters\": { \"DampingFactor\": 0.85 }\n    }",
        "parameters": [
          {
            "name": "algorithmName",
            "in": "path",
            "description": "The plugin name (e.g. PAGERANK, WCC, LABELPROPAGATION, DEGREE, TRIANGLECOUNT)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Scoping, budgets, algorithm parameters, result bound and the optional write-back",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The run's result (including converged=false / budgetExhausted=true partials that carry usable values)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsResultREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsResultREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsResultREST"
                }
              }
            }
          },
          "400": {
            "description": "Unknown direction/parameter values, out-of-ceiling maxIterations/maxResults/timeBudgetSeconds, or a bad write-back property key",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Unknown algorithm name",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "408": {
            "description": "The wall-clock budget exhausted with no usable result",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "All concurrent-run slots are taken",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/ns/{ns}/analytics/{algorithmName}/partition/{partitionId}": {
      "post": {
        "tags": [
          "Analytics"
        ],
        "summary": "Returns one partition's membership page from a fresh run of a partition algorithm",
        "description": "Analytics runs are one-shot (no job store), so the page comes from a FRESH run with\nthe same specification - deterministic for a quiescent graph. Use offset+maxResults\nto page; the page ceiling is 10000 rows.",
        "parameters": [
          {
            "name": "algorithmName",
            "in": "path",
            "description": "A partition algorithm (WCC or LABELPROPAGATION)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "partitionId",
            "in": "path",
            "description": "The partition id from a previous run's summaries",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The same run specification, plus the page offset",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The membership page",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PartitionMembersREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PartitionMembersREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PartitionMembersREST"
                }
              }
            }
          },
          "400": {
            "description": "Invalid specification, a negative offset, writeBack (not supported here), or a score algorithm",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Unknown algorithm or a partition id the run did not produce (including an empty scope)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "408": {
            "description": "The wall-clock budget exhausted with no usable result",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "All concurrent-run slots are taken",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/ns/{ns}/benchmark": {
      "get": {
        "tags": [
          "Benchmark"
        ],
        "summary": "Runs the edge-traversal benchmark and returns structured statistics",
        "description": "Traverses the ADDRESSED namespace, and like GET /ns/{ns}/generate it has no bare-URL\nalias to \"default\" (feature graph-namespaces): measuring a graph the caller did not name\nwould report the wrong graph's throughput as if it were theirs. It follows every outgoing\nedge of every vertex regardless of edge-property-id, so it works on any loaded graph and\nreports edges traversed per second (not query latency).",
        "parameters": [
          {
            "name": "iterations",
            "in": "query",
            "description": "Number of timed iterations (default 1000, at most\n    Fallen8:Security:BenchmarkMaxIterations; the default is clamped to that ceiling)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The benchmark statistics",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/BenchmarkResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Empty graph, non-positive or non-numeric iteration count, a count\n    above Fallen8:Security:BenchmarkMaxIterations, or a bare URL naming no namespace",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/bulk/export": {
      "get": {
        "tags": [
          "Bulk"
        ],
        "summary": "Streams the graph (or a filtered subset) as newline-delimited JSON.",
        "description": "The stream is fallen8-jsonl version 2: one meta line (format version + exact counts),\nthen vertex lines, then edge lines. Edges whose endpoints are not both in the exported\nvertex set are omitted, so EVERY exported file is internally consistent and importable\nby construction. Element embeddings export as their reserved System.Single[]\nproperties (the version-2 type).\n\nCONSISTENCY (honest): this is data interchange, not a crash-consistent backup. Reads\nare lock-free; a write committed during the export may or may not appear. The\nguarantee is internal consistency plus \"everything committed before the export began\nis present\" (subject to the filters). For a point-in-time backup, quiesce writes\nor use the save-game machinery. The same contract covers a property that an\nembedded/plugin writer adds DURING the stream: if it is not exportable it is omitted\nfrom its element rather than aborting the response (the REST write path cannot create\nsuch properties; the pre-stream 422 covers everything present at capture).",
        "parameters": [
          {
            "name": "vertexLabel",
            "in": "query",
            "description": "Optional: export only vertices with exactly this label",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "edgeLabel",
            "in": "query",
            "description": "Optional: export only edges with exactly this label",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "edgePropertyId",
            "in": "query",
            "description": "Optional: export only edges of exactly this type (their edgePropertyId); combines with edgeLabel as AND",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The NDJSON stream (application/x-ndjson)",
            "content": {
              "application/x-ndjson": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/x-ndjson; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/x-ndjson": { }
            }
          },
          "422": {
            "description": "An element carries a property that cannot be exported: a null\n     value, a runtime type outside the exportable allow-list, or a String/Char holding an\n     unpaired surrogate (invalid UTF-16). The body names the element, the property and which\n     of the three it was. Sent BEFORE any streaming, so a failed export is never a\n     half-written file",
            "content": {
              "application/x-ndjson; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/x-ndjson": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/bulk/import": {
      "post": {
        "tags": [
          "Bulk"
        ],
        "summary": "Imports a fallen8-jsonl stream into an EMPTY graph, assigning fresh engine ids.",
        "description": "The body is read as a stream and processed line by line; lines batch into large\ncreate transactions (Fallen8:BulkIO:ImportBatchSize per transaction = one WAL entry +\none fsync each). File ids are remapped unconditionally: they are references within the\nfile, resolved for edge endpoints, never preserved as engine ids. A leading meta line\nis optional (grep-filtered subset files stay valid); when present, its counts act as a\ntruncation guard.\n\nFAIL-FAST (honest): the first invalid line aborts the import with its exact line\nnumber. Batches committed before the failure STAY COMMITTED (each batch is atomic and\nWAL-logged; the file is not one transaction) - the error body reports the committed\ncounts, and because import requires an empty graph, recovery is always \"/tabularasa,\nfix the line, retry\".\n\nNOTE on the body cap: when Fallen8:BulkIO:MaxImportRequestBytes is configured, a real\nKestrel host may enforce it at the transport layer and answer 413 before this action's\nown check runs - the status is the same, but the problem body with committed counts is\nonly guaranteed when the application-level check fires first.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The import completed; the body carries created counts",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportResultREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportResultREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportResultREST"
                }
              }
            }
          },
          "400": {
            "description": "A line was invalid (malformed JSON, unknown fields, bad property\n     type/value, duplicate file id, unresolved edge endpoint, over-long line, meta-count\n     mismatch) - the problem body carries lineNumber and the committed counts",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The graph is not empty (import requires an empty target; use\n     /tabularasa or a fresh instance)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "413": {
            "description": "The request body exceeds the configured Fallen8:BulkIO:MaxImportRequestBytes",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "A batch transaction faulted internally; committed counts are reported"
          }
        }
      }
    },
    "/ns/{ns}/changefeed": {
      "get": {
        "tags": [
          "ChangeFeed"
        ],
        "summary": "Streams committed graph mutations as Server-Sent Events, with declarative server-side filtering and catch-up.",
        "description": "The stream format per event:\n\n    id: &lt;epoch-guid&gt;:&lt;seq&gt;\n    event: &lt;kind&gt;\n    data: {\"seq\":4712,\"ts\":\"2026-07-15T12:34:56.789Z\",\"kind\":\"propertySet\",\"element\":\"vertex\",\"id\":42,\"label\":\"person\",\"key\":\"name\"}\n\nDelivery: events arrive in commit order (ascending seq), at most once per connection.\nA comment line (\": keepalive\") is written every KeepAliveSeconds so proxies do not idle\nthe stream out. Filters combine with AND across dimensions and OR within one dimension;\nresync events bypass every filter (continuity loss must always reach the client). On\nany resync, re-fetch the state you display; for reason trim/tabulaRasa/load, treat all\nheld element ids as invalid.\n\nThe feed compiles no C# at all - filters are declarative parameters, never compiled\ncode. Payloads never contain property values;\nre-fetch the element when the value is needed.",
        "parameters": [
          {
            "name": "kinds",
            "in": "query",
            "description": "Event kinds to include (repeatable or comma-separated): vertexCreated, vertexRemoved, edgeCreated, edgeRemoved, propertySet, propertyRemoved. Unset = all kinds. resync events always pass.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "elements",
            "in": "query",
            "description": "Element types to include: vertex, edge. Unset = both.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "labels",
            "in": "query",
            "description": "Element labels to include (exact, case-sensitive). Unset = any label. An unlabeled element never matches a labels filter.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "keys",
            "in": "query",
            "description": "Property keys to include (exact, case-sensitive). Only property events carry a key, so setting this excludes create/remove events.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "since",
            "in": "query",
            "description": "Catch-up position: the last seen SSE id (\"&lt;epoch&gt;:&lt;seq&gt;\") or a bare sequence number. Buffered missed events replay first; a position outside the buffered window (or from another process epoch) starts the stream with resync(seekOutOfRange). The Last-Event-ID header (native EventSource reconnect) is honoured when this parameter is unset.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The SSE stream (text/event-stream); it stays open until the client disconnects",
            "content": {
              "text/event-stream": { }
            }
          },
          "400": {
            "description": "An unknown kind/element value or a malformed since position",
            "content": {
              "text/event-stream; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/event-stream": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/event-stream; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/event-stream": { }
            }
          },
          "503": {
            "description": "The change feed is disabled (Fallen8:ChangeFeed:Enabled=false), the concurrent subscriber limit (Fallen8:ChangeFeed:MaxSubscribers) is reached, or the addressed namespace is not loaded in this process (namespaceState \"notLoaded\")",
            "content": {
              "text/event-stream": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/document": {
      "post": {
        "tags": [
          "Document"
        ],
        "summary": "Ingests a document file into the graph",
        "description": "Asynchronous (feature semantic-layer): the Document vertex is created first (status\n`processing`, visible on the change feed) and the pipeline - convert, chunk,\nembed, write, then additive NLP enrichment into the entity graph - runs off the request\nthread on a single global queue; the row flips to `indexed` when it finishes. Any\nfailure leaves exactly one failed Document vertex and zero chunks.\nOnly what is knowable BEFORE the hand-off can answer with an HTTP status. Everything the\nworker discovers later - the page cap (`Fallen8:Ingestion:MaxPages`), the per-document\nchunk cap (`MaxChunksPerDocument`), a conversion that yields no text, and any\nembedding-backend fault - cannot, because this call has already answered 202. Those\noutcomes flip the queued document to `failed` with the reason on its status, so a\ncaller learns them from the change feed or from GET /document/{documentId}, never from\nthis response.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts conversion/embedding when the request is cancelled",
          "content": {
            "multipart/form-data; ver=0.1": {
              "schema": {
                "type": "object",
                "allOf": [
                  {
                    "type": "object",
                    "properties": {
                      "file": {
                        "$ref": "#/components/schemas/IFormFile"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "embed": {
                        "type": "boolean"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "sourceUri": {
                        "type": "string"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "replaceDocumentId": {
                        "pattern": "^-?(?:0|[1-9]\\d*)$",
                        "type": [
                          "integer",
                          "string"
                        ],
                        "format": "int32"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "propertiesJson": {
                        "type": "string"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "properties": {
                      "linkJson": {
                        "type": "string"
                      }
                    }
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "The document was accepted for asynchronous ingestion; the stub starts `processing` and flips to `indexed` on the change feed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSummaryREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Unsupported format, a reserved tag key, or an invalid link allowlist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled), or embed=true while the embedding provider is off",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The replace target does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "Duplicate content hash, or an index shape/model conflict",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "413": {
            "description": "The upload exceeds Fallen8:Ingestion:MaxUploadBytes",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "428": {
            "description": "The semantic layer is not bound; create the required indices first (POST /document/binding/ensure)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "503": {
            "description": "No docling endpoint is configured for a binary format, or the ingestion queue is full",
            "content": {
              "application/json": { }
            }
          },
          "507": {
            "description": "The namespace chunk ceiling is reached (Fallen8:Ingestion:MaxChunksPerNamespace)",
            "content": {
              "application/json": { }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Document"
        ],
        "summary": "Lists the namespace's documents",
        "description": "Summaries plus the chunk budget (FR-14) and the active embedding model,\n    so stale documents (FR-16) are visible in one call.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The documents, chunk usage and ceiling",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentListREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/document/binding": {
      "get": {
        "tags": [
          "Document"
        ],
        "summary": "Reports the semantic layer's index binding state",
        "description": "The three indices the layer uses (vector, fulltext, entity), whether each\n    exists and is usable, and whether ingestion is ready. The layer never creates an index\n    implicitly (FR-7); bind them with POST /document/binding/ensure.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The binding state",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentBindingREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/document/binding/ensure": {
      "post": {
        "tags": [
          "Document"
        ],
        "summary": "Creates the required indices, binding the semantic layer",
        "description": "The explicit, idempotent bind (FR-7): creates the vector, fulltext and entity\n    indices the configuration requires and that do not yet exist, then reports the state.\n    This is the only path that creates a bound index; ingestion answers 428 until it runs.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The binding state after creation (Ready when all required indices exist)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentBindingREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "An index with a bound id exists but is the wrong shape",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/document/entities": {
      "get": {
        "tags": [
          "Document"
        ],
        "summary": "Lists the entities the corpus mentions",
        "description": "Deduplicated Entity vertices (feature semantic-layer) ranked by mention count.\n    Each id is a valid /path or /subgraph seed. A bounded page; `total` reports the full\n    match count.",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "description": "Optional filter on the raw NLP label, compared case-insensitively (e.g. PERSON/ORG/GPE)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contains",
            "in": "query",
            "description": "Optional case-insensitive substring the entity text must contain",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Page cap (default 200, max 10000)",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 200
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The entity page and the total match count",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentEntityListREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/document/search": {
      "post": {
        "tags": [
          "Document"
        ],
        "summary": "Fused chunk search: dense kNN plus lexical fulltext, reciprocal rank fusion",
        "description": "The default mode fuses both sides with RRF (k=60, candidate depth max(50, 4k));\nwhen one side is unavailable (provider off, index absent) the answer degrades and\n`modeUsed` says so. Hits are live Chunk vertices - use them directly as\n/path or /subgraph seeds. Scores: RRF when fused, raw kNN when dense, match count\nwhen lexical.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the query embedding when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/DocumentSearchSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/DocumentSearchSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The hits (flat, or grouped per document)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSearchResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid k/window/mode, no usable query, a dimension mismatch, or the requested side is unavailable",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The vector index's dimension or declared model identity conflicts with the active provider",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The embedding backend produced invalid output",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The embedding backend is unavailable",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/document/text": {
      "post": {
        "tags": [
          "Document"
        ],
        "summary": "Ingests raw text or markdown into the graph",
        "description": "The sidecar-free path (FR-3): markdown chunks along its headings, plain\n    text as one bounded section. Same lifecycle and failure semantics as the file route.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts embedding when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IngestTextSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IngestTextSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "The document was accepted for asynchronous ingestion; the stub starts `processing` and flips to `indexed` on the change feed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSummaryREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Missing name/text, an unknown format, a reserved tag key, or an invalid link allowlist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled, or embed=true while the embedding provider is off",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The replace target does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "Duplicate content hash, or an index shape/model conflict",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "413": {
            "description": "The text exceeds Fallen8:Ingestion:MaxUploadBytes",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "428": {
            "description": "The semantic layer is not bound; create the required indices first (POST /document/binding/ensure)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "503": {
            "description": "The ingestion queue is full",
            "content": {
              "application/json": { }
            }
          },
          "507": {
            "description": "The namespace chunk ceiling is reached",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/document/{documentId}": {
      "get": {
        "tags": [
          "Document"
        ],
        "summary": "Gets one document with its chunks",
        "description": "Chunks carry previews and provenance; the full text stays one home, the\n    chunk vertex's `text` property (graph element routes).",
        "parameters": [
          {
            "name": "documentId",
            "in": "path",
            "description": "The document vertex id",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document and its chunks in document order",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetailREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The id is not a Document vertex",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No vertex with this id",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Document"
        ],
        "summary": "Deletes a document, its chunks and all their edges",
        "description": "One transactional removal (FR-7): edges (including `mentions` and\n    user-drawn ones onto chunks) cascade with the vertices; the fulltext mirror is\n    cleaned alongside.",
        "parameters": [
          {
            "name": "documentId",
            "in": "path",
            "description": "The document vertex id",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "Wait for the removal to commit",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "The removal was enqueued (and committed when waitForCompletion)",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "The id is not a Document vertex",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Ingestion is disabled (Fallen8:Ingestion:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No vertex with this id",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/edge": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Creates a new edge between two vertices in the graph",
        "description": "Sample request (edgePropertyId is the edge's type - the adjacency group traversals\nkey on; label is an optional, orthogonal category tag):\n\n    PUT /edge\n    {\n       \"sourceVertex\": 1,\n       \"targetVertex\": 2,\n       \"edgePropertyId\": \"knows\",\n       \"label\": \"friendship\",\n       \"creationDate\": 0,\n       \"properties\": [\n         {\n           \"propertyId\": \"since\",\n           \"propertyValue\": \"2024-01-01\",\n           \"fullQualifiedTypeName\": \"System.DateTime\"\n         }\n       ]\n    }",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The edge specification containing source, target and property information",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EdgeSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EdgeSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Edge creation accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Invalid edge specification",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "A referenced source or target vertex does not exist (only when waitForCompletion is true)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      }
    },
    "/ns/{ns}/edge/count": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "Gets the total number of edges in the database",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the number of edges",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              },
              "application/json": { }
            }
          }
        },
        "security": [ ]
      }
    },
    "/ns/{ns}/edge/{edgeIdentifier}": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Retrieves an edge from the graph by its identifier",
        "parameters": [
          {
            "name": "edgeIdentifier",
            "in": "path",
            "description": "The ID of the edge to retrieve",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the edge object",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/Edge"
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "Edge with the specified ID was not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/edge/{edgeIdentifier}/source": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the source vertex ID for a specific edge",
        "parameters": [
          {
            "name": "edgeIdentifier",
            "in": "path",
            "description": "The ID of the edge",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the source vertex ID",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Edge with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/edge/{edgeIdentifier}/target": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the target vertex ID for a specific edge",
        "parameters": [
          {
            "name": "edgeIdentifier",
            "in": "path",
            "description": "The ID of the edge",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the target vertex ID",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Edge with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/edges": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Creates many edges in ONE atomic transaction (feature mcp-followups)",
        "description": "The batch write path. If any referenced source/target vertex is missing, the WHOLE batch\nrolls back atomically and answers 404 (nothing is wired). A waited-on call returns the\nassigned edge ids. Edges reference vertices that already exist; to link vertices created in\nthe same session, create the vertices first, read their ids, then create the edges.",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits and returns the assigned ids in input order",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The edges to create (each references existing source/target vertex ids)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EdgeSpecification"
                }
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EdgeSpecification"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the assigned edge ids in input order (waitForCompletion=true)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "202": {
            "description": "Batch accepted (waitForCompletion=false)",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "A null list, or a null/invalid edge specification",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "A referenced source or target vertex does not exist (only when waited)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waited)",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/embedding/element": {
      "post": {
        "tags": [
          "Embedding"
        ],
        "summary": "Embeds a text and stores it as the element's named embedding",
        "description": "The generated vector is written through the element-embeddings surface together\nwith the provider's model-identity stamp (one atomic transaction); a vector index\nbound to the name updates its projection on commit.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the provider call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedElementSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedElementSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The embedding was generated and committed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Missing/oversized text or an invalid embedding name",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "The embedding provider is disabled (Fallen8:Embedding:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The graph element does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The provider's dimension or model identity conflicts with a vector index bound to this embedding name",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The embedding backend produced invalid output",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The embedding backend is unavailable (failed to load, or the Ollama sidecar is down)",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/embedding/elements": {
      "post": {
        "tags": [
          "Embedding"
        ],
        "summary": "Embeds a batch of texts onto elements - one provider batch, one transaction",
        "description": "The bulk-ingestion path: every vector plus its model stamp commits atomically.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the provider call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedElementsSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedElementsSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The batch was generated and committed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Empty/oversized batch, missing text, or an invalid embedding name",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "The embedding provider is disabled (Fallen8:Embedding:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "A referenced graph element does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The provider's dimension or model identity conflicts with a bound vector index",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The embedding backend produced invalid output",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The embedding backend is unavailable",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/embedding/search": {
      "post": {
        "tags": [
          "Embedding"
        ],
        "summary": "Semantic search: embeds a query text and runs kNN against a vector index",
        "description": "The text is embedded ONCE (with the configured query prefix); scores and ordering\nare exactly those of POST /scan/index/vector for the same vector.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the provider call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingSearchSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingSearchSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The hits, best first, with raw scores",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/VectorSearchResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Missing text, invalid k/kind, or the index is not a vector index",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "The embedding provider is disabled (Fallen8:Embedding:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No index with the given name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The index's dimension or declared model identity conflicts with the active provider",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The embedding backend produced invalid output",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The embedding backend is unavailable",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/embedding/text": {
      "post": {
        "tags": [
          "Embedding"
        ],
        "summary": "Embeds raw texts and returns the vectors",
        "description": "For clients driving the raw vector surfaces themselves (external pipelines,\n    semantic path queries with a client-held vector, debugging).",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Aborts the provider call when the request is cancelled",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedTextSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbedTextSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The vectors, in input order, plus the model identity",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/EmbeddingVectorsREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Empty/oversized batch or a missing text",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "The embedding provider is disabled (Fallen8:Embedding:Enabled)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "429": {
            "description": "The sensitive-endpoint rate limit was exceeded",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "502": {
            "description": "The embedding backend produced invalid output",
            "content": {
              "application/json": { }
            }
          },
          "503": {
            "description": "The embedding backend is unavailable",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/generate": {
      "get": {
        "tags": [
          "Benchmark"
        ],
        "summary": "Generates a random benchmark graph on top of the current one",
        "description": "Writes into the ADDRESSED namespace, and names it in the response. This is one of the\ntwo operations with no bare-URL alias to \"default\" (feature graph-namespaces): it grows\nexactly one graph, so a URL that names no namespace is a 400 rather than a silent write\ninto \"default\". The generated vertices are unlabeled and the edges carry edge property\n\"A\". A convenience for conjuring a graph to measure - GET /ns/{ns}/benchmark follows\nevery out-edge regardless of edge-property-id, so it benchmarks any loaded graph, not\nonly generated ones.",
        "parameters": [
          {
            "name": "nodeCount",
            "in": "query",
            "description": "Vertices to create (default 200)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "edgeCount",
            "in": "query",
            "description": "Out-edges added per vertex (default 5)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "distribution",
            "in": "query",
            "description": "Edge-target distribution: \"uniform\" (default) or\n    \"preferential\" (Barabási–Albert-style attachment — heavy-tailed in-degrees, so\n    PageRank/degree analytics at scale show real hubs)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "What was created, how long it took, and the resulting totals",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/GraphGenerationResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "A non-numeric or negative count, an unknown distribution, or a bare\n    URL naming no namespace",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/graph": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Retrieves the complete graph data including vertices and edges",
        "parameters": [
          {
            "name": "maxElements",
            "in": "query",
            "description": "Maximum number of elements to return (default: 1000)",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 1000
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the graph data with vertices and edges",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/Graph"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/graphelement/{graphElementIdentifier}": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Retrieves a graph element (vertex or edge) by its identifier",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element to retrieve",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the graph element object",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/AGraphElement"
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "Graph element with the specified ID was not found",
            "content": {
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes a graph element (vertex or edge) from the graph",
        "description": "Sample request:\n\n    DELETE /graphelement/123",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element to remove",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Graph element removal accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Malformed request (e.g. a non-integer element id). (A non-existent graph element is NOT a 400: an out-of-range id → 500, an in-range/absent id is a no-op → 202.)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      }
    },
    "/ns/{ns}/graphelement/{graphElementIdentifier}/embedding/{embeddingName}": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Sets (or replaces) a named embedding on a graph element",
        "description": "The element is the source of truth for its embedding (feature element-embeddings):\nthe write is WAL-durable element state, and every vector index BOUND to this\nembedding name updates its projection on commit - no separate index add. Replace\nsemantics: one current vector per name.\n\nSample request:\n\n    PUT /graphelement/42/embedding/default\n    { \"vector\": [0.12, -0.5, 0.33] }",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "embeddingName",
            "in": "path",
            "description": "The embedding name (letters, digits, '_', '-'; max 64 chars)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The embedding vector",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingWriteSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingWriteSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Embedding write accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Invalid embedding name, missing/empty vector, non-finite components, a dimension conflicting with a vector index bound to this name, or a zero-norm vector while a bound Cosine index exists",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The graph element does not exist",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      },
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes a named embedding from a graph element",
        "description": "Bound vector indices purge the element's projection on commit. Removing an absent\nembedding is a committed no-op, matching the property surface.",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "embeddingName",
            "in": "path",
            "description": "The embedding name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Embedding removal accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Invalid embedding name",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The graph element does not exist",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      },
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets a named embedding of a graph element",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "embeddingName",
            "in": "path",
            "description": "The embedding name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The stored embedding",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ElementEmbeddingREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid embedding name",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The graph element does not exist or carries no embedding of that name",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/graphelement/{graphElementIdentifier}/{propertyIdString}": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Sets a property on a graph element (vertex or edge), adding it or replacing its value",
        "description": "REPLACE semantics (feature platform-integrity-audit W2): writing a key that already exists\noverwrites it. Until W2 this route ran on the add path, which is \"insert, or verify the\nexisting value is equal\" and rolls back a value CHANGE - so this route, documented as\n\"adds or updates\", could not update: it answered 500 when waited and, at the default\nwaitForCompletion=false, 202 Accepted while discarding the write. Re-writing the value the\nelement already holds is a TRUE no-op (no modification-date bump, no change-feed event), so\nre-asserting unchanged state costs nothing observable. To change several properties\natomically, use PUT /graphelements/properties.\n\nSample request:\n\n    PUT /graphelement/123/age\n    {\n       \"propertyValue\": 35,\n       \"fullQualifiedTypeName\": \"System.Int32\"\n    }",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "propertyIdString",
            "in": "path",
            "description": "The ID/key of the property",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Property value specification",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Property write accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Malformed request body / invalid property specification. (A non-existent graph element is NOT a 400: an out-of-range id rolls back with an internal error → 500, and an in-range/absent id is a no-op → 202.)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      },
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes a property from a graph element (vertex or edge)",
        "description": "Sample request:\n\n    DELETE /graphelement/123/age",
        "parameters": [
          {
            "name": "graphElementIdentifier",
            "in": "path",
            "description": "The ID of the graph element",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "propertyIdString",
            "in": "path",
            "description": "The ID/key of the property to remove",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Property removal accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Malformed request (e.g. a non-integer element id). (A non-existent element/property is NOT a 400: an out-of-range id → 500, an in-range/absent id is a no-op → 202.)",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      }
    },
    "/ns/{ns}/graphelements": {
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes many graph elements in ONE atomic transaction (feature platform-integrity-audit)",
        "description": "The batch removal path. The whole batch is range-checked before anything is removed, so an\nout-of-range id removes nothing; an in-range but already-removed id is a committed no-op,\nmatching the single-element route. Removing a vertex cascades to its edges exactly as the\nsingle route does.\n\nSample request:\n\n    DELETE /graphelements\n    [1, 2, 3]",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The ids to remove",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Batch accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "A null list",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waited)"
          }
        }
      }
    },
    "/ns/{ns}/graphelements/get": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Reads many graph elements by id in ONE request (feature platform-integrity-audit)",
        "description": "The read-side companion to the batch write path. Every scan and every batch write returns IDS\nONLY, and the only other many-element reads are a whole-namespace dump (GET /graph) and a\nwhole-namespace export - so a caller holding several hundred resolved ids that needs their\ncurrent property values, which is what \"write only if something actually changed\" requires,\npreviously had one sequential request per element or a full dump per poll.\n\nEach element is returned WITHOUT its adjacency: this answers \"what does it hold now\", and\nshipping every edge id of every element would dominate the payload. Ask GET /vertex/{id} for\none element's adjacency.\n\nProperty values use the same invariant string form as every other read, so a value returned\nhere can be written straight back unchanged - which is what makes a value-level comparison\nmeaningful rather than a source of spurious differences.\n\nIds that resolve to no live element come back in \"notFound\" rather than being silently\nabsent, because \"gone\" and \"has no properties\" are different conclusions.\n\nSample request:\n\n    POST /graphelements/get\n    [1, 2, 3]",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The ids to read",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The elements that exist, plus the ids that do not",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/GraphElementBatchREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "A null list, or more ids than the page cap allows",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/graphelements/properties": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Sets and/or removes many properties across many elements in ONE atomic transaction (feature platform-integrity-audit)",
        "description": "The batch write path for properties, and the only ATOMIC way to change a value: the\nsingle-element routes are one transaction each, so a reconciliation spanning several\nproperties could previously be interrupted half-applied, leaving the element in a state no\nsource describes. REPLACE semantics: an existing key is overwritten, and the last write for\nan (element, key) pair in one batch wins.\n\nA semantically empty write is a TRUE no-op - setting a key to the value it already holds, or\nremoving one that is already absent, bumps no modification date and publishes no change-feed\nevent - so re-asserting unchanged state produces no observable mutation and a replayed batch\nis idempotent.\n\nSample request:\n\n    PUT /graphelements/properties\n    [\n      { \"graphElementId\": 42, \"propertyId\": \"ip\", \"fullQualifiedTypeName\": \"System.String\", \"propertyValue\": \"10.0.0.9\" },\n      { \"graphElementId\": 42, \"propertyId\": \"stale\", \"remove\": true }\n    ]",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The property writes. Each is a set, or a removal when `remove` is true.",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PropertyWriteSpecification"
                }
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PropertyWriteSpecification"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Batch accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "A null list, a null write, an unknown type name, or an unconvertible value. Nothing is enqueued.",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waited)"
          }
        }
      }
    },
    "/ns/{ns}/index": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Creates a new index for the graph",
        "description": "Sample request:\n\n    POST /index\n    {\n       \"uniqueId\": \"nameIndex\",\n       \"pluginType\": \"DictionaryIndex\",\n       \"pluginOptions\": {\n          \"propertyId\": \"name\",\n          \"type\": \"System.String\"\n       }\n    }",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Plugin specification with index type and configuration options",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns true if the index was created; false if the index type is unknown, the name already exists, or initialization failed (see server logs)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/index/backfill/{indexId}": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Repopulates an index from a property's values across the live elements (feature platform-integrity-audit)",
        "description": "Index content is DERIVED state with no durability of its own: index writes are neither\nsingle-writer transactions nor WAL-logged, so index state is snapshot-only. After a hard crash\nthe elements replay from the WAL but every index key added since the last checkpoint is gone,\nand three ORDINARY operations drop an index while a client is running - a tabula rasa, loading\na save game, and a per-index serialization failure that drops it from the checkpoint manifest.\nThis is the repair path, and it is the only one available to a client that is not in-process.\n\nDefault mode is a REPAIR: add-only and idempotent, so it is safe to run on every start and\nnothing is ever briefly missing. It does not remove keys that element state no longer\njustifies. Pass \"replace\": true for an EXACT rebuild, which wipes the index first and\ntherefore has a window in which a concurrent scan sees nothing.\n\nThe route is literal-first (/index/backfill/{indexId}, not /index/{indexId}/backfill) because\nPUT /index/vector/{indexId} already occupies three segments and index names are unvalidated\ncaller strings: an index legitimately named \"vector\" would otherwise be unreachable here.\n\nPass \"prefix\": true when propertyId is a KEY PREFIX rather than one exact key: every property\nwhose key starts with it is then indexed by its value, so one element can contribute several\nentries. That is the mode a client needs whose values are spread across dense ordinal keys\n($identity:0, $identity:1, ...), because the property surface accepts scalars and no array: an\nexact-key repair would restore only the first value of each element, leaving it findable by\none and invisible by the rest.\n\nSample request:\n\n    POST /index/backfill/claimIndex\n    {\n       \"propertyId\": \"$identity\",\n       \"replace\": false\n    }\n\nSample request, prefix mode:\n\n    POST /index/backfill/claimIndex\n    {\n       \"propertyId\": \"$identity:\",\n       \"prefix\": true\n    }",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The registered index to repopulate",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Which property supplies the keys, and whether to rebuild exactly",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexBackfillSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexBackfillSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The outcome: how many live elements were scanned and indexed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/IndexRebuildREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "No such index, a missing property id, or an index that cannot take arbitrary keys (vector, spatial, or a bound vector index that maintains itself)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/index/vector/{indexId}": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Adds (or replaces) an element's embedding vector in a vector index",
        "description": "One vector per element: adding again replaces. The generic PUT /index/{indexId} add\npath cannot express a float[] key, which is why the vector family has this typed\nendpoint (like fulltext and spatial have theirs).\n\nSample request (explicit mode):\n\n    PUT /index/vector/myEmbeddings\n    {\n       \"graphElementId\": 42,\n       \"vector\": [0.12, -0.5, 0.33]\n    }\n\nSample request (property mode - reads the element's float[] property):\n\n    PUT /index/vector/myEmbeddings\n    {\n       \"graphElementId\": 42,\n       \"propertyId\": \"embedding\"\n    }",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The ID of the vector index",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The element and its vector - explicit (\"vector\") or read from a float[] property (\"propertyId\")",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VectorIndexAddSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VectorIndexAddSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The vector was indexed (add-again replaced the previous vector)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Not a vector index, neither/both modes supplied, wrong dimension, NaN/Infinity components, zero-norm vector under Cosine, or the named property is missing / not a float[]",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The index or the graph element does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/index/{indexId}": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Adds a graph element to an existing index",
        "description": "Sample request:\n\n    PUT /index/nameIndex\n    {\n       \"graphElementId\": 123,\n       \"key\": {\n         \"propertyValue\": \"John Smith\",\n         \"fullQualifiedTypeName\": \"System.String\"\n       }\n    }",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The ID of the index",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Specification containing graph element ID and key information",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexAddToSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexAddToSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns true if the element was added; false if the index or the graph element does not exist (a miss is reported as 200 with a false body, not a 404)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Deletes an index from the system",
        "description": "Sample request:\n\n    DELETE /index/nameIndex",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The ID of the index to delete",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns true if the index was deleted; false if no index with that name exists (a miss is reported as 200 with a false body, not a 404)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/index/{indexId}/propertyValue": {
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes a key from an index",
        "description": "Sample request:\n\n    DELETE /index/nameIndex/propertyValue\n    {\n       \"propertyValue\": \"John Smith\",\n       \"fullQualifiedTypeName\": \"System.String\"\n    }",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The ID of the index",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The property specification representing the key to remove",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns true if the key was removed; false if the index does not exist (a miss is reported as 200 with a false body)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The property specification was missing or malformed, or the index is a vector index bound to an embedding (it maintains its own content)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/index/{indexId}/{graphElementId}": {
      "delete": {
        "tags": [
          "Graph"
        ],
        "summary": "Removes a graph element from an index",
        "description": "Sample request:\n\n    DELETE /index/nameIndex/123",
        "parameters": [
          {
            "name": "indexId",
            "in": "path",
            "description": "The ID of the index",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "graphElementId",
            "in": "path",
            "description": "The ID of the graph element to remove",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns true if the element was removed; false if the index or the graph element does not exist (a miss is reported as 200 with a false body, not a 404)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The index is a vector index bound to an embedding (it maintains its own content; remove the element embedding instead)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/load": {
      "put": {
        "tags": [
          "Admin"
        ],
        "summary": "Loads a Fallen-8 database from a saved file",
        "description": "Sample request:\n\n    PUT /load\n    {\n       \"startServices\": true,\n       \"saveGameLocation\": \"C:/Fallen8/database.f8s\"\n    }",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Load specification including file path and service start options",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/LoadSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/LoadSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Database loaded successfully"
          },
          "400": {
            "description": "Invalid load specification or file not found",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The load transaction was rolled back and did not complete"
          }
        }
      }
    },
    "/ns/{ns}/path/{from}/to/{to}": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Calculates the shortest path between two vertices in the graph",
        "description": "The path specification allows for dynamic filtering and cost calculation using compiled C# code fragments.\n\nSelect the algorithm via \"pathAlgorithmName\". \"BLS\" is a hop-count (unweighted) shortest\npath that ignores the \"cost\" block (\"totalWeight\" is 0), whereas \"DIJKSTRA\" is a weighted\nshortest path that honours the \"cost\" block and \"maxPathWeight\" (and returns the K\nleast-weight loop-free paths when \"maxResults\" &gt; 1).\n\nIMPORTANT: Filter and cost properties must contain valid C# lambda expressions prefixed with a \"return\" statement.\nThese are compiled at runtime into delegate methods.\n\nCorrect format for filter expressions:\n- \"return (parameter) =&gt; boolean_expression;\"\n\nCorrect format for cost expressions:\n- \"return (parameter) =&gt; numeric_expression;\"\n\nInstead of inline fragments, the body may reference a registered stored query of kind\n\"Path\" via \"storedQuery\" (mutually exclusive with \"filter\"/\"cost\"): the pre-compiled\nartifact is used and nothing is compiled per request. The numeric bounds and\n\"pathAlgorithmName\" stay per-request either way.\n\nSEMANTIC TRAVERSAL (feature element-embeddings): an optional \"semantic\" block carries\na query vector (or, with the embedding provider enabled, a \"queryText\" embedded once,\nup front) plus code-free similarity options - \"minScore\" filters vertices by\nsimilarity against their named element embedding, \"costBySimilarity\" weights a\nDIJKSTRA search by it. The block is pure data (it compiles no C#);\ncompiled fragments and stored queries read the same vector via the \"context\"\nparameter. Example: { \"semantic\": { \"queryVector\": [0.1, 0.2], \"minScore\": 0.7 } }.\nFull rules: features/element-embeddings README, \"Semantic traversal\".\n\nSECURITY: inline filter/cost fragments are compiled with Roslyn and executed IN-PROCESS\nWITH FULL TRUST. This endpoint is a trust boundary, not a sandbox: anyone permitted to\nintroduce code is trusted as the server process. Dynamic code execution is ALWAYS ON -\nthere is no switch to disable it - so authentication (required whenever an API key is\nconfigured) is the boundary. Invoking an operator-registered stored query narrows WHO can\nintroduce code, but the invoked query still runs with full trust; it is not a sandbox.\n\nEXECUTION BUDGET: the optional \"timeBudgetSeconds\" bounds the traversal (omitted =\nunbounded, exactly as before), and the traversal is always bound to the request abort, so\na client that gives up stops the work. Exhaustion answers 408. The budget is COOPERATIVE -\nit is checked between filter/cost invocations - so it contains an algorithmic blow-up but\ncannot interrupt a single fragment call that never returns.\n\nSample request:\n\n    POST /path/1/to/5\n    {\n       \"pathAlgorithmName\": \"BLS\",\n       \"maxDepth\": 5,\n       \"maxPathWeight\": 100.0,\n       \"maxResults\": 10,\n       \"filter\": {\n         \"vertexFilter\": \"return (v) =&gt; v.Label == \\\"Person\\\";\",\n         \"edgeFilter\": \"return (e) =&gt; e.Label == \\\"friendship\\\";\",\n         \"edgePropertyFilter\": \"return (p) =&gt; p == \\\"knows\\\";\"\n       },\n       \"cost\": {\n         \"vertexCost\": \"return (v) =&gt; v.TryGetProperty(out var age, \\\"age\\\") ? (double)age : 1.0;\",\n         \"edgeCost\": \"return (e) =&gt; e.TryGetProperty(out var weight, \\\"weight\\\") ? (double)weight : 1.0;\"\n       }\n    }",
        "parameters": [
          {
            "name": "from",
            "in": "path",
            "description": "The ID of the source vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "to",
            "in": "path",
            "description": "The ID of the target vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Path specification with algorithm, depth, filters and other constraints",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PathSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PathSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the found paths between the vertices",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PathREST"
                  }
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid path specification, a fragment failed to compile, storedQuery was mixed with inline fragments, or the referenced stored query has the wrong kind",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No stored query with the referenced name exists (a missing source/target vertex is not a 404: it yields a 200 with an empty path list)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "408": {
            "description": "The execution budget (\"timeBudgetSeconds\") or the client's own cancellation stopped the traversal before it finished; no result is reported, because an empty 200 would read as \"no path exists\"",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The referenced stored query is not invocable (its recompile on load failed - see its diagnostics via GET /storedquery/{name})",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "An unexpected runtime fault occurred while calculating the path (e.g. a compiled filter/cost fragment threw)",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/plugins": {
      "get": {
        "tags": [
          "Plugins"
        ],
        "summary": "Lists all registered plugins in the addressed namespace.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the plugin summaries",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PluginSummaryREST"
                  }
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/plugins/algorithm": {
      "post": {
        "tags": [
          "Plugins"
        ],
        "summary": "Registers an algorithm plugin (Path / SubGraph / Analytics) from whole-type C# source.",
        "description": "The source is compiled ONCE here and validated against the contract (exactly one public\nclass implementing the contract's interface, with a public parameterless constructor and a\nPluginName equal to the registration name). A registered algorithm is then invoked by name\nthrough the existing path/subgraph/analytics endpoints. Entries are immutable: to change\none, delete and re-register.\n\nSECURITY: registration compiles C# that later executes IN-PROCESS WITH FULL TRUST. It\nrequires the dynamic-plugin capability (Fallen8:Security:EnableDynamicPluginLoading) - a\nprovisioning window - plus authentication; invoking an already-registered plugin does not.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The registration (name, contract, description, sourceCode)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AlgorithmPluginRegistration"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AlgorithmPluginRegistration"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The plugin was compiled, validated and registered",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PluginSummaryREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The registration was malformed, or the source failed to compile / satisfy the contract (diagnostics in the body)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Dynamic plugin registration is disabled on this server",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "A plugin with the same name already exists, the name collides with a built-in, or the per-namespace quota was reached",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The registration transaction faulted with an internal error",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/plugins/algorithm/validate": {
      "post": {
        "tags": [
          "Plugins"
        ],
        "summary": "Compile-checks an algorithm plugin source WITHOUT registering it (for the authoring editor).",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginValidationSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginValidationSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The compile check ran; the body reports validity + diagnostics",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PluginValidationREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request was malformed (invalid contract)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Dynamic plugin registration is disabled on this server",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/plugins/function": {
      "post": {
        "tags": [
          "Plugins"
        ],
        "summary": "Registers a graph function (a stored graph procedure) from whole-type C# source.",
        "description": "A graph function reads the whole graph (full scan or index query) and returns a view of\nexisting vertices/edges. It is invoked by name via POST /plugins/function/{name}/invoke.\nRead-only in v1. Same compile/validate/gate contract as algorithm registration.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The registration (name, description, sourceCode)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/FunctionPluginRegistration"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/FunctionPluginRegistration"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The function was compiled, validated and registered",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PluginSummaryREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The registration was malformed, or the source failed to compile / satisfy the contract",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Dynamic plugin registration is disabled on this server",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "A plugin with the same name already exists, or the per-namespace quota was reached",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The registration transaction faulted with an internal error",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/plugins/function/validate": {
      "post": {
        "tags": [
          "Plugins"
        ],
        "summary": "Compile-checks a graph function source WITHOUT registering it (for the authoring editor).",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginValidationSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginValidationSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The compile check ran; the body reports validity + diagnostics",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PluginValidationREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request was malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Dynamic plugin registration is disabled on this server",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/plugins/function/{name}/invoke": {
      "post": {
        "tags": [
          "Plugins"
        ],
        "summary": "Invokes a registered graph function by name against the addressed namespace's graph.",
        "description": "Invoking a registered function does NOT require the dynamic-plugin capability (only\nregistration does) - it carries the standard authentication like any read. The function is\nactivated fresh and runs read-only; the result references existing graph elements.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The registered function name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The call-time parameters (string-valued in v1)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/GraphFunctionInvocation"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/GraphFunctionInvocation"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The function ran; returns the selected vertices/edges",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/GraphFunctionResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The function reported an expected failure (e.g. a missing/invalid parameter)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No graph function with the given name is registered in this namespace",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The function exists but is not in a runnable (Compiled) state",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The function threw while running",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/plugins/{name}": {
      "get": {
        "tags": [
          "Plugins"
        ],
        "summary": "Gets the full definition of a registered plugin, including its source.",
        "description": "The response includes the stored source (which also covers manual migration between\ninstances) and - for a Failed entry - the recompile diagnostics.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The plugin name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the plugin detail",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PluginDetailREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No plugin with the given name exists in this namespace",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Plugins"
        ],
        "summary": "Deletes (deregisters) a plugin.",
        "description": "Deletion drops the pinned compiled type so its collectible load context can unload once\nin-flight invocations finish. Removal compiles nothing; it carries only the standard\nauthentication (not the dynamic-plugin capability).",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The plugin name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The plugin was deleted"
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No plugin with the given name exists in this namespace",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The removal transaction was rolled back and did not complete"
          }
        }
      }
    },
    "/ns/{ns}/save": {
      "put": {
        "tags": [
          "Admin"
        ],
        "summary": "Saves the current database state to a file",
        "description": "Sample request:\n\n    PUT /save\n    {\n       \"saveGameLocation\": \"C:/Fallen8/database.f8s\",\n       \"savePartitions\": 8\n    }\n\nBoth parameters are optional. If not provided, the save goes to the configured durability\nstorage directory (Fallen8:Durability:StorageDirectory; the app base directory when unset)\nusing the CheckpointBaseName (\"Temp.f8s\" by default) and the optimal partition count.\nThe save is recorded in the save-game registry (feature save-games); the response is the\ncreated entry, whose \"location\" field is the path the database was saved to.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Save specification including file path and partition options (both optional)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SaveSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SaveSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the created save-game registry entry",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SaveGameREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid save specification",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The save transaction was rolled back and did not complete",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/scan/graph/properties": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Scans every property of every element for a case-insensitive substring match (discovery search)",
        "description": "The all-property companion to `POST /scan/graph/property/{propertyId}`: singular scans one\nnamed key with a typed operator; this plural route scans EVERY property value. Each value is\nrendered to its invariant-culture text form (so numbers, booleans and dates are searchable too)\nand tested with a case-insensitive Contains; an element matches when ANY of its values matches.\nIt is a cold, un-indexed O(elements x properties) scan - use an index for scale. Reserved\nembedding entries are never matched.\n\nSample request:\n\n    POST /scan/graph/properties\n    {\n       \"searchTerm\": \"acme\",\n       \"label\": \"company\",\n       \"resultType\": \"Both\"\n    }\n\nThe optional \"label\" field restricts the scan to elements whose label matches exactly;\nomit it to scan every element type.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Search specification with the term, optional label restrictor and result type",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySearchSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySearchSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the matching element IDs (empty when nothing matches)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or the search term was blank",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/scan/graph/property/{propertyId}": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Scans the graph for elements with a specific property value",
        "description": "Sample request:\n\n    POST /scan/graph/property/name\n    {\n       \"operator\": 0,\n       \"literal\": {\n         \"value\": \"John Doe\",\n         \"fullQualifiedTypeName\": \"System.String\"\n       },\n       \"resultType\": \"Vertices\"\n    }\n\nThe optional \"label\" field restricts the scan to elements whose label matches exactly\n(e.g. \"person\"); omit it to scan every element type.",
        "parameters": [
          {
            "name": "propertyId",
            "in": "path",
            "description": "The property ID to scan for",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Scan specification with comparison operator and value",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/ScanSpecification"
              }
            },
            "text/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/ScanSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/ScanSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the matching element IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid scan specification",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/scan/index/all": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Performs a scan operation on an index with a specific value and operator",
        "description": "Sample request:\n\n    POST /scan/index/all\n    {\n       \"indexId\": \"userNameIndex\",\n       \"operator\": 0,\n       \"literal\": {\n         \"value\": \"Jane\",\n         \"fullQualifiedTypeName\": \"System.String\"\n       },\n       \"resultType\": \"Vertices\"\n    }\n\nThe optional \"label\" field restricts the hits to elements whose label matches exactly\n(e.g. \"person\"); omit it to return every match.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Index scan specification with index ID, operator and value",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexScanSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexScanSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the matching element IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid scan specification or index not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/scan/index/fulltext": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Performs a fulltext search on an indexed property",
        "description": "Sample request:\n\n    POST /scan/index/fulltext\n    {\n       \"indexId\": \"documentIndex\",\n       \"requestString\": \"graph database nosql\"\n    }",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Fulltext search specification with index ID and search terms",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/FulltextIndexScanSpecification"
              }
            },
            "text/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/FulltextIndexScanSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/FulltextIndexScanSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the search results with highlighting",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/FulltextSearchResultREST"
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "The index does not exist or is not a fulltext index (a miss yields 204 No Content, not a 404)",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/scan/index/range": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Performs a range-based scan on an index between two values",
        "description": "Sample request:\n\n    POST /scan/index/range\n    {\n       \"indexId\": \"ageIndex\",\n       \"leftLimit\": \"18\",\n       \"rightLimit\": \"30\",\n       \"includeLeft\": true,\n       \"includeRight\": false,\n       \"fullQualifiedTypeName\": \"System.Int32\",\n       \"resultType\": \"Vertices\"\n    }",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Range scan specification with index ID, limits and include/exclude options",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/RangeIndexScanSpecification"
              }
            },
            "text/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/RangeIndexScanSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/RangeIndexScanSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the matching element IDs within the range",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid range specification or index not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/scan/index/spatial": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Performs a spatial distance search using a spatial index",
        "description": "Sample request:\n\n    POST /scan/index/spatial\n    {\n       \"indexId\": \"locationIndex\",\n       \"graphElementId\": 123,\n       \"distance\": 5.0\n    }",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Spatial search specification with index ID, reference element and distance",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SearchDistanceSpecification"
              }
            },
            "text/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SearchDistanceSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SearchDistanceSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the element IDs within the specified distance",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "The index does not exist, is not a spatial index, or the reference element does not exist (a miss yields 204 No Content, not a 404)",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/scan/index/vector": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Finds the k nearest neighbours of a query vector in a vector index",
        "description": "Exact brute-force kNN (SIMD): deterministic ordering - best score first, ties broken\nby ascending element id. Constraints are applied BEFORE scoring, so the returned k are\nk MATCHING elements. Removed elements never appear. The GraphRAG recipe: feed the\nreturned element ids into the existing traversal surface (POST /path, PUT /subgraph,\nproperty reads) - similarity search lands ON the graph.\n\nSample request:\n\n    POST /scan/index/vector\n    {\n       \"indexId\": \"myEmbeddings\",\n       \"query\": [0.1, 0.2, 0.3],\n       \"k\": 10,\n       \"kind\": \"vertex\",\n       \"label\": \"person\"\n    }",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The kNN query: index, query vector, k, optional kind/label constraints",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VectorIndexScanSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VectorIndexScanSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the k best-scoring matching elements (fewer when the corpus is smaller)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/VectorSearchResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Not a vector index, wrong query dimension, NaN/Infinity components, k outside [1, 1024], zero-norm query under Cosine, or an unknown kind value",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The index does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/service": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Creates a new service based on the specified plugin",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Plugin specification including type, ID and options",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns true if the service was created; false if the plugin type is unknown or the id already exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/service/{key}": {
      "delete": {
        "tags": [
          "Admin"
        ],
        "summary": "Deletes a service with the specified key",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "description": "The unique identifier of the service to delete",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns whether the service was successfully deleted",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/statistics": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "summary": "Returns a graph-shape snapshot: counts, cardinalities, degrees, indices, memory",
        "description": "The result is an ADVISORY snapshot, not transactionally consistent: reads are\nlock-free over the volatile element snapshot, so a write committed during the pass\nmay or may not appear.\n\nCOST (honest): counts and memory are O(1); labels and property keys are one pass\nover the element snapshot; degrees are O(1) adjacency-count reads per vertex. When\nV+E exceeds the configured element budget (Fallen8:Observability:StatisticsElementBudget,\ndefault 1,000,000) the pass samples with a uniform stride and the response says so:\nsampled=true, sampleStride, per-name counts as counted IN THE SAMPLE (multiply by\nthe stride to extrapolate), distinctTotal = distinct within the sample (sampling\nhonestly undercounts distinct values). Degree percentiles from a strided sample are\nstatistically sound. Memory numbers never force a GC.\n\nThis endpoint exposes SCHEMA-SHAPED data (label names, property keys, index names),\nso it sits behind the normal API-key policy - unlike /metrics, whose inventory is\naggregate numbers only - and under the sensitive rate limiter so a misconfigured\nscrape loop cannot turn an O(V+E) pass into a DoS.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The snapshot",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/GraphStatisticsREST"
                }
              },
              "application/json": { }
            }
          },
          "429": {
            "description": "Rate limited (the sensitive fixed-window limiter)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/status": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "Gets the current status of the Fallen-8 database",
        "description": "The anonymous connection probe. It is also the ONE namespace-scoped route that still\nanswers for a namespace this process did not load (feature namespace-startup-load): it\nthen reports \"namespaceState\": \"notLoaded\" and leaves every engine-derived field null\n(counts, index inventory, available plugins, durability) rather than reporting zeros or\nempty lists. Every other namespace-scoped route refuses such a namespace with 503.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the database status information",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/StatusREST"
                }
              },
              "application/json": { }
            }
          }
        },
        "security": [ ]
      }
    },
    "/ns/{ns}/storedquery": {
      "post": {
        "tags": [
          "StoredQueries"
        ],
        "summary": "Registers a stored query: validates and compiles the specification, then publishes it under a unique name.",
        "description": "Exactly one of \"path\" / \"subGraph\" must be present and must match \"kind\". The code\nfragments are compiled ONCE here, with the same bounds as the inline endpoints; a\ncompile failure rejects the registration with the compiler diagnostics. Entries are\nimmutable: to change one, delete and re-register.\n\nSECURITY: registration compiles C# fragments with Roslyn that later execute IN-PROCESS\nWITH FULL TRUST. It carries the same authentication as the inline code endpoints\n(required whenever an API key is configured); dynamic code execution itself is always on.\n\nSample request:\n\n    POST /storedquery\n    {\n       \"name\": \"adults-shortest\",\n       \"kind\": \"Path\",\n       \"description\": \"age&gt;30 vertices, weight-by-distance\",\n       \"path\": {\n         \"filter\": { \"vertexFilter\": \"return (v) =&gt; v.TryGetProperty(out int age, \\\"age\\\") &amp;&amp; age &gt; 30;\" },\n         \"cost\":   { \"edgeCost\": \"return (e) =&gt; 1.0;\" }\n       }\n    }",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The stored query specification (name, kind, and the matching path/subGraph block)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/StoredQuerySpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/StoredQuerySpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The stored query was compiled and registered",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/StoredQuerySummaryREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The specification was malformed (name/kind/block), or a fragment failed to compile (the body carries the compiler diagnostics)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "A stored query with the same name already exists, or the library quota (Fallen8:StoredQueries:MaxCount) was reached",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The registration transaction faulted with an internal error",
            "content": {
              "application/json": { }
            }
          }
        }
      },
      "get": {
        "tags": [
          "StoredQueries"
        ],
        "summary": "Lists all registered stored queries.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the stored query summaries",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StoredQuerySummaryREST"
                  }
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/storedquery/{name}": {
      "get": {
        "tags": [
          "StoredQueries"
        ],
        "summary": "Gets the full definition of a stored query, including its source specification.",
        "description": "The response includes the stored specification JSON (the registration request's\npath/subGraph block), which also covers manual migration between instances, and - for\na Failed entry - the recompile diagnostics.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The stored query name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the stored query detail",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/StoredQueryDetailREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No stored query with the given name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "StoredQueries"
        ],
        "summary": "Deletes (deregisters) a stored query.",
        "description": "Deletion drops the pinned compiled artifact so its collectible load context can unload\nonce in-flight invocations finish. Removal compiles nothing; it carries only the\nstandard authentication (the API key when one is configured).",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The stored query name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The stored query was deleted"
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No stored query with the given name exists",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The removal transaction was rolled back and did not complete"
          }
        }
      }
    },
    "/ns/{ns}/subgraph": {
      "put": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Creates and registers a new subgraph from a specification.",
        "description": "Filter and pattern predicates are C# code fragments prefixed with \"return\", compiled\nat runtime. A null/empty fragment matches everything.\n\nInstead of inline fragments, the body may reference a registered stored query of kind\n\"SubGraph\" via \"storedQuery\" (mutually exclusive with \"vertexFilter\"/\"edgeFilter\"/\n\"patterns\"): the stored template is instantiated under this request's \"name\" and\nnothing is compiled per request. The created subgraph is self-contained - deleting the\nstored query later does not affect it.\n\nSEMANTIC SUBGRAPHS (feature element-embeddings): an optional \"semantic\" block carries\na query vector (or \"queryText\" via the embedding provider) bound at REGISTRATION -\nrecalculation reuses it and never embeds anything. \"minScore\" becomes the code-free\nvertex pre-filter, a vertex pattern step's \"semanticMinScore\" that step's filter\n(feature subgraph-semantic-thresholds); compiled fragments read the same vector via\n\"context\". Pure data (it compiles no C#); not available on\nstored-template invocations.\nFull rules: features/element-embeddings README, \"Semantic traversal\".\n\nSECURITY: inline filter/pattern fragments are compiled with Roslyn and executed\nIN-PROCESS WITH FULL TRUST - a trust boundary, not a sandbox. Dynamic code execution is\nALWAYS ON (there is no switch to disable it), so authentication (required whenever an API\nkey is configured) is the boundary. Instantiating an operator-registered stored query\nnarrows WHO can introduce code, but the invoked query still runs with full trust.\n\nSample request:\n\n    PUT /subgraph\n    {\n       \"name\": \"friends-of-alice\",\n       \"vertexFilter\": \"return (v) =&gt; v.Label == \\\"person\\\";\",\n       \"patterns\": [\n         { \"type\": \"Vertex\", \"patternName\": \"start\", \"vertexFilter\": \"return (v) =&gt; v.Label == \\\"person\\\";\" },\n         { \"type\": \"Edge\", \"patternName\": \"rel\", \"direction\": \"OutgoingEdge\", \"edgePropertyFilter\": \"return (p) =&gt; p == \\\"knows\\\";\" },\n         { \"type\": \"Vertex\", \"patternName\": \"end\", \"vertexFilter\": \"return (v) =&gt; v.Label == \\\"person\\\";\" }\n       ]\n    }",
        "parameters": [
          {
            "name": "fromSubGraph",
            "in": "query",
            "description": "Optional name of an existing subgraph to source this one from (creates a nested subgraph). When omitted, the subgraph is sourced from the whole graph.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The subgraph specification (name, filters, patterns)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SubGraphSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SubGraphSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The subgraph was created and registered. A syntactically-valid pattern that matches nothing yields a registered EMPTY subgraph (201), identically whether the source graph is empty or populated.",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SubGraphSummary"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The specification was invalid, the pattern was structurally invalid, a filter failed to compile, storedQuery was mixed with inline fragments, the referenced stored query has the wrong kind, or the requested algorithm is not an available subgraph plugin",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The source subgraph named by fromSubGraph does not exist, or no stored query with the referenced name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "A subgraph with the same name already exists, a resource quota (subgraph count or materialized-element ceiling) was exceeded, or the referenced stored query is not invocable (its recompile on load failed)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The create transaction faulted with an internal error",
            "content": {
              "application/json": { }
            }
          }
        }
      },
      "get": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Lists the names of all registered subgraphs.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of subgraph names",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/subgraph/{name}": {
      "get": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Gets a summary (metadata and element counts) of a registered subgraph.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The subgraph name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the subgraph summary",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SubGraphSummary"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No subgraph with the given name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Deregisters (deletes) a subgraph.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The subgraph name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The subgraph was deleted"
          },
          "404": {
            "description": "No subgraph with the given name exists",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The removal transaction was rolled back and did not complete"
          }
        }
      }
    },
    "/ns/{ns}/subgraph/{name}/graph": {
      "get": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Gets the extracted contents (vertices and edges) of a registered subgraph.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The subgraph name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "maxElements",
            "in": "query",
            "description": "Maximum number of vertices and edges to return (default 1000)",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 1000
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the subgraph contents",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/Graph"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No subgraph with the given name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/subgraph/{name}/recalculate": {
      "post": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Recalculates a subgraph against the current state of its source graph.",
        "description": "Only subgraphs created by an algorithm (with a stored source and plugin name)\ncan be recalculated; manually registered subgraphs cannot.\n\nThe materialized-element quotas bound a refresh exactly as they bound the create: a\nrecalculation whose fresh extraction would exceed the per-subgraph or total element\nceiling is rejected and the subgraph KEEPS its previous, in-quota contents (it stays\nstale until the quota is raised or it is deleted).",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The subgraph name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the recalculated subgraph summary",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SubGraphSummary"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No subgraph with the given name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The subgraph exists but cannot be recalculated: either its source graph or algorithm plugin is missing, or the recalculated extraction would exceed a materialized-element quota (previous contents kept)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/tabularasa": {
      "head": {
        "tags": [
          "Admin"
        ],
        "summary": "Erases the addressed namespace's data (the namespace stays registered, empty)",
        "description": "Bare /tabularasa erases the \"default\" namespace; /ns/{ns}/tabularasa erases that\nnamespace. The Fallen-8-wide factory reset is HEAD /tabularasa/all.",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Namespace clear successfully enqueued (this void action returns 200 with an empty body, not 204)"
          }
        }
      }
    },
    "/ns/{ns}/trim": {
      "head": {
        "tags": [
          "Admin"
        ],
        "summary": "Trims the database, releasing unused memory",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Trim operation successfully enqueued (this void action returns 200 with an empty body, not 204)"
          }
        }
      }
    },
    "/ns/{ns}/unittest": {
      "put": {
        "tags": [
          "SampleGraph"
        ],
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/ns/{ns}/vertex": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Creates a new vertex in the graph",
        "description": "Sample request:\n\n    PUT /vertex\n    {\n       \"label\": \"person\",\n       \"creationDate\": 1713862800,\n       \"properties\": [\n         {\n           \"propertyId\": \"name\",\n           \"propertyValue\": \"John Doe\",\n           \"fullQualifiedTypeName\": \"System.String\"\n         }\n       ]\n    }",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The vertex specification containing label and property information",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VertexSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VertexSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Vertex creation accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Invalid vertex specification",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      }
    },
    "/ns/{ns}/vertex/count": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "Gets the total number of vertices in the database",
        "parameters": [
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the number of vertices",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              },
              "application/json": { }
            }
          }
        },
        "security": [ ]
      }
    },
    "/ns/{ns}/vertex/{vertexIdentifier}": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Retrieves a vertex from the graph by its identifier",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex to retrieve",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the vertex object",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/Vertex"
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "Vertex with the specified ID was not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/vertex/{vertexIdentifier}/edges/in": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets all available incoming edge property IDs for a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of incoming edge property IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "Vertex has no incoming edges or vertex not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/vertex/{vertexIdentifier}/edges/in/{edgePropertyIdentifier}": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets incoming edges of a specific type to a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "edgePropertyIdentifier",
            "in": "path",
            "description": "The edge property identifier/type to filter by",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of matching incoming edge IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "No matching edges found or vertex not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/vertex/{vertexIdentifier}/edges/in/{edgePropertyIdentifier}/degree": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the count of incoming edges of a specific type for a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "edgePropertyIdentifier",
            "in": "path",
            "description": "The edge property identifier/type to count",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the count of matching incoming edges (0 if the vertex has no such edge group)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "uint32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Vertex with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/vertex/{vertexIdentifier}/edges/indegree": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the total count of incoming edges for a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the count of incoming edges",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "uint32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Vertex with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/vertex/{vertexIdentifier}/edges/out": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets all available outgoing edge property IDs for a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of outgoing edge property IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "Vertex has no outgoing edges or vertex not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/vertex/{vertexIdentifier}/edges/out/{edgePropertyIdentifier}": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets outgoing edges of a specific type from a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "edgePropertyIdentifier",
            "in": "path",
            "description": "The edge property identifier/type to filter by",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of matching outgoing edge IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "No matching edges found or vertex not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/vertex/{vertexIdentifier}/edges/out/{edgePropertyIdentifier}/degree": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the count of outgoing edges of a specific type from a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "edgePropertyIdentifier",
            "in": "path",
            "description": "The edge property identifier/type to count",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the count of matching outgoing edges (0 if the vertex has no such edge group)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "uint32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Vertex with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/vertex/{vertexIdentifier}/edges/outdegree": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the total count of outgoing edges for a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the count of outgoing edges",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "uint32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Vertex with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/ns/{ns}/vertices": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Creates many vertices in ONE atomic transaction (feature mcp-followups)",
        "description": "The batch write path: far fewer round-trips than one `PUT /vertex` per vertex, and -\nunlike the single endpoint (202, no body) - a waited-on call RETURNS the assigned vertex\nids so a caller can immediately reference them (e.g. to create edges).",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits and returns the assigned ids in input order",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "ns",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The vertices to create",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/VertexSpecification"
                }
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/VertexSpecification"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the assigned vertex ids in input order (waitForCompletion=true)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "202": {
            "description": "Batch accepted (waitForCompletion=false)",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "A null list, or a null/invalid vertex specification",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waited)",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/path/{from}/to/{to}": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Calculates the shortest path between two vertices in the graph",
        "description": "The path specification allows for dynamic filtering and cost calculation using compiled C# code fragments.\n\nSelect the algorithm via \"pathAlgorithmName\". \"BLS\" is a hop-count (unweighted) shortest\npath that ignores the \"cost\" block (\"totalWeight\" is 0), whereas \"DIJKSTRA\" is a weighted\nshortest path that honours the \"cost\" block and \"maxPathWeight\" (and returns the K\nleast-weight loop-free paths when \"maxResults\" &gt; 1).\n\nIMPORTANT: Filter and cost properties must contain valid C# lambda expressions prefixed with a \"return\" statement.\nThese are compiled at runtime into delegate methods.\n\nCorrect format for filter expressions:\n- \"return (parameter) =&gt; boolean_expression;\"\n\nCorrect format for cost expressions:\n- \"return (parameter) =&gt; numeric_expression;\"\n\nInstead of inline fragments, the body may reference a registered stored query of kind\n\"Path\" via \"storedQuery\" (mutually exclusive with \"filter\"/\"cost\"): the pre-compiled\nartifact is used and nothing is compiled per request. The numeric bounds and\n\"pathAlgorithmName\" stay per-request either way.\n\nSEMANTIC TRAVERSAL (feature element-embeddings): an optional \"semantic\" block carries\na query vector (or, with the embedding provider enabled, a \"queryText\" embedded once,\nup front) plus code-free similarity options - \"minScore\" filters vertices by\nsimilarity against their named element embedding, \"costBySimilarity\" weights a\nDIJKSTRA search by it. The block is pure data (it compiles no C#);\ncompiled fragments and stored queries read the same vector via the \"context\"\nparameter. Example: { \"semantic\": { \"queryVector\": [0.1, 0.2], \"minScore\": 0.7 } }.\nFull rules: features/element-embeddings README, \"Semantic traversal\".\n\nSECURITY: inline filter/cost fragments are compiled with Roslyn and executed IN-PROCESS\nWITH FULL TRUST. This endpoint is a trust boundary, not a sandbox: anyone permitted to\nintroduce code is trusted as the server process. Dynamic code execution is ALWAYS ON -\nthere is no switch to disable it - so authentication (required whenever an API key is\nconfigured) is the boundary. Invoking an operator-registered stored query narrows WHO can\nintroduce code, but the invoked query still runs with full trust; it is not a sandbox.\n\nEXECUTION BUDGET: the optional \"timeBudgetSeconds\" bounds the traversal (omitted =\nunbounded, exactly as before), and the traversal is always bound to the request abort, so\na client that gives up stops the work. Exhaustion answers 408. The budget is COOPERATIVE -\nit is checked between filter/cost invocations - so it contains an algorithmic blow-up but\ncannot interrupt a single fragment call that never returns.\n\nSample request:\n\n    POST /path/1/to/5\n    {\n       \"pathAlgorithmName\": \"BLS\",\n       \"maxDepth\": 5,\n       \"maxPathWeight\": 100.0,\n       \"maxResults\": 10,\n       \"filter\": {\n         \"vertexFilter\": \"return (v) =&gt; v.Label == \\\"Person\\\";\",\n         \"edgeFilter\": \"return (e) =&gt; e.Label == \\\"friendship\\\";\",\n         \"edgePropertyFilter\": \"return (p) =&gt; p == \\\"knows\\\";\"\n       },\n       \"cost\": {\n         \"vertexCost\": \"return (v) =&gt; v.TryGetProperty(out var age, \\\"age\\\") ? (double)age : 1.0;\",\n         \"edgeCost\": \"return (e) =&gt; e.TryGetProperty(out var weight, \\\"weight\\\") ? (double)weight : 1.0;\"\n       }\n    }",
        "parameters": [
          {
            "name": "from",
            "in": "path",
            "description": "The ID of the source vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "to",
            "in": "path",
            "description": "The ID of the target vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Path specification with algorithm, depth, filters and other constraints",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PathSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PathSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the found paths between the vertices",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PathREST"
                  }
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid path specification, a fragment failed to compile, storedQuery was mixed with inline fragments, or the referenced stored query has the wrong kind",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No stored query with the referenced name exists (a missing source/target vertex is not a 404: it yields a 200 with an empty path list)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "408": {
            "description": "The execution budget (\"timeBudgetSeconds\") or the client's own cancellation stopped the traversal before it finished; no result is reported, because an empty 200 would read as \"no path exists\"",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The referenced stored query is not invocable (its recompile on load failed - see its diagnostics via GET /storedquery/{name})",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "An unexpected runtime fault occurred while calculating the path (e.g. a compiled filter/cost fragment threw)",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/plugins": {
      "get": {
        "tags": [
          "Plugins"
        ],
        "summary": "Lists all registered plugins in the addressed namespace.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the plugin summaries",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PluginSummaryREST"
                  }
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/plugins/algorithm": {
      "post": {
        "tags": [
          "Plugins"
        ],
        "summary": "Registers an algorithm plugin (Path / SubGraph / Analytics) from whole-type C# source.",
        "description": "The source is compiled ONCE here and validated against the contract (exactly one public\nclass implementing the contract's interface, with a public parameterless constructor and a\nPluginName equal to the registration name). A registered algorithm is then invoked by name\nthrough the existing path/subgraph/analytics endpoints. Entries are immutable: to change\none, delete and re-register.\n\nSECURITY: registration compiles C# that later executes IN-PROCESS WITH FULL TRUST. It\nrequires the dynamic-plugin capability (Fallen8:Security:EnableDynamicPluginLoading) - a\nprovisioning window - plus authentication; invoking an already-registered plugin does not.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The registration (name, contract, description, sourceCode)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AlgorithmPluginRegistration"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/AlgorithmPluginRegistration"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The plugin was compiled, validated and registered",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PluginSummaryREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The registration was malformed, or the source failed to compile / satisfy the contract (diagnostics in the body)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Dynamic plugin registration is disabled on this server",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "A plugin with the same name already exists, the name collides with a built-in, or the per-namespace quota was reached",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The registration transaction faulted with an internal error",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/plugins/algorithm/validate": {
      "post": {
        "tags": [
          "Plugins"
        ],
        "summary": "Compile-checks an algorithm plugin source WITHOUT registering it (for the authoring editor).",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginValidationSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginValidationSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The compile check ran; the body reports validity + diagnostics",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PluginValidationREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request was malformed (invalid contract)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Dynamic plugin registration is disabled on this server",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/plugins/function": {
      "post": {
        "tags": [
          "Plugins"
        ],
        "summary": "Registers a graph function (a stored graph procedure) from whole-type C# source.",
        "description": "A graph function reads the whole graph (full scan or index query) and returns a view of\nexisting vertices/edges. It is invoked by name via POST /plugins/function/{name}/invoke.\nRead-only in v1. Same compile/validate/gate contract as algorithm registration.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The registration (name, description, sourceCode)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/FunctionPluginRegistration"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/FunctionPluginRegistration"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The function was compiled, validated and registered",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PluginSummaryREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The registration was malformed, or the source failed to compile / satisfy the contract",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Dynamic plugin registration is disabled on this server",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "A plugin with the same name already exists, or the per-namespace quota was reached",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The registration transaction faulted with an internal error",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/plugins/function/validate": {
      "post": {
        "tags": [
          "Plugins"
        ],
        "summary": "Compile-checks a graph function source WITHOUT registering it (for the authoring editor).",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginValidationSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginValidationSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The compile check ran; the body reports validity + diagnostics",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PluginValidationREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request was malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "403": {
            "description": "Dynamic plugin registration is disabled on this server",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/plugins/function/{name}/invoke": {
      "post": {
        "tags": [
          "Plugins"
        ],
        "summary": "Invokes a registered graph function by name against the addressed namespace's graph.",
        "description": "Invoking a registered function does NOT require the dynamic-plugin capability (only\nregistration does) - it carries the standard authentication like any read. The function is\nactivated fresh and runs read-only; the result references existing graph elements.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The registered function name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The call-time parameters (string-valued in v1)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/GraphFunctionInvocation"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/GraphFunctionInvocation"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The function ran; returns the selected vertices/edges",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/GraphFunctionResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The function reported an expected failure (e.g. a missing/invalid parameter)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No graph function with the given name is registered in this namespace",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The function exists but is not in a runnable (Compiled) state",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The function threw while running",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/plugins/{name}": {
      "get": {
        "tags": [
          "Plugins"
        ],
        "summary": "Gets the full definition of a registered plugin, including its source.",
        "description": "The response includes the stored source (which also covers manual migration between\ninstances) and - for a Failed entry - the recompile diagnostics.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The plugin name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the plugin detail",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/PluginDetailREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No plugin with the given name exists in this namespace",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Plugins"
        ],
        "summary": "Deletes (deregisters) a plugin.",
        "description": "Deletion drops the pinned compiled type so its collectible load context can unload once\nin-flight invocations finish. Removal compiles nothing; it carries only the standard\nauthentication (not the dynamic-plugin capability).",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The plugin name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The plugin was deleted"
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No plugin with the given name exists in this namespace",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The removal transaction was rolled back and did not complete"
          }
        }
      }
    },
    "/save": {
      "put": {
        "tags": [
          "Admin"
        ],
        "summary": "Saves the current database state to a file",
        "description": "Sample request:\n\n    PUT /save\n    {\n       \"saveGameLocation\": \"C:/Fallen8/database.f8s\",\n       \"savePartitions\": 8\n    }\n\nBoth parameters are optional. If not provided, the save goes to the configured durability\nstorage directory (Fallen8:Durability:StorageDirectory; the app base directory when unset)\nusing the CheckpointBaseName (\"Temp.f8s\" by default) and the optimal partition count.\nThe save is recorded in the save-game registry (feature save-games); the response is the\ncreated entry, whose \"location\" field is the path the database was saved to.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Save specification including file path and partition options (both optional)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SaveSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SaveSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the created save-game registry entry",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SaveGameREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid save specification",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The save transaction was rolled back and did not complete",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/save/all": {
      "put": {
        "tags": [
          "Admin"
        ],
        "summary": "Saves every namespace into one save-game entry (Fallen-8-level — all namespaces)",
        "description": "One consistent restore point for the whole Fallen-8: each namespace is checkpointed to\nits own default location and the registry records a single entry whose \"namespaces\"\nmanifest lists every member. Restore the whole entry - or a single namespace out of it -\nvia PUT /savegames/{id}/load.\n\nA namespace that is cataloged but NOT loaded in this process is never a member of a save\n(feature namespace-startup-load): it is skipped, its checkpoint and write-ahead log are\nleft untouched, and it is named in the response's \"skippedNamespaces\" (on the 200 body,\nand as a problem extension on the 500) - so the entry spanning a strict subset of the\nFallen-8 is visible rather than implied.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the created save-game registry entry, plus \"skippedNamespaces\" when it does not span every namespace",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SaveGameREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SaveGameREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SaveGameREST"
                }
              }
            }
          },
          "429": {
            "description": "The sensitive-endpoint rate limit was exceeded",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "At least one namespace's save failed (the body names it; successfully saved namespaces are still registered)"
          }
        }
      }
    },
    "/savegames": {
      "get": {
        "tags": [
          "SaveGames"
        ],
        "summary": "Lists all registered save games, newest first",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The registered save games",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SaveGameREST"
                  }
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/savegames/{id}": {
      "get": {
        "tags": [
          "SaveGames"
        ],
        "summary": "Gets a single registered save game by id",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The save-game id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The save game",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SaveGameREST"
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "No save game with that id",
            "content": {
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "SaveGames"
        ],
        "summary": "Removes a save game from the registry, optionally deleting its files",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The save-game id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deleteFiles",
            "in": "query",
            "description": "When true, also delete the checkpoint files on disk",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Removed"
          },
          "404": {
            "description": "No save game with that id",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/savegames/{id}/load": {
      "put": {
        "tags": [
          "SaveGames"
        ],
        "summary": "Restores a registered save game's namespaces, replacing their in-memory graphs",
        "description": "Restores exactly the namespaces the entry contains (feature graph-namespaces): a dropped\nnamespace is recreated, an existing one has its content replaced, and namespaces the\nentry does NOT contain are left untouched. Pre-namespace (v1) entries restore into\n\"default\". With ?namespace={name}, only that one namespace is restored.\n\nA member that is cataloged but NOT loaded in this process is ACTIVATED and its\nstartup-load policy is set to \"enabled\" (feature namespace-startup-load, spec decision\n8.3), and both are reported in the response's \"activatedNamespaces\". Activating without\nthe policy would let the restored data go invisible again at the next boot; refusing\nwould dead-end a legitimate recovery behind \"change policy, restart, restore\". Such a\nmember is loaded synchronously even with waitForCompletion=false, whose 202 carries no\nbody - GET /ns then shows it as loaded.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The save-game id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "Wait for the load transactions to finish before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "namespace",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Loaded (waited); returns the save game, plus \"activatedNamespaces\" when it had to load one",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SaveGameREST"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SaveGameREST"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SaveGameREST"
                }
              }
            }
          },
          "202": {
            "description": "Load accepted (not waited)"
          },
          "404": {
            "description": "No save game with that id, or the entry does not contain the requested namespace",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "A load transaction was rolled back, a dropped namespace could not be recreated, or a not-loaded member could not be activated"
          }
        }
      }
    },
    "/scan/graph/properties": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Scans every property of every element for a case-insensitive substring match (discovery search)",
        "description": "The all-property companion to `POST /scan/graph/property/{propertyId}`: singular scans one\nnamed key with a typed operator; this plural route scans EVERY property value. Each value is\nrendered to its invariant-culture text form (so numbers, booleans and dates are searchable too)\nand tested with a case-insensitive Contains; an element matches when ANY of its values matches.\nIt is a cold, un-indexed O(elements x properties) scan - use an index for scale. Reserved\nembedding entries are never matched.\n\nSample request:\n\n    POST /scan/graph/properties\n    {\n       \"searchTerm\": \"acme\",\n       \"label\": \"company\",\n       \"resultType\": \"Both\"\n    }\n\nThe optional \"label\" field restricts the scan to elements whose label matches exactly;\nomit it to scan every element type.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Search specification with the term, optional label restrictor and result type",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySearchSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PropertySearchSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the matching element IDs (empty when nothing matches)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or the search term was blank",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/scan/graph/property/{propertyId}": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Scans the graph for elements with a specific property value",
        "description": "Sample request:\n\n    POST /scan/graph/property/name\n    {\n       \"operator\": 0,\n       \"literal\": {\n         \"value\": \"John Doe\",\n         \"fullQualifiedTypeName\": \"System.String\"\n       },\n       \"resultType\": \"Vertices\"\n    }\n\nThe optional \"label\" field restricts the scan to elements whose label matches exactly\n(e.g. \"person\"); omit it to scan every element type.",
        "parameters": [
          {
            "name": "propertyId",
            "in": "path",
            "description": "The property ID to scan for",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Scan specification with comparison operator and value",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/ScanSpecification"
              }
            },
            "text/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/ScanSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/ScanSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the matching element IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid scan specification",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/scan/index/all": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Performs a scan operation on an index with a specific value and operator",
        "description": "Sample request:\n\n    POST /scan/index/all\n    {\n       \"indexId\": \"userNameIndex\",\n       \"operator\": 0,\n       \"literal\": {\n         \"value\": \"Jane\",\n         \"fullQualifiedTypeName\": \"System.String\"\n       },\n       \"resultType\": \"Vertices\"\n    }\n\nThe optional \"label\" field restricts the hits to elements whose label matches exactly\n(e.g. \"person\"); omit it to return every match.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Index scan specification with index ID, operator and value",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexScanSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/IndexScanSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the matching element IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid scan specification or index not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/scan/index/fulltext": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Performs a fulltext search on an indexed property",
        "description": "Sample request:\n\n    POST /scan/index/fulltext\n    {\n       \"indexId\": \"documentIndex\",\n       \"requestString\": \"graph database nosql\"\n    }",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Fulltext search specification with index ID and search terms",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/FulltextIndexScanSpecification"
              }
            },
            "text/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/FulltextIndexScanSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/FulltextIndexScanSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the search results with highlighting",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/FulltextSearchResultREST"
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "The index does not exist or is not a fulltext index (a miss yields 204 No Content, not a 404)",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/scan/index/range": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Performs a range-based scan on an index between two values",
        "description": "Sample request:\n\n    POST /scan/index/range\n    {\n       \"indexId\": \"ageIndex\",\n       \"leftLimit\": \"18\",\n       \"rightLimit\": \"30\",\n       \"includeLeft\": true,\n       \"includeRight\": false,\n       \"fullQualifiedTypeName\": \"System.Int32\",\n       \"resultType\": \"Vertices\"\n    }",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Range scan specification with index ID, limits and include/exclude options",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/RangeIndexScanSpecification"
              }
            },
            "text/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/RangeIndexScanSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/RangeIndexScanSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the matching element IDs within the range",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Invalid range specification or index not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/scan/index/spatial": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Performs a spatial distance search using a spatial index",
        "description": "Sample request:\n\n    POST /scan/index/spatial\n    {\n       \"indexId\": \"locationIndex\",\n       \"graphElementId\": 123,\n       \"distance\": 5.0\n    }",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Spatial search specification with index ID, reference element and distance",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SearchDistanceSpecification"
              }
            },
            "text/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SearchDistanceSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SearchDistanceSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the element IDs within the specified distance",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "The index does not exist, is not a spatial index, or the reference element does not exist (a miss yields 204 No Content, not a 404)",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/scan/index/vector": {
      "post": {
        "tags": [
          "Graph"
        ],
        "summary": "Finds the k nearest neighbours of a query vector in a vector index",
        "description": "Exact brute-force kNN (SIMD): deterministic ordering - best score first, ties broken\nby ascending element id. Constraints are applied BEFORE scoring, so the returned k are\nk MATCHING elements. Removed elements never appear. The GraphRAG recipe: feed the\nreturned element ids into the existing traversal surface (POST /path, PUT /subgraph,\nproperty reads) - similarity search lands ON the graph.\n\nSample request:\n\n    POST /scan/index/vector\n    {\n       \"indexId\": \"myEmbeddings\",\n       \"query\": [0.1, 0.2, 0.3],\n       \"k\": 10,\n       \"kind\": \"vertex\",\n       \"label\": \"person\"\n    }",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The kNN query: index, query vector, k, optional kind/label constraints",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VectorIndexScanSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VectorIndexScanSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the k best-scoring matching elements (fewer when the corpus is smaller)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/VectorSearchResultREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "Not a vector index, wrong query dimension, NaN/Infinity components, k outside [1, 1024], zero-norm query under Cosine, or an unknown kind value",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The index does not exist",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/service": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Creates a new service based on the specified plugin",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Plugin specification including type, ID and options",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/PluginSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns true if the service was created; false if the plugin type is unknown or the id already exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The request body was missing or malformed",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/service/{key}": {
      "delete": {
        "tags": [
          "Admin"
        ],
        "summary": "Deletes a service with the specified key",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "description": "The unique identifier of the service to delete",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns whether the service was successfully deleted",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "boolean"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/statistics": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "summary": "Returns a graph-shape snapshot: counts, cardinalities, degrees, indices, memory",
        "description": "The result is an ADVISORY snapshot, not transactionally consistent: reads are\nlock-free over the volatile element snapshot, so a write committed during the pass\nmay or may not appear.\n\nCOST (honest): counts and memory are O(1); labels and property keys are one pass\nover the element snapshot; degrees are O(1) adjacency-count reads per vertex. When\nV+E exceeds the configured element budget (Fallen8:Observability:StatisticsElementBudget,\ndefault 1,000,000) the pass samples with a uniform stride and the response says so:\nsampled=true, sampleStride, per-name counts as counted IN THE SAMPLE (multiply by\nthe stride to extrapolate), distinctTotal = distinct within the sample (sampling\nhonestly undercounts distinct values). Degree percentiles from a strided sample are\nstatistically sound. Memory numbers never force a GC.\n\nThis endpoint exposes SCHEMA-SHAPED data (label names, property keys, index names),\nso it sits behind the normal API-key policy - unlike /metrics, whose inventory is\naggregate numbers only - and under the sensitive rate limiter so a misconfigured\nscrape loop cannot turn an O(V+E) pass into a DoS.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The snapshot",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/GraphStatisticsREST"
                }
              },
              "application/json": { }
            }
          },
          "429": {
            "description": "Rate limited (the sensitive fixed-window limiter)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/status": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "Gets the current status of the Fallen-8 database",
        "description": "The anonymous connection probe. It is also the ONE namespace-scoped route that still\nanswers for a namespace this process did not load (feature namespace-startup-load): it\nthen reports \"namespaceState\": \"notLoaded\" and leaves every engine-derived field null\n(counts, index inventory, available plugins, durability) rather than reporting zeros or\nempty lists. Every other namespace-scoped route refuses such a namespace with 503.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the database status information",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/StatusREST"
                }
              },
              "application/json": { }
            }
          }
        },
        "security": [ ]
      }
    },
    "/storedquery": {
      "post": {
        "tags": [
          "StoredQueries"
        ],
        "summary": "Registers a stored query: validates and compiles the specification, then publishes it under a unique name.",
        "description": "Exactly one of \"path\" / \"subGraph\" must be present and must match \"kind\". The code\nfragments are compiled ONCE here, with the same bounds as the inline endpoints; a\ncompile failure rejects the registration with the compiler diagnostics. Entries are\nimmutable: to change one, delete and re-register.\n\nSECURITY: registration compiles C# fragments with Roslyn that later execute IN-PROCESS\nWITH FULL TRUST. It carries the same authentication as the inline code endpoints\n(required whenever an API key is configured); dynamic code execution itself is always on.\n\nSample request:\n\n    POST /storedquery\n    {\n       \"name\": \"adults-shortest\",\n       \"kind\": \"Path\",\n       \"description\": \"age&gt;30 vertices, weight-by-distance\",\n       \"path\": {\n         \"filter\": { \"vertexFilter\": \"return (v) =&gt; v.TryGetProperty(out int age, \\\"age\\\") &amp;&amp; age &gt; 30;\" },\n         \"cost\":   { \"edgeCost\": \"return (e) =&gt; 1.0;\" }\n       }\n    }",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The stored query specification (name, kind, and the matching path/subGraph block)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/StoredQuerySpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/StoredQuerySpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The stored query was compiled and registered",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/StoredQuerySummaryREST"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The specification was malformed (name/kind/block), or a fragment failed to compile (the body carries the compiler diagnostics)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "A stored query with the same name already exists, or the library quota (Fallen8:StoredQueries:MaxCount) was reached",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The registration transaction faulted with an internal error",
            "content": {
              "application/json": { }
            }
          }
        }
      },
      "get": {
        "tags": [
          "StoredQueries"
        ],
        "summary": "Lists all registered stored queries.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the stored query summaries",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StoredQuerySummaryREST"
                  }
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/storedquery/{name}": {
      "get": {
        "tags": [
          "StoredQueries"
        ],
        "summary": "Gets the full definition of a stored query, including its source specification.",
        "description": "The response includes the stored specification JSON (the registration request's\npath/subGraph block), which also covers manual migration between instances, and - for\na Failed entry - the recompile diagnostics.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The stored query name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the stored query detail",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/StoredQueryDetailREST"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No stored query with the given name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "StoredQueries"
        ],
        "summary": "Deletes (deregisters) a stored query.",
        "description": "Deletion drops the pinned compiled artifact so its collectible load context can unload\nonce in-flight invocations finish. Removal compiles nothing; it carries only the\nstandard authentication (the API key when one is configured).",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The stored query name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The stored query was deleted"
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No stored query with the given name exists",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The removal transaction was rolled back and did not complete"
          }
        }
      }
    },
    "/subgraph": {
      "put": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Creates and registers a new subgraph from a specification.",
        "description": "Filter and pattern predicates are C# code fragments prefixed with \"return\", compiled\nat runtime. A null/empty fragment matches everything.\n\nInstead of inline fragments, the body may reference a registered stored query of kind\n\"SubGraph\" via \"storedQuery\" (mutually exclusive with \"vertexFilter\"/\"edgeFilter\"/\n\"patterns\"): the stored template is instantiated under this request's \"name\" and\nnothing is compiled per request. The created subgraph is self-contained - deleting the\nstored query later does not affect it.\n\nSEMANTIC SUBGRAPHS (feature element-embeddings): an optional \"semantic\" block carries\na query vector (or \"queryText\" via the embedding provider) bound at REGISTRATION -\nrecalculation reuses it and never embeds anything. \"minScore\" becomes the code-free\nvertex pre-filter, a vertex pattern step's \"semanticMinScore\" that step's filter\n(feature subgraph-semantic-thresholds); compiled fragments read the same vector via\n\"context\". Pure data (it compiles no C#); not available on\nstored-template invocations.\nFull rules: features/element-embeddings README, \"Semantic traversal\".\n\nSECURITY: inline filter/pattern fragments are compiled with Roslyn and executed\nIN-PROCESS WITH FULL TRUST - a trust boundary, not a sandbox. Dynamic code execution is\nALWAYS ON (there is no switch to disable it), so authentication (required whenever an API\nkey is configured) is the boundary. Instantiating an operator-registered stored query\nnarrows WHO can introduce code, but the invoked query still runs with full trust.\n\nSample request:\n\n    PUT /subgraph\n    {\n       \"name\": \"friends-of-alice\",\n       \"vertexFilter\": \"return (v) =&gt; v.Label == \\\"person\\\";\",\n       \"patterns\": [\n         { \"type\": \"Vertex\", \"patternName\": \"start\", \"vertexFilter\": \"return (v) =&gt; v.Label == \\\"person\\\";\" },\n         { \"type\": \"Edge\", \"patternName\": \"rel\", \"direction\": \"OutgoingEdge\", \"edgePropertyFilter\": \"return (p) =&gt; p == \\\"knows\\\";\" },\n         { \"type\": \"Vertex\", \"patternName\": \"end\", \"vertexFilter\": \"return (v) =&gt; v.Label == \\\"person\\\";\" }\n       ]\n    }",
        "parameters": [
          {
            "name": "fromSubGraph",
            "in": "query",
            "description": "Optional name of an existing subgraph to source this one from (creates a nested subgraph). When omitted, the subgraph is sourced from the whole graph.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The subgraph specification (name, filters, patterns)",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SubGraphSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/SubGraphSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The subgraph was created and registered. A syntactically-valid pattern that matches nothing yields a registered EMPTY subgraph (201), identically whether the source graph is empty or populated.",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SubGraphSummary"
                }
              },
              "application/json": { }
            }
          },
          "401": {
            "description": "No valid credential was supplied",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "400": {
            "description": "The specification was invalid, the pattern was structurally invalid, a filter failed to compile, storedQuery was mixed with inline fragments, the referenced stored query has the wrong kind, or the requested algorithm is not an available subgraph plugin",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "The source subgraph named by fromSubGraph does not exist, or no stored query with the referenced name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "A subgraph with the same name already exists, a resource quota (subgraph count or materialized-element ceiling) was exceeded, or the referenced stored query is not invocable (its recompile on load failed)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The create transaction faulted with an internal error",
            "content": {
              "application/json": { }
            }
          }
        }
      },
      "get": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Lists the names of all registered subgraphs.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of subgraph names",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/subgraph/{name}": {
      "get": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Gets a summary (metadata and element counts) of a registered subgraph.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The subgraph name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the subgraph summary",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SubGraphSummary"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No subgraph with the given name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Deregisters (deletes) a subgraph.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The subgraph name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The subgraph was deleted"
          },
          "404": {
            "description": "No subgraph with the given name exists",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The removal transaction was rolled back and did not complete"
          }
        }
      }
    },
    "/subgraph/{name}/graph": {
      "get": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Gets the extracted contents (vertices and edges) of a registered subgraph.",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The subgraph name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "maxElements",
            "in": "query",
            "description": "Maximum number of vertices and edges to return (default 1000)",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32",
              "default": 1000
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the subgraph contents",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/Graph"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No subgraph with the given name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/subgraph/{name}/recalculate": {
      "post": {
        "tags": [
          "SubGraph"
        ],
        "summary": "Recalculates a subgraph against the current state of its source graph.",
        "description": "Only subgraphs created by an algorithm (with a stored source and plugin name)\ncan be recalculated; manually registered subgraphs cannot.\n\nThe materialized-element quotas bound a refresh exactly as they bound the create: a\nrecalculation whose fresh extraction would exceed the per-subgraph or total element\nceiling is rejected and the subgraph KEEPS its previous, in-quota contents (it stays\nstale until the quota is raised or it is deleted).",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "description": "The subgraph name",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the recalculated subgraph summary",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/SubGraphSummary"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "No subgraph with the given name exists",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "409": {
            "description": "The subgraph exists but cannot be recalculated: either its source graph or algorithm plugin is missing, or the recalculated extraction would exceed a materialized-element quota (previous contents kept)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/tabularasa": {
      "head": {
        "tags": [
          "Admin"
        ],
        "summary": "Erases the addressed namespace's data (the namespace stays registered, empty)",
        "description": "Bare /tabularasa erases the \"default\" namespace; /ns/{ns}/tabularasa erases that\nnamespace. The Fallen-8-wide factory reset is HEAD /tabularasa/all.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Namespace clear successfully enqueued (this void action returns 200 with an empty body, not 204)"
          }
        }
      }
    },
    "/tabularasa/all": {
      "head": {
        "tags": [
          "Admin"
        ],
        "summary": "Factory reset: drops every non-default namespace and erases \"default\" (Fallen-8-level — all namespaces)",
        "description": "Irreversible. Dropped namespaces lose their on-disk data; save-game entries remain\nvalid restore points. Afterwards only an empty \"default\" namespace exists.",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "All namespaces erased"
          },
          "429": {
            "description": "The sensitive-endpoint rate limit was exceeded",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/trim": {
      "head": {
        "tags": [
          "Admin"
        ],
        "summary": "Trims the database, releasing unused memory",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Trim operation successfully enqueued (this void action returns 200 with an empty body, not 204)"
          }
        }
      }
    },
    "/unittest": {
      "put": {
        "tags": [
          "SampleGraph"
        ],
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/vertex": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Creates a new vertex in the graph",
        "description": "Sample request:\n\n    PUT /vertex\n    {\n       \"label\": \"person\",\n       \"creationDate\": 1713862800,\n       \"properties\": [\n         {\n           \"propertyId\": \"name\",\n           \"propertyValue\": \"John Doe\",\n           \"fullQualifiedTypeName\": \"System.String\"\n         }\n       ]\n    }",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits for the transaction to complete before responding",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The vertex specification containing label and property information",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VertexSpecification"
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "$ref": "#/components/schemas/VertexSpecification"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Vertex creation accepted (and committed when waitForCompletion is true)"
          },
          "400": {
            "description": "Invalid vertex specification",
            "content": {
              "text/plain; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waitForCompletion is true)"
          }
        }
      }
    },
    "/vertex/count": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "Gets the total number of vertices in the database",
        "parameters": [
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the number of vertices",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "int32"
                }
              },
              "application/json": { }
            }
          }
        },
        "security": [ ]
      }
    },
    "/vertex/{vertexIdentifier}": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Retrieves a vertex from the graph by its identifier",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex to retrieve",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the vertex object",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/Vertex"
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "Vertex with the specified ID was not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/vertex/{vertexIdentifier}/edges/in": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets all available incoming edge property IDs for a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of incoming edge property IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "Vertex has no incoming edges or vertex not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/vertex/{vertexIdentifier}/edges/in/{edgePropertyIdentifier}": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets incoming edges of a specific type to a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "edgePropertyIdentifier",
            "in": "path",
            "description": "The edge property identifier/type to filter by",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of matching incoming edge IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "No matching edges found or vertex not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/vertex/{vertexIdentifier}/edges/in/{edgePropertyIdentifier}/degree": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the count of incoming edges of a specific type for a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "edgePropertyIdentifier",
            "in": "path",
            "description": "The edge property identifier/type to count",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the count of matching incoming edges (0 if the vertex has no such edge group)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "uint32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Vertex with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/vertex/{vertexIdentifier}/edges/indegree": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the total count of incoming edges for a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the count of incoming edges",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "uint32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Vertex with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/vertex/{vertexIdentifier}/edges/out": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets all available outgoing edge property IDs for a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of outgoing edge property IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "Vertex has no outgoing edges or vertex not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/vertex/{vertexIdentifier}/edges/out/{edgePropertyIdentifier}": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets outgoing edges of a specific type from a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "edgePropertyIdentifier",
            "in": "path",
            "description": "The edge property identifier/type to filter by",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the list of matching outgoing edge IDs",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "204": {
            "description": "No matching edges found or vertex not found",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    },
    "/vertex/{vertexIdentifier}/edges/out/{edgePropertyIdentifier}/degree": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the count of outgoing edges of a specific type from a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "edgePropertyIdentifier",
            "in": "path",
            "description": "The edge property identifier/type to count",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the count of matching outgoing edges (0 if the vertex has no such edge group)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "uint32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Vertex with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/vertex/{vertexIdentifier}/edges/outdegree": {
      "get": {
        "tags": [
          "Graph"
        ],
        "summary": "Gets the total count of outgoing edges for a vertex",
        "parameters": [
          {
            "name": "vertexIdentifier",
            "in": "path",
            "description": "The ID of the vertex",
            "required": true,
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the count of outgoing edges",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                  "type": [
                    "integer",
                    "string"
                  ],
                  "format": "uint32"
                }
              },
              "application/json": { }
            }
          },
          "404": {
            "description": "Vertex with the specified ID was not found",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          }
        }
      }
    },
    "/vertices": {
      "put": {
        "tags": [
          "Graph"
        ],
        "summary": "Creates many vertices in ONE atomic transaction (feature mcp-followups)",
        "description": "The batch write path: far fewer round-trips than one `PUT /vertex` per vertex, and -\nunlike the single endpoint (202, no body) - a waited-on call RETURNS the assigned vertex\nids so a caller can immediately reference them (e.g. to create edges).",
        "parameters": [
          {
            "name": "waitForCompletion",
            "in": "query",
            "description": "When true, waits and returns the assigned ids in input order",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "api-version",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Version",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The vertices to create",
          "content": {
            "application/json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/VertexSpecification"
                }
              }
            },
            "application/*+json; ver=0.1": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/VertexSpecification"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returns the assigned vertex ids in input order (waitForCompletion=true)",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "type": "array",
                  "items": {
                    "pattern": "^-?(?:0|[1-9]\\d*)$",
                    "type": [
                      "integer",
                      "string"
                    ],
                    "format": "int32"
                  }
                }
              },
              "application/json": { }
            }
          },
          "202": {
            "description": "Batch accepted (waitForCompletion=false)",
            "content": {
              "application/json": { }
            }
          },
          "400": {
            "description": "A null list, or a null/invalid vertex specification",
            "content": {
              "application/json; ver=0.1": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": { }
            }
          },
          "500": {
            "description": "The transaction was rolled back with an internal error (only when waited)",
            "content": {
              "application/json": { }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AGraphElement": {
        "required": [
          "id",
          "creationDate",
          "modificationDate"
        ],
        "type": "object",
        "properties": {
          "id": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The unique identifier of the graph element",
            "format": "int32",
            "default": 123,
            "example": 123
          },
          "creationDate": {
            "type": "string",
            "description": "The date and time when the element was created",
            "format": "date-time",
            "example": "2025-04-22T10:00:00Z"
          },
          "modificationDate": {
            "type": "string",
            "description": "The date and time when the element was last modified",
            "format": "date-time",
            "example": "2025-04-22T10:00:00Z"
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "The type label of the graph element used for categorization",
            "default": "person",
            "example": "person"
          },
          "properties": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PropertySpecification"
            },
            "description": "The collection of properties (key-value pairs) associated with the graph element"
          }
        },
        "description": "Abstract base class for all graph elements (vertices and edges)"
      },
      "AlgorithmPluginRegistration": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The unique name to register under (per namespace). Must equal the type's `PluginName`."
          },
          "contract": {
            "type": [
              "null",
              "string"
            ],
            "description": "The contract the source implements: \"Path\", \"SubGraph\" or \"Analytics\"."
          },
          "description": {
            "type": [
              "null",
              "string"
            ],
            "description": "An optional human-readable description."
          },
          "sourceCode": {
            "type": [
              "null",
              "string"
            ],
            "description": "The whole-type C# source implementing the contract's interface."
          }
        },
        "description": "Request body for `POST /plugins/algorithm` (feature plugin-registration): register a\nruntime-authored algorithm plugin from whole-type C# source.",
        "example": {
          "name": "MyDijkstra",
          "contract": "Path",
          "description": "a custom weighted shortest path",
          "sourceCode": "using ...; public sealed class MyDijkstra : IShortestPathAlgorithm { ... }"
        }
      },
      "AnalyticsResultREST": {
        "type": "object",
        "properties": {
          "algorithm": {
            "type": [
              "null",
              "string"
            ],
            "description": "The plugin that ran.",
            "example": "PAGERANK"
          },
          "converged": {
            "type": "boolean",
            "description": "Whether the iterative algorithm converged (single-pass algorithms: true).\n    False with usable values when the iteration cap stopped the run.",
            "example": true
          },
          "iterationsRun": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Completed iterations.",
            "format": "int32",
            "example": 23
          },
          "elapsedMs": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Wall-clock duration in milliseconds.",
            "format": "double",
            "example": 184.2
          },
          "budgetExhausted": {
            "type": "boolean",
            "description": "True when the time budget or cancellation stopped the run and the values\n    are the last completed iteration's (partial relative to the requested work).",
            "example": false
          },
          "vertexCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "How many vertices were in scope for the run.",
            "format": "int32",
            "example": 2500000
          },
          "statistics": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "double"
            },
            "description": "Run-level aggregates: TriangleCount, ComponentCount, CommunityCount,\n    degree Min/Max/Mean."
          },
          "results": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/ScoredVertexREST"
            },
            "description": "Top-K scored vertices (score algorithms only), best first."
          },
          "partitions": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PartitionSummaryREST"
            },
            "description": "Partition summaries (partition algorithms only), largest first."
          },
          "writeBack": {
            "description": "The write-back report; null when the request did not opt in.",
            "$ref": "#/components/schemas/WriteBackResultREST"
          }
        },
        "description": "One analytics run's response: run metadata, statistics, and the BOUNDED projection of\nthe per-vertex result (top-K scores or partition summaries - the full result set's\ndelivery vehicle is write-back)."
      },
      "AnalyticsSpecification": {
        "type": "object",
        "properties": {
          "vertexLabel": {
            "type": [
              "null",
              "string"
            ],
            "description": "Only vertices with exactly this label participate (induced-subgraph\n    scoping); null = whole graph.",
            "example": "person"
          },
          "edgePropertyId": {
            "type": [
              "null",
              "string"
            ],
            "description": "Only edges in this adjacency group (edge-property-id) are traversed;\n    null = all edges.",
            "example": "knows"
          },
          "direction": {
            "type": [
              "null",
              "string"
            ],
            "description": "Edge-direction interpretation: \"in\", \"out\" or \"both\". Null selects the\n    algorithm's default (PAGERANK: out; DEGREE and LABELPROPAGATION: both; WCC and\n    TRIANGLECOUNT ignore direction).",
            "example": "out"
          },
          "maxIterations": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Iteration cap for iterative algorithms (PAGERANK default 100,\n    LABELPROPAGATION default 20; ceiling 10000). Reaching the cap is a normal outcome:\n    converged=false, values usable.",
            "format": "int32",
            "example": 100
          },
          "epsilon": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "PageRank convergence threshold (L1 delta); 0 selects the default 1e-6.",
            "format": "double",
            "example": 0.000001
          },
          "timeBudgetSeconds": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "Wall-clock budget in seconds; null selects the configured default (30 s).\n    Values above the configured ceiling are a 400.",
            "format": "int32",
            "example": 30
          },
          "parameters": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "double"
            },
            "description": "Algorithm-specific numeric knobs, e.g. {\"DampingFactor\": 0.85}."
          },
          "maxResults": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "How many rows the response carries (top-K scores or partition summaries).\n    Default 100, ceiling 10000 - the full result set's delivery vehicle is write-back,\n    not pagination through millions.",
            "format": "int32",
            "example": 100
          },
          "offset": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Offset into a partition's membership page (partition endpoint only).",
            "format": "int32",
            "example": 0
          },
          "writeBack": {
            "type": "boolean",
            "description": "Opt-in: write each in-scope vertex's value as a property through chunked\n    plugin write transactions. Snapshot-durable only (a WAL-only replay loses the\n    properties; re-run to restore) - the mode-(a) contract of DelegateTransaction.",
            "example": false
          },
          "writeBackPropertyKey": {
            "type": [
              "null",
              "string"
            ],
            "description": "Overrides the convention property key (e.g. \"analytics.pagerank\");\n    non-empty, at most 256 chars.",
            "example": "analytics.pagerank"
          }
        },
        "description": "One analytics run request (feature graph-analytics): data-only scoping, budgets,\nalgorithm parameters, the bounded-result knob and the opt-in property write-back.\nNo dynamic code anywhere - these endpoints compile no C#.",
        "example": {
          "vertexLabel": "person",
          "maxResults": 10,
          "parameters": {
            "DampingFactor": 0.85
          }
        }
      },
      "BenchmarkResultREST": {
        "type": "object",
        "properties": {
          "iterations": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Number of timed iterations the statistics are computed over",
            "format": "int32"
          },
          "edgesTraversed": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Edges traversed in a single iteration",
            "format": "int64"
          },
          "averageTps": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Mean traversals per second across iterations",
            "format": "double"
          },
          "medianTps": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Median traversals per second across iterations",
            "format": "double"
          },
          "standardDeviationTps": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Standard deviation of the per-iteration TPS samples",
            "format": "double"
          }
        },
        "description": "Structured result of the edge-traversal benchmark (GET /ns/{ns}/benchmark)"
      },
      "BinaryOperator": {
        "type": "integer"
      },
      "BulkImportResultREST": {
        "type": "object",
        "properties": {
          "verticesCreated": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The number of vertices created.",
            "format": "int32",
            "example": 10000
          },
          "edgesCreated": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The number of edges created.",
            "format": "int32",
            "example": 25000
          },
          "linesRead": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The number of lines read from the request body (including meta and blank lines).",
            "format": "int64",
            "example": 35001
          }
        },
        "description": "The success summary of a bulk JSONL import (feature bulk-import-export)."
      },
      "CardinalityStatsREST": {
        "type": "object",
        "properties": {
          "top": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/NamedCountREST"
            },
            "description": "The top-N entries, count-descending."
          },
          "distinctTotal": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Distinct names seen (within the sample when sampled=true).",
            "format": "int32",
            "example": 17
          }
        },
        "description": "Top-N names by count plus the distinct total. Sampling honestly UNDERCOUNTS\n    distinct values: when sampled=true, distinctTotal is distinct-within-the-sample - the\n    DTO documents that rather than pretending to estimate."
      },
      "ChatMessageSpecification": {
        "required": [
          "content"
        ],
        "type": "object",
        "properties": {
          "role": {
            "type": [
              "null",
              "string"
            ],
            "description": "The role: `system`, `user`, `assistant`, or `tool`\n    (unknown values are treated as `user`).",
            "example": "user"
          },
          "content": {
            "type": [
              "null",
              "string"
            ],
            "description": "The message content.",
            "example": "Draft a vertex filter for label person"
          }
        },
        "description": "One chat turn."
      },
      "ChatOptionsSpecification": {
        "type": "object",
        "properties": {
          "temperature": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "description": "Sampling temperature (backend default when omitted).",
            "format": "double",
            "example": 0.1
          }
        },
        "description": "Optional per-request generation knobs."
      },
      "ChatProviderStatsREST": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Whether the capability flag (Fallen8:Chat:Enabled) is on."
          },
          "backend": {
            "type": [
              "null",
              "string"
            ],
            "description": "The backend selector (config value), e.g. Ollama."
          },
          "model": {
            "type": [
              "null",
              "string"
            ],
            "description": "The server-owned model."
          },
          "loaded": {
            "type": "boolean",
            "description": "Whether the backend client has been created (a chat call happened)."
          },
          "resident": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "Whether the model is currently loaded in the backend (Ollama /api/ps): true =\n    warm, false = not loaded right now (loads on first use), null = undeterminable or not an\n    Ollama backend. A point-in-time read, only set on GET /config."
          },
          "gpu": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "Best-effort GPU residency of the model: true/false when the backend reports it,\n    null when undeterminable (or not probed). A point-in-time read, only set on GET /config."
          }
        },
        "description": "The chat gateway state (feature instance-config), mirroring the embedding block's\n    shape: it lives on the cheap /status probe (capability discovery) and on GET /config (the\n    operator view). No endpoint is exposed, matching the embedding block's tag hygiene."
      },
      "ChatResultREST": {
        "type": "object",
        "properties": {
          "content": {
            "type": [
              "null",
              "string"
            ],
            "description": "The assistant message content."
          },
          "model": {
            "type": [
              "null",
              "string"
            ],
            "description": "The model that produced it (the server-owned model).",
            "example": "phi4-f8-mini"
          },
          "stats": {
            "description": "Generation stats (token counts and durations); fields are null when the\n    backend does not report them.",
            "$ref": "#/components/schemas/ChatStatsREST"
          }
        },
        "description": "A chat completion plus the backend's generation stats."
      },
      "ChatSpecification": {
        "required": [
          "messages"
        ],
        "type": "object",
        "properties": {
          "messages": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/ChatMessageSpecification"
            },
            "description": "The conversation turns, in order (at least one)."
          },
          "options": {
            "description": "Optional generation knobs.",
            "$ref": "#/components/schemas/ChatOptionsSpecification"
          }
        },
        "description": "A chat completion request proxied to the instance's model backend (feature\n    instance-config). The model is SERVER-owned (`Fallen8:Chat:Ollama:Model`); there is no\n    client model field.",
        "example": {
          "messages": [
            {
              "role": "user",
              "content": "Draft a vertex filter for label person"
            }
          ]
        }
      },
      "ChatStatsREST": {
        "type": "object",
        "properties": {
          "promptTokens": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "Prompt (input) token count.",
            "format": "int64"
          },
          "completionTokens": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "Completion (output) token count.",
            "format": "int64"
          },
          "durationMs": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "description": "Total wall-clock generation time in milliseconds.",
            "format": "double"
          },
          "tokensPerSecond": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "description": "Output tokens per second.",
            "format": "double"
          }
        },
        "description": "Generation stats forwarded from the backend."
      },
      "ChunkHitREST": {
        "type": "object",
        "properties": {
          "chunkId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "documentId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "score": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "float"
          },
          "order": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "text": {
            "type": [
              "null",
              "string"
            ]
          },
          "headingPath": {
            "type": [
              "null",
              "string"
            ]
          },
          "pageFrom": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pageTo": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "identifiers": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          },
          "window": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/ChunkWindowEntryREST"
            },
            "description": "Sibling chunks in document order, the hit itself excluded (window &gt; 0)."
          }
        },
        "description": "One retrieved chunk. The score is mode-dependent: RRF when fused, the raw\n    kNN score when dense, the fulltext match count when lexical."
      },
      "ChunkSummaryREST": {
        "type": "object",
        "properties": {
          "chunkId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "order": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "kind": {
            "type": [
              "null",
              "string"
            ],
            "example": "text"
          },
          "headingPath": {
            "type": [
              "null",
              "string"
            ]
          },
          "pageFrom": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pageTo": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "identifiers": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          },
          "textPreview": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "One chunk on GET /document/{id} - a PREVIEW; the full text is the chunk\n    vertex's `text` property, readable via the graph element routes."
      },
      "ChunkWindowEntryREST": {
        "type": "object",
        "properties": {
          "chunkId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "order": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "text": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "One sibling chunk of a hit's window (FR-12)."
      },
      "ConfigREST": {
        "type": "object",
        "properties": {
          "semantic": {
            "description": "The semantic providers (embedding + chat).",
            "$ref": "#/components/schemas/SemanticConfigREST"
          },
          "observability": {
            "description": "The observability posture (OTLP / Prometheus / sampling).",
            "$ref": "#/components/schemas/ObservabilityConfigREST"
          },
          "apiKeyRequired": {
            "type": "boolean",
            "description": "Whether an API key is configured (never the key itself)."
          }
        },
        "description": "The instance's read-only configuration view (feature instance-config), the single home\nfor the Studio Configuration section: the semantic providers and the observability\nposture. Secrets are never emitted (no API key, no credentials); only the boolean\nbool ConfigREST.ApiKeyRequired reports the security posture. Fallen-8-level and API-key\ngated (like /statistics); config is startup-bound, so this is display-only."
      },
      "DegreeStatsREST": {
        "type": "object",
        "properties": {
          "min": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64",
            "example": 0
          },
          "max": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64",
            "example": 420
          },
          "mean": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double",
            "example": 3.7
          },
          "p50": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64",
            "example": 2
          },
          "p90": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64",
            "example": 9
          },
          "p99": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64",
            "example": 40
          }
        },
        "description": "Degree distribution over the sampled vertices - strided-sample percentiles are\n    statistically sound."
      },
      "DelegateDiagnosticREST": {
        "type": "object",
        "properties": {
          "line": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "1-based start line in fragment coordinates",
            "format": "int32"
          },
          "column": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "1-based start column in fragment coordinates",
            "format": "int32"
          },
          "endLine": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "1-based end line in fragment coordinates",
            "format": "int32"
          },
          "endColumn": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "1-based end column (exclusive) in fragment coordinates",
            "format": "int32"
          },
          "id": {
            "type": [
              "null",
              "string"
            ],
            "description": "The diagnostic id, e.g. \"CS1061\" (or \"F8LIMIT\" for the size guard)"
          },
          "message": {
            "type": [
              "null",
              "string"
            ],
            "description": "The human-readable compiler message"
          },
          "severity": {
            "type": [
              "null",
              "string"
            ],
            "description": "\"error\", \"warning\" or \"info\""
          }
        },
        "description": "A single compiler diagnostic in fragment coordinates (feature web-ui, gap G-2)"
      },
      "DelegateValidationREST": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "True when the fragment compiles without errors (warnings do not block)"
          },
          "diagnostics": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/DelegateDiagnosticREST"
            },
            "description": "All non-hidden compiler diagnostics, in fragment coordinates"
          }
        },
        "description": "Result of compile-checking a delegate fragment (feature web-ui, gap G-2)"
      },
      "Direction": {
        "type": "integer"
      },
      "DoclingStatsREST": {
        "type": "object",
        "properties": {
          "configured": {
            "type": "boolean"
          },
          "reachable": {
            "type": "boolean",
            "description": "A cached, short-TTL health probe - reading status stays cheap."
          }
        },
        "description": "The sidecar's config/health state (spec FR-1)."
      },
      "DocumentBindingREST": {
        "type": "object",
        "properties": {
          "ready": {
            "type": "boolean",
            "description": "True when every required index exists and is the right shape: ingestion will\n    be accepted (subject to the other gates)."
          },
          "vector": {
            "description": "The vector index over the chunk embeddings (kNN side of fused search).",
            "$ref": "#/components/schemas/DocumentBindingRoleREST"
          },
          "fulltext": {
            "description": "The fulltext index over chunk text (lexical side of fused search).",
            "$ref": "#/components/schemas/DocumentBindingRoleREST"
          },
          "entity": {
            "description": "The dictionary index that deduplicates Entity vertices (one per (type,\n    normalized) per namespace).",
            "$ref": "#/components/schemas/DocumentBindingRoleREST"
          }
        },
        "description": "The semantic layer's index binding (feature semantic-layer FR-7): the state the Studio\n\"State\" panel reads to decide whether to offer \"create the required indexes\". The layer\nnever creates indices implicitly - ingestion answers 428 until bool DocumentBindingREST.Ready."
      },
      "DocumentBindingRoleREST": {
        "type": "object",
        "properties": {
          "role": {
            "type": [
              "null",
              "string"
            ],
            "description": "`vector`, `fulltext` or `entity`."
          },
          "indexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The configured index id this role binds."
          },
          "required": {
            "type": "boolean",
            "description": "Whether the current configuration needs this index (embeddings on for the\n    vector role, NLP on for the entity role, the fulltext role whenever it is enabled)."
          },
          "exists": {
            "type": "boolean",
            "description": "Whether an index with this id exists at all."
          },
          "ready": {
            "type": "boolean",
            "description": "Whether the index exists AND is the right shape for this role."
          },
          "detail": {
            "type": [
              "null",
              "string"
            ],
            "description": "A short note: the binding detail when ready, or the shape conflict when not."
          }
        },
        "description": "One index role in the binding: its id, whether the current configuration requires\n    it, whether it exists, whether it is usable (right shape), and a short human note."
      },
      "DocumentDetailREST": {
        "type": "object",
        "properties": {
          "summary": {
            "$ref": "#/components/schemas/DocumentSummaryREST"
          },
          "chunks": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/ChunkSummaryREST"
            }
          }
        },
        "description": "GET /document/{id}: the summary plus its chunks in document order."
      },
      "DocumentEntityListREST": {
        "type": "object",
        "properties": {
          "entities": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/DocumentEntityREST"
            },
            "description": "The entities, most-mentioned first (ties by text, then id)."
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The total number of entities matching the filter, before the page cap.",
            "format": "int32"
          }
        },
        "description": "The entity network the corpus mentions (feature semantic-layer FR-6): deduplicated\nEntity vertices ranked by how often chunks mention them. Backs the MCP `entities`\nop and the Studio \"Entities\" view. A page (bounded); int DocumentEntityListREST.Total is the full\ncount so the caller knows whether more exist."
      },
      "DocumentEntityREST": {
        "type": "object",
        "properties": {
          "id": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The Entity vertex id - usable directly as a /path or /subgraph seed.",
            "format": "int32"
          },
          "text": {
            "type": [
              "null",
              "string"
            ],
            "description": "The entity's surface form (the first one seen)."
          },
          "type": {
            "type": [
              "null",
              "string"
            ],
            "description": "The entity type: the label the NLP sidecar emitted, e.g. PERSON, ORG or GPE."
          },
          "mentionCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "How many chunks mention this entity (incoming `mentions` edges).",
            "format": "int32"
          }
        },
        "description": "One deduplicated entity: the vertex id (a valid graph seed), its surface text,\n    its type, and how many chunks mention it."
      },
      "DocumentGroupREST": {
        "type": "object",
        "properties": {
          "document": {
            "$ref": "#/components/schemas/DocumentSummaryREST"
          },
          "bestScore": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "float"
          },
          "chunks": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/ChunkHitREST"
            }
          }
        },
        "description": "Hits of one document (groupByDocument=true)."
      },
      "DocumentListREST": {
        "type": "object",
        "properties": {
          "documents": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/DocumentSummaryREST"
            }
          },
          "namespaceChunkCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Live chunks in this namespace.",
            "format": "int32"
          },
          "chunkCeiling": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Fallen8:Ingestion:MaxChunksPerNamespace.",
            "format": "int32"
          },
          "currentEmbeddingModel": {
            "type": [
              "null",
              "string"
            ],
            "description": "The active provider's model identity (null while the provider is off) -\n    the reference for bool DocumentSummaryREST.EmbeddingModelStale."
          }
        },
        "description": "GET /document: the namespace's documents plus the chunk budget (FR-14)."
      },
      "DocumentSearchResultREST": {
        "type": "object",
        "properties": {
          "modeUsed": {
            "type": [
              "null",
              "string"
            ],
            "example": "fused"
          },
          "hits": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/ChunkHitREST"
            },
            "description": "Flat hits, best first (absent when grouped)."
          },
          "documents": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/DocumentGroupREST"
            },
            "description": "Per-document groups (groupByDocument=true only)."
          }
        },
        "description": "The fused search answer. `modeUsed` states what actually ran: a fused\n    request degrades honestly when one side is unavailable."
      },
      "DocumentSearchSpecification": {
        "type": "object",
        "properties": {
          "queryText": {
            "type": [
              "null",
              "string"
            ],
            "description": "The query. Feeds the lexical side always, and the dense side when the\n    embedding provider is on and no queryVector is supplied.",
            "example": "the server that terminates tls for the shop"
          },
          "queryVector": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            },
            "description": "Optional client-side dense query vector (bring-your-own-vector)."
          },
          "mode": {
            "type": [
              "null",
              "string"
            ],
            "description": "`fused` (default), `dense` or `lexical`.",
            "example": "fused"
          },
          "k": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "Results to return (default 10, max 100).",
            "format": "int32",
            "example": 10
          },
          "window": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "Sibling chunks each side of a hit over `next` edges (default 0, max 5).",
            "format": "int32",
            "example": 1
          },
          "groupByDocument": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "Group hits per document: documents by best hit, chunks by document\n    position, duplicates collapsed (FR-11)."
          }
        },
        "description": "POST /document/search (spec unstructured-ingestion FR-11): fused chunk\n    retrieval over the bound vector index and the fulltext index."
      },
      "DocumentSummaryREST": {
        "type": "object",
        "properties": {
          "documentId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "name": {
            "type": [
              "null",
              "string"
            ]
          },
          "sourceFormat": {
            "type": [
              "null",
              "string"
            ],
            "example": "pdf"
          },
          "sourceUri": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "type": [
              "null",
              "string"
            ],
            "description": "`processing`, `indexed` or `failed`.",
            "example": "indexed"
          },
          "error": {
            "type": [
              "null",
              "string"
            ],
            "description": "The failure reason (failed documents only)."
          },
          "chunkCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pageCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "contentHash": {
            "type": [
              "null",
              "string"
            ],
            "description": "SHA-256 of the ingested bytes - the duplicate/re-ingestion currency."
          },
          "converter": {
            "type": [
              "null",
              "string"
            ],
            "description": "`docling-serve` or `none`."
          },
          "chunkerConfig": {
            "type": [
              "null",
              "string"
            ]
          },
          "embeddingModel": {
            "type": [
              "null",
              "string"
            ],
            "description": "The model identity the chunks were embedded with (absent when unembedded)."
          },
          "embeddingDimension": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "embedded": {
            "type": "boolean"
          },
          "embeddingModelStale": {
            "type": "boolean",
            "description": "True when the recorded embedding model differs from the active provider\n    (FR-16) - queries embed with the new model, these chunks carry the old one."
          }
        },
        "description": "One document as reported by the ingest/list/get surfaces (FR-2/FR-7)."
      },
      "DurabilityStatusREST": {
        "type": "object",
        "properties": {
          "walEnabled": {
            "type": "boolean",
            "description": "Whether a write-ahead log is configured. When false, a committed transaction is durable\nonly as far as the last checkpoint - the documented volatile/no-WAL posture, not a fault,\nwhich is why bool DurabilityStatusREST.Degraded stays false and this flag distinguishes the two.",
            "example": true
          },
          "degraded": {
            "type": "boolean",
            "description": "Whether write durability is DEGRADED right now: the sticky failure fence tripped, or an\nanchored log is awaiting its paired snapshot load. Transactions still commit in memory and\nstill report success, so this is the only signal that they are not reaching disk. A\nsuccessful save clears it.",
            "example": false
          },
          "recoveryRan": {
            "type": "boolean",
            "description": "Whether a log recovery has run in this engine's lifetime. When false the two\n    recovery fields below carry no information.",
            "example": false
          },
          "lastRecoveryTruncated": {
            "type": "boolean",
            "description": "Whether the last recovery stopped BEFORE the end of the log. Replay is fail-stop for\ncore-data entries, because continuing past a bad one would misapply every later entry\nagainst a diverged id space - so the graph is internally consistent but is a PREFIX of the\ncommitted history.",
            "example": false
          },
          "lastRecoveryReplayedEntries": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "How many log entries the last recovery replayed.",
            "format": "int32",
            "example": 0
          },
          "lastCheckpointDroppedIndices": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "How many indices the last checkpoint could not persist and dropped from its manifest.\nDropping is deliberate - one failing index must not cost the whole checkpoint - but the\nnext load then comes up with every element intact and those indices gone. Index content is\nderived state, so the repair is `POST /index/backfill/{indexId}`; this number is what\ntells a client it needs to.",
            "format": "int32",
            "example": 0
          }
        },
        "description": "The durability and recovery-integrity block on `GET /status` (feature\nplatform-integrity-audit W5).\n\nEvery fact here was already computed by the engine and reachable nowhere: the\ndegraded-log state existed only as an OpenTelemetry gauge, so it existed only if the operator\nhad wired a collector, and a truncated recovery logged one error and became an activity tag.\nA client could therefore write into a degraded log, receive success for every write, and lose\nall of them on the next kill.\n\nWho needs it and why. Any writer that DELETES state because \"nothing asserts it\nany more\" is reading that conclusion out of graph content. If the content is a\npost-truncation prefix, or if an index it reasoned over was dropped from the last checkpoint,\nthe conclusion is wrong and the deletion is the one mutation that re-syncing cannot undo.\nSuch a client checks this block first and DEFERS the deletion when anything here is set:\ndeferring is recoverable, deleting wrongly is not."
      },
      "Edge": {
        "required": [
          "targetVertex",
          "sourceVertex",
          "edgePropertyId",
          "id",
          "creationDate",
          "modificationDate"
        ],
        "type": "object",
        "properties": {
          "targetVertex": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The identifier of the vertex where this edge ends",
            "format": "int32",
            "example": 2
          },
          "sourceVertex": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The identifier of the vertex where this edge starts",
            "format": "int32",
            "example": 1
          },
          "edgePropertyId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The edge's type: the adjacency group this edge occupies on its endpoints, set at\ncreation time. Distinct from the optional `label` and not one of the edge's\nkey/value properties (see the graph-model docs page).",
            "example": "knows"
          },
          "id": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The unique identifier of the graph element",
            "format": "int32",
            "default": 123,
            "example": 123
          },
          "creationDate": {
            "type": "string",
            "description": "The date and time when the element was created",
            "format": "date-time",
            "example": "2025-04-22T10:00:00Z"
          },
          "modificationDate": {
            "type": "string",
            "description": "The date and time when the element was last modified",
            "format": "date-time",
            "example": "2025-04-22T10:00:00Z"
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "The type label of the graph element used for categorization",
            "default": "person",
            "example": "person"
          },
          "properties": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PropertySpecification"
            },
            "description": "The collection of properties (key-value pairs) associated with the graph element"
          }
        },
        "description": "Represents an edge (relationship) between two vertices in the graph",
        "example": {
          "id": 10,
          "creationDate": "2025-04-22T10:00:00Z",
          "modificationDate": "2025-04-22T10:00:00Z",
          "label": "friendship",
          "properties": [
            {
              "propertyId": "since",
              "fullQualifiedTypeName": "System.DateTime",
              "propertyValue": "2024-01-15T00:00:00.0000000"
            },
            {
              "propertyId": "strength",
              "fullQualifiedTypeName": "System.Single",
              "propertyValue": "0.85"
            }
          ],
          "sourceVertex": 1,
          "targetVertex": 2,
          "edgePropertyId": "knows"
        }
      },
      "EdgeSpecification": {
        "required": [
          "creationDate",
          "sourceVertex",
          "targetVertex",
          "edgePropertyId"
        ],
        "type": "object",
        "properties": {
          "creationDate": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The creation date of the edge as a Unix timestamp",
            "format": "uint32",
            "default": 0,
            "example": 1713862800
          },
          "sourceVertex": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The identifier of the source vertex where the edge starts",
            "format": "int32",
            "default": 1,
            "example": 1
          },
          "targetVertex": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The identifier of the target vertex where the edge ends",
            "format": "int32",
            "default": 2,
            "example": 2
          },
          "edgePropertyId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The edge's type: the adjacency group the edge occupies on both endpoints, which the\ntraversal surface keys on (see the graph-model docs page).",
            "default": "knows",
            "example": "knows"
          },
          "properties": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PropertySpecification"
            },
            "description": "The properties of the edge as key-value pairs"
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional category tag, orthogonal to the edge's type (edgePropertyId) - not a second\ncopy of it. The same field every vertex has.",
            "default": "friendship",
            "example": "friendship"
          }
        },
        "description": "Specification for creating a new edge between two vertices in the graph",
        "example": {
          "sourceVertex": 1,
          "targetVertex": 2,
          "edgePropertyId": "knows",
          "label": "friendship",
          "creationDate": 1713862800,
          "properties": [
            {
              "propertyId": "since",
              "propertyValue": "2024-01-15T00:00:00",
              "fullQualifiedTypeName": "System.DateTime"
            },
            {
              "propertyId": "strength",
              "propertyValue": 0.85,
              "fullQualifiedTypeName": "System.Double"
            }
          ]
        }
      },
      "ElementEmbeddingREST": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The embedding name.",
            "example": "default"
          },
          "vector": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            },
            "description": "The stored vector."
          },
          "model": {
            "type": [
              "null",
              "string"
            ],
            "description": "The model-identity stamp written by the embedding provider, or null for a\n    bring-your-own-vector embedding.",
            "example": "bge-micro-v2#384#Cosine"
          }
        },
        "description": "A stored element embedding (feature element-embeddings)."
      },
      "EmbeddingProviderStatsREST": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Whether the capability flag (Fallen8:Embedding:Enabled) is on.",
            "example": false
          },
          "backend": {
            "type": [
              "null",
              "string"
            ],
            "description": "The configured backend: Onnx, LLamaSharp or Ollama.",
            "example": "Onnx"
          },
          "modelName": {
            "type": [
              "null",
              "string"
            ],
            "description": "The declared model name.",
            "example": "bge-micro-v2"
          },
          "modelVersion": {
            "type": [
              "null",
              "string"
            ],
            "description": "The declared model version (empty when unspecified)."
          },
          "dimension": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The declared output dimension.",
            "format": "int32",
            "example": 384
          },
          "intendedMetric": {
            "type": [
              "null",
              "string"
            ],
            "description": "The metric the embeddings are intended for.",
            "example": "Cosine"
          },
          "loaded": {
            "type": "boolean",
            "description": "Whether the backend has actually been created (lazy load happened on first use).\n    For an Ollama backend this is client construction, not model residency - see\n    bool? EmbeddingProviderStatsREST.Resident.",
            "example": false
          },
          "resident": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "Whether the model is currently loaded in the backend (Ollama /api/ps): true =\n    warm, false = not loaded right now (loads on first use), null = undeterminable or not an\n    Ollama backend. Only set on GET /config (a point-in-time probe), never on /status or\n    /statistics."
          },
          "gpu": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "Best-effort GPU residency (Ollama VRAM): true/false when reported, null when\n    undeterminable or not probed. Only set on GET /config."
          }
        },
        "description": "The active embedding provider and its declared model identity (feature\n    embedding-provider). Cheap config/state reads only - surfacing it never loads a model.\n    Carried by both GET /status (the cheap discovery surface) and GET /statistics (the\n    full snapshot)."
      },
      "EmbeddingSearchSpecification": {
        "required": [
          "indexId",
          "text",
          "k"
        ],
        "type": "object",
        "properties": {
          "indexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The vector index to query.",
            "example": "embeddings"
          },
          "text": {
            "type": [
              "null",
              "string"
            ],
            "description": "The query text (embedded once, with the configured query prefix).",
            "example": "red bicycles"
          },
          "k": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "How many nearest neighbours to return (1..1024).",
            "format": "int32",
            "example": 10
          },
          "kind": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional element-kind constraint: vertex, edge, or any (default).",
            "example": "vertex"
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional exact (case-sensitive) label constraint.",
            "example": "person"
          }
        },
        "description": "Semantic search: embed a query text and run kNN against a vector index\n    (feature embedding-provider).",
        "example": {
          "indexId": "embeddings",
          "text": "red bicycles",
          "k": 10,
          "kind": "vertex"
        }
      },
      "EmbeddingVectorsREST": {
        "type": "object",
        "properties": {
          "model": {
            "type": [
              "null",
              "string"
            ],
            "description": "The provider's model-identity stamp.",
            "example": "bge-micro-v2#384#Cosine"
          },
          "dimension": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The vector dimension.",
            "format": "int32",
            "example": 384
          },
          "vectors": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "array",
              "items": {
                "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
                "type": [
                  "number",
                  "string"
                ],
                "format": "float"
              }
            },
            "description": "One vector per input text, in order."
          }
        },
        "description": "Raw embedding vectors plus the identity they came from."
      },
      "EmbeddingWriteSpecification": {
        "required": [
          "vector"
        ],
        "type": "object",
        "properties": {
          "vector": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            },
            "description": "The embedding vector; finite components, dimension within [1, 4096]."
          }
        },
        "description": "Sets (replace semantics) a named element embedding (feature element-embeddings).",
        "example": {
          "vector": [
            0.12,
            -0.5,
            0.33
          ]
        }
      },
      "EmbedElementItem": {
        "required": [
          "graphElementId",
          "text"
        ],
        "type": "object",
        "properties": {
          "graphElementId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The target graph element id.",
            "format": "int32",
            "example": 42
          },
          "text": {
            "type": [
              "null",
              "string"
            ],
            "description": "The text to embed."
          }
        },
        "description": "One item of a batch embed (feature embedding-provider)."
      },
      "EmbedElementSpecification": {
        "required": [
          "graphElementId",
          "text"
        ],
        "type": "object",
        "properties": {
          "graphElementId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The target graph element id.",
            "format": "int32",
            "example": 42
          },
          "text": {
            "type": [
              "null",
              "string"
            ],
            "description": "The text to embed.",
            "example": "a red bicycle"
          },
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The embedding name (default \"default\").",
            "example": "default"
          }
        },
        "description": "Embed a text and store it as the element's named embedding (feature\n    embedding-provider).",
        "example": {
          "graphElementId": 42,
          "text": "a red bicycle",
          "name": "default"
        }
      },
      "EmbedElementsSpecification": {
        "required": [
          "items"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The embedding name for the whole batch (default \"default\").",
            "example": "default"
          },
          "items": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/EmbedElementItem"
            },
            "description": "The batch (bounded by Fallen8:Embedding:MaxBatchSize)."
          }
        },
        "description": "Embed a batch of texts onto elements in one provider batch and one\n    transaction (feature embedding-provider) - the bulk-ingestion path.",
        "example": {
          "name": "default",
          "items": [
            {
              "graphElementId": 1,
              "text": "..."
            }
          ]
        }
      },
      "EmbedTextSpecification": {
        "required": [
          "texts"
        ],
        "type": "object",
        "properties": {
          "texts": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "The texts to embed (bounded by Fallen8:Embedding:MaxBatchSize)."
          }
        },
        "description": "Embed raw texts and return the vectors (feature embedding-provider) - for\n    clients that drive the raw vector surfaces themselves.",
        "example": {
          "texts": [
            "a red bicycle",
            "a blue car"
          ]
        }
      },
      "FulltextIndexScanSpecification": {
        "required": [
          "indexId",
          "requestString"
        ],
        "type": "object",
        "properties": {
          "indexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The identifier of the fulltext index to search",
            "default": "documentIndex",
            "example": "documentIndex"
          },
          "requestString": {
            "type": [
              "null",
              "string"
            ],
            "description": "The search query text to look for in the indexed content",
            "example": "graph database nosql"
          }
        },
        "description": "Specification for performing fulltext search queries on indexed content",
        "example": {
          "indexId": "documentIndex",
          "requestString": "graph database nosql"
        }
      },
      "FulltextSearchResultElementREST": {
        "required": [
          "graphElementId",
          "highlights",
          "score"
        ],
        "type": "object",
        "properties": {
          "graphElementId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The identifier of the graph element (vertex or edge) that matched the search query",
            "format": "int32",
            "example": 123
          },
          "highlights": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "Collection of highlighted text fragments showing the context of search term matches",
            "example": [
              "This is a &lt;em&gt;graph&lt;/em&gt; &lt;em&gt;database&lt;/em&gt; document"
            ]
          },
          "score": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "The relevance score of this result, indicating how well it matches the search query",
            "format": "double",
            "example": 0.87
          }
        },
        "description": "Represents a single match in fulltext search results with relevance scoring and highlighting",
        "example": {
          "graphElementId": 123,
          "score": 0.87,
          "highlights": [
            "This is a &lt;em&gt;graph&lt;/em&gt; &lt;em&gt;database&lt;/em&gt; document",
            "Another fragment with &lt;em&gt;NoSQL&lt;/em&gt; mention"
          ]
        }
      },
      "FulltextSearchResultREST": {
        "required": [
          "maximumScore",
          "elements"
        ],
        "type": "object",
        "properties": {
          "maximumScore": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "The highest relevance score among all matching elements",
            "format": "double",
            "example": 0.87
          },
          "elements": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/FulltextSearchResultElementREST"
            },
            "description": "Collection of matching elements with their relevance scores and highlighted content"
          }
        },
        "description": "Result container for fulltext search operations with scoring and highlighting",
        "example": {
          "maximumScore": 0.87,
          "elements": [
            {
              "graphElementId": 123,
              "score": 0.87,
              "highlight": "This is a <em>graph</em> <em>database</em> document about <em>NoSQL</em>"
            },
            {
              "graphElementId": 456,
              "score": 0.65,
              "highlight": "Introduction to <em>graph</em> theory and <em>database</em> systems"
            }
          ]
        }
      },
      "FunctionPluginRegistration": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The unique name to register under (per namespace). Must equal the type's `PluginName`."
          },
          "description": {
            "type": [
              "null",
              "string"
            ],
            "description": "An optional human-readable description."
          },
          "sourceCode": {
            "type": [
              "null",
              "string"
            ],
            "description": "The whole-type C# source implementing `IGraphFunction`."
          }
        },
        "description": "Request body for `POST /plugins/function` (feature plugin-registration): register a\nstored graph function (an `IGraphFunction`) from whole-type C# source. The function\ncategory has a single contract, so no discriminator is needed.",
        "example": {
          "name": "NeighboursOfLabel",
          "description": "all vertices of a label and their edges",
          "sourceCode": "using ...; public sealed class NeighboursOfLabel : IGraphFunction { ... }"
        }
      },
      "Graph": {
        "type": "object",
        "properties": {
          "edges": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/Edge"
            },
            "description": "Collection of all edges in the graph"
          },
          "vertices": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/Vertex"
            },
            "description": "Collection of all vertices in the graph"
          }
        },
        "description": "Represents an entire graph structure with vertices and edges",
        "example": {
          "vertices": [
            {
              "id": 1,
              "label": "person",
              "properties": {
                "name": "John Doe",
                "age": 30
              }
            },
            {
              "id": 2,
              "label": "person",
              "properties": {
                "name": "Jane Smith",
                "age": 28
              }
            }
          ],
          "edges": [
            {
              "id": 10,
              "label": "friendship",
              "sourceVertex": 1,
              "targetVertex": 2,
              "edgePropertyId": "knows",
              "properties": {
                "since": "2024-01-15T00:00:00"
              }
            }
          ]
        }
      },
      "GraphElementBatchREST": {
        "type": "object",
        "properties": {
          "elements": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/GraphElementProjectionREST"
            },
            "description": "The elements that exist, in the order the requested ids were given (duplicates in\n    the request collapse to one entry)."
          },
          "notFound": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            },
            "description": "The requested ids that resolve to no live element - removed, never created, or out\n    of range. Stated rather than implied."
          }
        },
        "description": "Result of `POST /graphelements/get` (feature platform-integrity-audit W6): the elements\nthat exist, plus the ids that do not.\n\nWhy the route exists. Every scan and every batch write returns IDS ONLY, and the\nonly many-element reads were a whole-namespace dump and a whole-namespace export. So a caller\nthat had resolved several hundred ids and needed their current property values - which is what\n\"write only if something actually changed\" requires - had one sequential request per element,\nor a full graph dump per poll. That is the read-side mirror of the batch write path.\n\nList&lt;int&gt; GraphElementBatchREST.NotFound is explicit rather than left to the caller to infer from a\nmissing entry, because \"this id is gone\" and \"this id has no properties\" are different\nconclusions and a reconciling caller acts differently on each."
      },
      "GraphElementProjectionREST": {
        "required": [
          "id",
          "creationDate",
          "modificationDate"
        ],
        "type": "object",
        "properties": {
          "kind": {
            "type": [
              "null",
              "string"
            ],
            "description": "`vertex` or `edge`. The singular getters are addressed per kind, so a batch read\nthat accepts mixed ids has to say which each one turned out to be.",
            "example": "vertex"
          },
          "id": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The unique identifier of the graph element",
            "format": "int32",
            "default": 123,
            "example": 123
          },
          "creationDate": {
            "type": "string",
            "description": "The date and time when the element was created",
            "format": "date-time",
            "example": "2025-04-22T10:00:00Z"
          },
          "modificationDate": {
            "type": "string",
            "description": "The date and time when the element was last modified",
            "format": "date-time",
            "example": "2025-04-22T10:00:00Z"
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "The type label of the graph element used for categorization",
            "default": "person",
            "example": "person"
          },
          "properties": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PropertySpecification"
            },
            "description": "The collection of properties (key-value pairs) associated with the graph element"
          }
        },
        "description": "One element in a `POST /graphelements/get` result (feature platform-integrity-audit W6):\nits identity, label, stamps and properties - and deliberately NOT its adjacency.\n\nIt derives from AGraphElement so the property projection goes through the\none egress home, which is what makes every value here round-trip back through a write\nunchanged. Adjacency is omitted on purpose: this route exists so a caller can compare the\nvalues it intends to write against the values already stored, and shipping every edge id of\nevery element in a several-hundred-element batch would dominate the payload while answering a\nquestion nobody asked. A caller that needs adjacency asks for one element through\nGET /vertex/{id}, which already returns it."
      },
      "GraphFunctionInvocation": {
        "type": "object",
        "properties": {
          "parameters": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "type": "string"
            },
            "description": "The parameters passed to the function (may be null/empty)."
          }
        },
        "description": "Request body for `POST /plugins/function/{name}/invoke` (feature plugin-registration):\nthe call-time parameter bag. Values are STRINGS in v1 (a function parses what it needs);\nricher typed parameters are a later refinement."
      },
      "GraphFunctionResultREST": {
        "type": "object",
        "properties": {
          "vertices": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/Vertex"
            },
            "description": "The selected vertices."
          },
          "edges": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/Edge"
            },
            "description": "The selected edges."
          }
        },
        "description": "The result of a graph-function invocation (feature plugin-registration): the selected\nvertices and edges, projected with the SAME DTOs as `GET /vertex/{id}` /\n`GET /edge/{id}` (a view of existing elements at call time)."
      },
      "GraphGenerationResultREST": {
        "type": "object",
        "properties": {
          "namespace": {
            "type": [
              "null",
              "string"
            ],
            "description": "The namespace the vertices and edges were written into.",
            "example": "flights"
          },
          "verticesCreated": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The number of vertices created by this call.",
            "format": "int32",
            "example": 200
          },
          "edgesCreated": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The number of edges created by this call. Lower than\n`verticesCreated * edgeCount` whenever the requested out-degree exceeds the number\nof distinct targets available (targets are drawn distinct), and under\n`preferential` by construction, because the earliest vertices have fewer earlier\nvertices to attach to.",
            "format": "int64",
            "example": 1000
          },
          "distribution": {
            "type": [
              "null",
              "string"
            ],
            "description": "The edge-target distribution that was used: \"uniform\" or \"preferential\".",
            "example": "uniform"
          },
          "elapsedMilliseconds": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Wall-clock milliseconds spent creating and committing the graph.",
            "format": "double",
            "example": 412.8
          },
          "vertexCountAfter": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The namespace's total vertex count once generation finished.",
            "format": "int32",
            "example": 200
          },
          "edgeCountAfter": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The namespace's total edge count once generation finished.",
            "format": "int32",
            "example": 1000
          }
        },
        "description": "Structured result of a benchmark-graph generation (GET /ns/{ns}/generate)."
      },
      "GraphStatisticsREST": {
        "type": "object",
        "properties": {
          "vertexCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32",
            "example": 2500000
          },
          "edgeCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32",
            "example": 10000000
          },
          "vertexLabels": {
            "description": "Vertex label cardinalities (top-N + distinct).",
            "$ref": "#/components/schemas/CardinalityStatsREST"
          },
          "edgeLabels": {
            "description": "Edge label cardinalities (top-N + distinct).",
            "$ref": "#/components/schemas/CardinalityStatsREST"
          },
          "inDegree": {
            "description": "In-degree distribution over the sampled vertices.",
            "$ref": "#/components/schemas/DegreeStatsREST"
          },
          "outDegree": {
            "description": "Out-degree distribution over the sampled vertices.",
            "$ref": "#/components/schemas/DegreeStatsREST"
          },
          "totalDegree": {
            "description": "Total (in+out) degree distribution over the sampled vertices.",
            "$ref": "#/components/schemas/DegreeStatsREST"
          },
          "propertyKeys": {
            "description": "Property-key cardinalities by element count (top-N + distinct) - the\n    heaviest stat (O(total properties) over the sampled elements).",
            "$ref": "#/components/schemas/CardinalityStatsREST"
          },
          "indices": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/IndexStatsREST"
            },
            "description": "The registered indices."
          },
          "memory": {
            "description": "Free process/GC memory reads (never a forced GC).",
            "$ref": "#/components/schemas/MemoryStatsREST"
          },
          "computedInMs": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Wall-clock cost of computing this snapshot.",
            "format": "double",
            "example": 184.2
          },
          "sampled": {
            "type": "boolean",
            "description": "True when V+E exceeded the element budget and the pass sampled with a\n    uniform stride; per-name counts are then within-sample.",
            "example": false
          },
          "sampleStride": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The uniform stride used (1 when exact).",
            "format": "int32",
            "example": 1
          },
          "embedding": {
            "description": "The embedding provider state (feature embedding-provider). Reading this\n    NEVER triggers the lazy model load.",
            "$ref": "#/components/schemas/EmbeddingProviderStatsREST"
          },
          "ingestion": {
            "description": "The unstructured-ingestion state (feature unstructured-ingestion): the\n    same block as /status, so either discovery surface answers capability questions.",
            "$ref": "#/components/schemas/IngestionStatsREST"
          },
          "nlp": {
            "description": "The semantic-layer NLP enrichment state (feature semantic-layer): same\n    block as /status.",
            "$ref": "#/components/schemas/NlpStatsREST"
          }
        },
        "description": "The graph-shape snapshot behind GET /statistics (feature observability). An ADVISORY,\nlock-free snapshot - not transactionally consistent - computed on demand under an\nelement budget: exact when V+E fits the budget, uniformly strided (and flagged) above it."
      },
      "IFormFile": {
        "type": "string",
        "format": "binary"
      },
      "IndexAddToSpecification": {
        "required": [
          "graphElementId",
          "key"
        ],
        "type": "object",
        "properties": {
          "graphElementId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The identifier of the graph element to index",
            "format": "int32",
            "default": 123,
            "example": 123
          },
          "key": {
            "description": "The key under which to index the graph element",
            "$ref": "#/components/schemas/PropertySpecification"
          }
        },
        "description": "Specification for adding or updating a graph element in an index",
        "example": {
          "graphElementId": 123,
          "key": {
            "propertyValue": "John Doe",
            "fullQualifiedTypeName": "System.String"
          }
        }
      },
      "IndexBackfillSpecification": {
        "required": [
          "propertyId"
        ],
        "type": "object",
        "properties": {
          "propertyId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The property key whose VALUE becomes the index key. Elements not carrying it are skipped.",
            "default": "name",
            "example": "name"
          },
          "replace": {
            "type": "boolean",
            "description": "`false` (default) REPAIRS: add-only and idempotent, so it is safe on every start and\nnothing is briefly missing, but keys the elements no longer justify are left alone.\n`true` REBUILDS exactly: the index is wiped first, so stale keys go, at the cost of a\nwindow in which a concurrent scan sees an empty index.",
            "default": false,
            "example": false
          },
          "prefix": {
            "type": "boolean",
            "description": "`false` (default) selects ONE exact property key. `true` means\n`propertyId` is a KEY PREFIX and EVERY property whose key starts with it is indexed\nby its value, so one element can contribute several entries. Prefix mode exists because a\nset of values is spread across dense ordinal keys (`$identity:0`,\n`$identity:1`, ...): the property surface accepts scalars and no array, so a set is\nnot expressible under one key, and an exact-key repair then restores only the first value\nof each element - leaving it findable by one and invisible by the rest.",
            "default": false,
            "example": false
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional label restriction, for when the property only occurs on one kind of element.\nOmit to scan every live element.",
            "example": "person"
          }
        },
        "description": "Body of `POST /index/backfill/{indexId}` (feature platform-integrity-audit W4): which\nproperty supplies the index keys, and whether to rebuild exactly or merely repair.",
        "example": {
          "propertyId": "name",
          "replace": false
        }
      },
      "IndexDescriptionREST": {
        "type": "object",
        "properties": {
          "indexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The index id used by the scan and index endpoints.",
            "example": "nameIndex"
          },
          "pluginType": {
            "type": [
              "null",
              "string"
            ],
            "description": "The index plugin type the index was created with.",
            "example": "DictionaryIndex"
          },
          "embeddingName": {
            "type": [
              "null",
              "string"
            ],
            "description": "For a vector index BOUND to an element embedding (feature element-embeddings), the\nembedding name it derives its projection from; `null` for an unbound (raw)\nvector index and for every other family. Lets a client show that the index is a\nself-maintained projection and that explicit adds are rejected. Not captured in\nsave-game KPIs (only the live `/status` inventory populates it).",
            "example": "default"
          },
          "model": {
            "type": [
              "null",
              "string"
            ],
            "description": "For a vector index, the declared model-identity string it expects its vectors to\ncome from (feature embedding-provider), or `null`. Diagnostic only.",
            "example": "bge-micro-v2#384#Cosine"
          },
          "capabilities": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "The query families this index answers (feature index-workspace). `equality`\ncomes straight from the index's own `IIndex.SupportsPointEqualityLookup`\ndeclaration (the engine-owned single home for \"can this index be looked up by an\nexact key\" - the semantic layer's entity/link gates read the same flag, so this\ninventory and those gates can never disagree); the remaining tags come from the\nfamily interface the index implements: `IVectorIndex` → `vector`;\n`ISpatialIndex` → `spatial`; `IFulltextIndex` → `fulltext`;\n`IRangeIndex` → `range`. The built-in vector and spatial indexes declare\nNO `equality` because their keys (float[], geometry) cannot travel as the scan\nendpoints' typed literal. Like string IndexDescriptionREST.EmbeddingName, only the live\n`/status` inventory populates it; save-game KPIs leave it `null`.",
            "example": [
              "equality",
              "range"
            ]
          },
          "keys": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "`CountOfKeys()` at snapshot time — live `/status` inventory only,\n`null` in save-game KPIs and when the index reports a negative\n\"count not supported\" sentinel (e.g. the spatial R-Tree).",
            "format": "int32",
            "example": 1000
          },
          "values": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "`CountOfValues()` at snapshot time (O(entries) on bucket indexes — fine for\nthe status poll at self-hosted scale) — live `/status` inventory only,\n`null` in save-game KPIs and for a negative sentinel (see int? IndexDescriptionREST.Keys).",
            "format": "int32",
            "example": 1200
          }
        },
        "description": "A registered index: its id and the index plugin type. Appears on\nStatusREST (live inventory) and in save-game KPIs (inventory at save time)."
      },
      "IndexRebuildREST": {
        "type": "object",
        "properties": {
          "indexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The index that was repopulated."
          },
          "propertyId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The property whose values became the keys."
          },
          "replaced": {
            "type": "boolean",
            "description": "Whether the index was wiped first (an exact rebuild rather than a repair)."
          },
          "scannedElements": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Live elements scanned.",
            "format": "int32"
          },
          "indexedElements": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Live elements that carried the property and were indexed.",
            "format": "int32"
          },
          "skippedUnindexableValues": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Elements carrying the property whose value cannot be an index key (not comparable, for\nexample a vector written through the raw property surface). Skipped, and counted here so the\nskip is not silent.",
            "format": "int32"
          }
        },
        "description": "Outcome of an index backfill. Reports the numbers rather than a bare boolean so a caller can\ntell a no-op from real work, and can spot having named the wrong property (scanned many,\nindexed none)."
      },
      "IndexScanSpecification": {
        "required": [
          "indexId",
          "operator",
          "literal",
          "resultType"
        ],
        "type": "object",
        "properties": {
          "indexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The identifier of the index to scan",
            "default": "nameIndex",
            "example": "nameIndex"
          },
          "operator": {
            "description": "The binary operator to use for comparing property values, sent as its integer code:\n0 Equals, 1 Greater, 2 GreaterOrEquals, 3 Lower, 4 LowerOrEquals, 5 NotEquals.\nA member name is not accepted: unlike resultType, this enum carries no string-enum\nconverter, so the code is the wire form (this summary is the mapping's one home,\nsince the generated schema shows only \"integer\").",
            "examples": [
              0
            ],
            "$ref": "#/components/schemas/BinaryOperator"
          },
          "literal": {
            "description": "The literal value to compare against",
            "$ref": "#/components/schemas/LiteralSpecification"
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional restrictor: only elements with exactly this label match",
            "example": "person"
          },
          "resultType": {
            "description": "Specifies which types of graph elements to include in the results",
            "default": "Vertices",
            "examples": [
              "Vertices"
            ],
            "$ref": "#/components/schemas/ResultTypeSpecification"
          }
        },
        "description": "Specification for scanning an index for elements with specific property values",
        "example": {
          "indexId": "nameIndex",
          "operator": 0,
          "literal": {
            "value": "John Doe",
            "fullQualifiedTypeName": "System.String"
          },
          "resultType": "Vertices"
        }
      },
      "IndexStatsREST": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The index name.",
            "example": "myIndex"
          },
          "type": {
            "type": [
              "null",
              "string"
            ],
            "description": "The plugin type name.",
            "example": "DictionaryIndex"
          },
          "keys": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "`CountOfKeys()`, or `null` when the index reports a negative\n    \"count not supported\" sentinel - the sentinel contract is documented on\n    int? IndexDescriptionREST.Keys, whose inventory answers identically.",
            "format": "int32",
            "example": 1000
          },
          "values": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "`CountOfValues()`, or `null` for a negative sentinel (see\n    int? IndexStatsREST.Keys).",
            "format": "int32",
            "example": 1200
          }
        },
        "description": "One registered index."
      },
      "IngestionLimitsREST": {
        "type": "object",
        "properties": {
          "maxUploadBytes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "maxPages": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "maxChunksPerDocument": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "maxChunksPerNamespace": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "maxLinksPerChunk": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          }
        },
        "description": "The enforced ingestion bounds (spec FR-1/FR-14)."
      },
      "IngestionStatsREST": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "textFormats": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "Formats that ingest without the sidecar."
          },
          "binaryFormats": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "Formats that need the docling sidecar."
          },
          "docling": {
            "$ref": "#/components/schemas/DoclingStatsREST"
          },
          "limits": {
            "$ref": "#/components/schemas/IngestionLimitsREST"
          },
          "embeddingName": {
            "type": [
              "null",
              "string"
            ],
            "description": "The element-embedding name chunk vectors are written under."
          },
          "vectorIndexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The ensured bound vector index id (null when EnsureVectorIndex is off)."
          },
          "fulltextIndexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The ensured fulltext index id (null when EnsureFulltextIndex is off -\n    fused search then degrades to dense-only)."
          }
        },
        "description": "The unstructured-ingestion capability state on the discovery surfaces (spec FR-1,\n/status and /statistics): the flag, the formats each path accepts, the sidecar\nprobe (cached short-TTL, never a conversion), the enforced limits and the ensured\nindex ids. F8 Studio gates its upload UI on this block."
      },
      "IngestTextSpecification": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The document name.",
            "example": "edge-server-notes"
          },
          "text": {
            "type": [
              "null",
              "string"
            ],
            "description": "The content."
          },
          "format": {
            "type": [
              "null",
              "string"
            ],
            "description": "`markdown` (default, heading-aware chunking) or `plain`.",
            "example": "markdown"
          },
          "embed": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "Embed the chunks (default true). Requires the embedding provider; pass\n    false to ingest text-only."
          },
          "properties": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "type": "string"
            },
            "description": "User tag properties applied to the document and every chunk. Keys of the\n    document graph model are reserved (400)."
          },
          "sourceUri": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional source pointer stored on the document vertex.",
            "example": "https://wiki.example/edge-servers"
          },
          "replaceDocumentId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "Replace this document (FR-15): the new content is ingested fully first,\n    the old document and its chunks are removed on success.",
            "format": "int32"
          },
          "link": {
            "description": "Opt-in structural linking (FR-13).",
            "$ref": "#/components/schemas/LinkSpecificationREST"
          }
        },
        "description": "Raw-text ingestion (spec unstructured-ingestion FR-3) - works without the\n    docling sidecar."
      },
      "JsonElement": { },
      "LinkSpecificationREST": {
        "type": "object",
        "properties": {
          "indexIds": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "The index ids to match extracted identifiers against. Each must be\n    equality-capable (dictionary, range, single-value or fulltext); a vector or spatial\n    index is rejected with 400."
          },
          "maxLinksPerChunk": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "Optional per-request cap; never above Fallen8:Ingestion:MaxLinksPerChunk.",
            "format": "int32",
            "example": 8
          }
        },
        "description": "Opt-in structural linking (spec unstructured-ingestion FR-13): exact-match\n    identifier lookups against an explicit allowlist of equality-capable indices."
      },
      "LiteralSpecification": {
        "required": [
          "value"
        ],
        "type": "object",
        "properties": {
          "value": {
            "type": [
              "null",
              "string"
            ],
            "description": "The string representation of the value to use in comparisons",
            "example": "John Doe"
          },
          "fullQualifiedTypeName": {
            "type": [
              "null",
              "string"
            ],
            "description": "The fully qualified .NET type name of the value",
            "default": "System.String",
            "example": "System.String"
          }
        },
        "description": "Specification for literal values used in graph queries and scans",
        "example": {
          "value": "John Doe",
          "fullQualifiedTypeName": "System.String"
        }
      },
      "LoadSpecification": {
        "required": [
          "startServices",
          "saveGameLocation"
        ],
        "type": "object",
        "properties": {
          "startServices": {
            "type": "boolean",
            "description": "Indicates whether services should be automatically started after loading",
            "default": true,
            "example": true
          },
          "saveGameLocation": {
            "type": [
              "null",
              "string"
            ],
            "description": "The file path location of the Fallen-8 database save file",
            "default": "C:/Fallen8/database.f8s",
            "example": "C:/Fallen8/database.f8s"
          }
        },
        "description": "Specification for loading a Fallen-8 database from disk",
        "example": {
          "startServices": true,
          "saveGameLocation": "C:/Fallen8/database.f8s"
        }
      },
      "MemoryStatsREST": {
        "type": "object",
        "properties": {
          "processWorkingSetBytes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Process working set.",
            "format": "int64",
            "example": 1073741824
          },
          "gcHeapBytes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "GC.GetTotalMemory(false) - allocated managed memory, no forced collection.",
            "format": "int64",
            "example": 805306368
          },
          "gcLastHeapSizeBytes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "GCMemoryInfo.HeapSizeBytes from the last GC.",
            "format": "int64",
            "example": 805306368
          },
          "gcFragmentedBytes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "GCMemoryInfo.FragmentedBytes from the last GC.",
            "format": "int64",
            "example": 52428800
          }
        },
        "description": "Process/GC memory numbers that are FREE to read - this endpoint never forces a\n    GC (deliberate contrast with the benchmark-only GC.GetTotalMemory(true))."
      },
      "NamedCountREST": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The label / property key.",
            "example": "person"
          },
          "count": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "How many sampled elements carry it.",
            "format": "int64",
            "example": 1200
          }
        },
        "description": "One label (or property key) with its element count. When the response is\n    sampled, counts are AS COUNTED IN THE SAMPLE (multiply by sampleStride to extrapolate)."
      },
      "NamespaceActivationREST": {
        "type": "object",
        "properties": {
          "namespace": {
            "description": "The namespace as it stands after the call (state `ready`, real counts).",
            "$ref": "#/components/schemas/NamespaceREST"
          },
          "activated": {
            "type": "boolean",
            "description": "Whether THIS call loaded the namespace. `false` means it was already loaded in this\nprocess and nothing was restored - a success, since activation is idempotent, and the\nonly way a caller can tell the two apart."
          },
          "detail": {
            "type": [
              "null",
              "string"
            ],
            "description": "What happened, in the operator's words: which save game was restored (and whether its\nwrite-ahead-log tail was replayed on top), or that the namespace was already loaded, or\nthat no registered save game contains it."
          }
        },
        "description": "The result of one `POST /ns/{name}/activate` (feature namespace-startup-load §4.8).\nIts own type rather than a bare NamespaceREST, because the answer is a report\nabout an OPERATION - \"did this call load it, and what came back\" - and a namespace entry has\nno place to say that. Putting bool NamespaceActivationREST.Activated on NamespaceREST instead\nwould ship a meaningless field on every entry of `GET /ns`."
      },
      "NamespaceREST": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The unique, URL-addressable name."
          },
          "state": {
            "type": [
              "null",
              "string"
            ],
            "description": "Lifecycle state: `ready`, `creating` (reserved for future async creation), or\n`notLoaded` - cataloged, but with no engine in this process (feature\nnamespace-startup-load). A `notLoaded` namespace still appears here BY DESIGN:\nhiding it reaches the Studio recover state by absence, whose primary action recreates it\nempty."
          },
          "vertexCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "The namespace's vertex count, or `null` when it is `notLoaded` and this\nprocess therefore has no count to report. Never `0` in that case: the Studio\ndashboard branches on `vertexCount === 0` to replay the first-run walkthrough, so a\nzero would greet an operator with \"get started\" over a namespace that holds data, and a\nreconciling writer would read \"healthy and empty\" and delete on that basis.",
            "format": "int32"
          },
          "edgeCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "The namespace's edge count, or `null` when it is `notLoaded`\n    (see int? NamespaceREST.VertexCount for why absent rather than zero).",
            "format": "int32"
          },
          "createdAt": {
            "type": [
              "null",
              "string"
            ],
            "description": "When the namespace was created (UTC, ISO 8601)."
          },
          "pluginRegistrationEnabled": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "This namespace's plugin-registration override (feature plugin-registration):\n`true`/`false` when set explicitly, `null` when it inherits the global\n`Fallen8:Security:EnableDynamicPluginLoading` default."
          },
          "loadOnStartupEnabled": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "This namespace's startup-load override (feature namespace-startup-load):\n`true`/`false` when set explicitly, `null` when it inherits the global\n`Fallen8:Namespaces:LoadOnStartup` default. It describes the NEXT boot, so it is\nindependent of string NamespaceREST.State - a loaded namespace can carry `false`, and a\n`notLoaded` one can carry `true` (it was excluded by\n`Fallen8:Namespaces:StartupLoadMode` instead). The reserved `default` namespace\nalways reports `true`: it aliases every bare URL and cannot be excluded."
          }
        },
        "description": "One namespace as the REST surface reports it (feature graph-namespaces). No memory\nfigure by design: engines share one GC heap, so a per-namespace byte count would be\nfiction (spec §5.3)."
      },
      "NamespacesREST": {
        "type": "object",
        "properties": {
          "namespaces": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/NamespaceREST"
            },
            "description": "All namespaces, name-ordered (always includes `default`)."
          },
          "maxNamespaces": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The configured `Fallen8:Namespaces:MaxNamespaces` ceiling.",
            "format": "int32"
          }
        },
        "description": "The namespace list with its configured ceiling."
      },
      "NamespaceUpdateSpecification": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional new namespace name (rename). Permissive: 1-63 characters of any case, spaces,\npunctuation, or Unicode; only empty/whitespace-only, leading/trailing whitespace,\n\".\" / \"..\", \"/\", \"\\\", and control characters are rejected. Case-sensitive. Omit to leave\nthe name unchanged."
          },
          "pluginRegistration": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional plugin-registration override (feature plugin-registration):\n`\"enabled\"` | `\"disabled\"` | `\"inherit\"`. Omit (or null) to leave it\nunchanged; `\"inherit\"` clears the override so this namespace follows the global\n`Fallen8:Security:EnableDynamicPluginLoading` default."
          },
          "loadOnStartup": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional startup-load override (feature namespace-startup-load):\n`\"enabled\"` | `\"disabled\"` | `\"inherit\"`, the same tri-state vocabulary as\nstring NamespaceUpdateSpecification.PluginRegistration. Omit (or null) to leave it unchanged;\n`\"inherit\"` clears the override so this namespace follows the global\n`Fallen8:Namespaces:LoadOnStartup` default. It takes effect on the next restart -\nit never loads or unloads the namespace in the running process."
          }
        },
        "description": "Request body for updating a namespace via `PATCH /ns/{name}`: rename it and/or set its\nplugin-registration or startup-load override. Every field is optional; supply at least one."
      },
      "NlpStatsREST": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "configured": {
            "type": "boolean"
          },
          "reachable": {
            "type": "boolean",
            "description": "Cached, short-TTL probe; only run when the capability is on (like docling)."
          }
        },
        "description": "The semantic-layer NLP enrichment state on the discovery surfaces (feature\nsemantic-layer, /status and /statistics): the flag plus a cached sidecar probe. The\nStudio's entity controls gate on this; enrichment is additive, so \"off\" just means no\nentity network is built. Null only when the host wired no NLP options."
      },
      "ObservabilityConfigREST": {
        "type": "object",
        "properties": {
          "otlpEnabled": {
            "type": "boolean",
            "description": "Whether OTLP push export is on (an endpoint is configured)."
          },
          "otlpEndpoint": {
            "type": [
              "null",
              "string"
            ],
            "description": "The OTLP endpoint metrics/traces/logs are pushed to, as configured; null when off."
          },
          "prometheusEnabled": {
            "type": "boolean",
            "description": "Whether the Prometheus scrape endpoint (GET /metrics) is mapped."
          },
          "prometheusRequireApiKey": {
            "type": "boolean",
            "description": "Whether /metrics requires the API key (vs the anonymous default)."
          },
          "tracingSamplingRatio": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Root trace sampling ratio [0, 1].",
            "format": "double"
          },
          "statisticsElementBudget": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The GET /statistics element budget before sampling kicks in.",
            "format": "int32"
          },
          "statisticsTopN": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Top-N size for the statistics cardinality lists.",
            "format": "int32"
          }
        },
        "description": "The observability posture (feature observability), read-only. Endpoints are\n    operator config (never a secret); this codebase's OTLP options carry only an endpoint."
      },
      "PartitionMembersREST": {
        "type": "object",
        "properties": {
          "partitionId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The partition id.",
            "format": "int32",
            "example": 0
          },
          "size": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The partition's total size (across all pages).",
            "format": "int32",
            "example": 42
          },
          "offset": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "This page's offset into the ascending-id member list.",
            "format": "int32",
            "example": 0
          },
          "members": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            },
            "description": "The member vertex ids on this page, ascending."
          }
        },
        "description": "One partition's membership page (partition algorithms)."
      },
      "PartitionSummaryREST": {
        "type": "object",
        "properties": {
          "partitionId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The partition id (WCC: smallest member vertex id; LABELPROPAGATION: the\n    community's label, itself a vertex id).",
            "format": "int32",
            "example": 0
          },
          "size": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The number of vertices in the partition.",
            "format": "int32",
            "example": 42
          }
        },
        "description": "One partition summary (partition algorithms), rows ordered size-descending\n    with ascending-partition-id tie-break."
      },
      "PathCostSpecification": {
        "type": "object",
        "properties": {
          "vertexCost": {
            "type": [
              "null",
              "string"
            ],
            "description": "Cost function for vertices during path traversal",
            "default": "return (vertex) => 1.0;",
            "example": "return (vertex) =&gt; vertex.TryGetProperty(out var age, \"age\") ? (double)age : 1.0;"
          },
          "edgeCost": {
            "type": [
              "null",
              "string"
            ],
            "description": "Cost function for edges during path traversal",
            "default": "return (edge) => 1.0;",
            "example": "return (edge) =&gt; edge.TryGetProperty(out var weight, \"weight\") ? (double)weight : 1.0;"
          }
        },
        "description": "Specification for defining cost functions used in path calculations",
        "example": {
          "vertexCost": "return (v) =&gt; v.TryGetProperty(out var age, \"age\") ? (double)age : 1.0;",
          "edgeCost": "return (e) =&gt; e.TryGetProperty(out var weight, \"weight\") ? (double)weight : 1.0;"
        }
      },
      "PathElementREST": {
        "required": [
          "sourceVertexId",
          "targetVertexId",
          "edgeId",
          "edgePropertyId",
          "direction",
          "weight"
        ],
        "type": "object",
        "properties": {
          "sourceVertexId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The identifier of the vertex where this path segment begins",
            "format": "int32",
            "default": 1,
            "example": 1
          },
          "targetVertexId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The identifier of the vertex where this path segment ends",
            "format": "int32",
            "default": 2,
            "example": 2
          },
          "edgeId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The identifier of the edge connecting the source and target vertices",
            "format": "int32",
            "default": 10,
            "example": 10
          },
          "edgePropertyId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The property identifier/type of the edge in this path segment",
            "default": "knows",
            "example": "knows"
          },
          "direction": {
            "description": "The direction in which the edge is traversed (OutgoingEdge, IncomingEdge, or UndirectedEdge)",
            "default": 1,
            "examples": [
              "OutgoingEdge"
            ],
            "$ref": "#/components/schemas/Direction"
          },
          "weight": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "The cost/weight associated with traversing this path segment",
            "format": "double",
            "default": 1.5,
            "example": 1.5
          }
        },
        "description": "Represents a single segment of a path between vertices in the graph",
        "example": {
          "sourceVertexId": 1,
          "targetVertexId": 2,
          "edgeId": 10,
          "edgePropertyId": "knows",
          "direction": "OutgoingEdge",
          "weight": 1.5
        }
      },
      "PathFilterSpecification": {
        "required": [
          "edgePropertyFilter",
          "vertexFilter",
          "edgeFilter"
        ],
        "type": "object",
        "properties": {
          "edgePropertyFilter": {
            "type": [
              "null",
              "string"
            ],
            "description": "Filter to apply on edge properties during path traversal",
            "default": "return (p) => true;",
            "example": "return (p) =&gt; p == \"knows\";"
          },
          "vertexFilter": {
            "type": [
              "null",
              "string"
            ],
            "description": "Filter to apply on vertices during path traversal",
            "default": "return (v) => true;",
            "example": "return (v) =&gt; v.Label == \"person\";"
          },
          "edgeFilter": {
            "type": [
              "null",
              "string"
            ],
            "description": "Filter to apply on edges during path traversal",
            "default": "return (e) => true;",
            "example": "return (e) =&gt; e.Label == \"friendship\";"
          }
        },
        "description": "Specification for filtering graph elements during path finding operations",
        "example": {
          "edgePropertyFilter": "return (p) =&gt; p == \"knows\";",
          "vertexFilter": "return (v) =&gt; v.Label == \"person\";",
          "edgeFilter": "return (e) =&gt; e.Label == \"friendship\";"
        }
      },
      "PathREST": {
        "required": [
          "pathElements",
          "totalWeight"
        ],
        "type": "object",
        "properties": {
          "pathElements": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PathElementREST"
            },
            "description": "The ordered sequence of path elements (vertices and edges) that form the path"
          },
          "totalWeight": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "The aggregate weight/cost of the entire path",
            "format": "double",
            "example": 3.5
          }
        },
        "description": "Represents a path between two vertices in the graph",
        "example": {
          "pathElements": [
            {
              "vertexId": 1,
              "edgeId": 10,
              "direction": "Outgoing",
              "weight": 1.0
            },
            {
              "vertexId": 2,
              "edgeId": 15,
              "direction": "Outgoing",
              "weight": 2.5
            },
            {
              "vertexId": 5,
              "edgeId": null,
              "direction": null,
              "weight": 0.0
            }
          ],
          "totalWeight": 3.5
        }
      },
      "PathSpecification": {
        "required": [
          "pathAlgorithmName",
          "maxDepth"
        ],
        "type": "object",
        "properties": {
          "pathAlgorithmName": {
            "type": [
              "null",
              "string"
            ],
            "description": "The algorithm to use for path finding.",
            "default": "BLS",
            "example": "BLS"
          },
          "maxDepth": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The maximum number of edges in paths to consider",
            "format": "uint16",
            "default": 7,
            "example": 5
          },
          "maxResults": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The maximum number of paths to return in the result",
            "format": "uint16",
            "default": 65535,
            "example": 10
          },
          "maxPathWeight": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "The maximum allowed weight for a path to be included in results",
            "format": "double",
            "example": 100.0
          },
          "timeBudgetSeconds": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "description": "Optional wall-clock budget for the traversal, in seconds.",
            "format": "double",
            "example": 5.0
          },
          "filter": {
            "description": "Filtering criteria for elements to include in path calculations",
            "$ref": "#/components/schemas/PathFilterSpecification"
          },
          "cost": {
            "description": "Cost function specifications for weighting paths",
            "$ref": "#/components/schemas/PathCostSpecification"
          },
          "storedQuery": {
            "type": [
              "null",
              "string"
            ],
            "description": "The name of a registered stored query of kind `Path` to use instead of inline\nPathFilterSpecification PathSpecification.Filter/PathCostSpecification PathSpecification.Cost fragments (feature stored-query-library).\nMutually exclusive with them (400 when mixed). A stored-query request compiles\nnothing (the pinned artifact runs); the numeric bounds and\nstring PathSpecification.PathAlgorithmName stay per-request.",
            "example": "adults-shortest"
          },
          "semantic": {
            "description": "The declarative semantic block (feature element-embeddings): the query vector for\nthe traversal context plus optional code-free similarity filter/cost. Pure data -\nit compiles no C#, and is deliberately NOT part of the compile\ncache key (the context is a factory parameter, not source).",
            "$ref": "#/components/schemas/SemanticTraversalSpecification"
          }
        },
        "description": "Specification for finding paths between vertices in the graph",
        "example": {
          "pathAlgorithmName": "BLS",
          "maxDepth": 5,
          "maxResults": 10,
          "maxPathWeight": 100.0,
          "filter": {
            "edgePropertyFilter": "return (p) =&gt; true;",
            "vertexFilter": "return (v) =&gt; true;",
            "edgeFilter": "return (e) =&gt; true;"
          },
          "cost": {
            "vertexCost": "return (v) =&gt; 1.0;",
            "edgeCost": "return (e) =&gt; 1.0;"
          }
        }
      },
      "PatternSpecification": {
        "type": "object",
        "properties": {
          "type": {
            "type": [
              "null",
              "string"
            ],
            "description": "The kind of pattern: `Vertex`, `Edge` or `VariableLengthEdge`.",
            "default": "Vertex",
            "example": "Vertex"
          },
          "patternName": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional name used to identify this pattern element in the definition.",
            "example": "start"
          },
          "vertexFilter": {
            "type": [
              "null",
              "string"
            ],
            "description": "Vertex-specific filter. Only meaningful when string PatternSpecification.Type is\n`Vertex`. The lambda receives a `VertexModel`.",
            "example": "return (v) =&gt; v.TryGetProperty(out var age, \"age\") &amp;&amp; (int)age &gt;= 18;"
          },
          "semanticMinScore": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "description": "Declarative semantic membership threshold for a `Vertex` pattern (feature\nsubgraph-semantic-thresholds): the vertex matches when its named embedding scores\npast this against the request's `semantic` query - the same scoring rules as\n`semantic.minScore` (at least, under Cosine/DotProduct; at most, under L2;\nvertices without the embedding never match). Owns the step's filter slot - setting\nit together with string PatternSpecification.VertexFilter is a 400, as is setting it on an edge\npattern or without a request-level `semantic` block. Pure data: it compiles\nno C#.",
            "format": "double",
            "example": 0.7
          },
          "direction": {
            "type": [
              "null",
              "string"
            ],
            "description": "Traversal direction for edge patterns: `OutgoingEdge`, `IncomingEdge`\nor `UndirectedEdge`. Only meaningful for `Edge` /\n`VariableLengthEdge`. Defaults to `OutgoingEdge`.",
            "default": "OutgoingEdge",
            "example": "OutgoingEdge"
          },
          "edgePropertyFilter": {
            "type": [
              "null",
              "string"
            ],
            "description": "Filter applied to an edge's type (its edgePropertyId, a string) before the edge\nitself is inspected. Only meaningful for edge patterns.",
            "example": "return (p) =&gt; p == \"knows\";"
          },
          "edgeFilter": {
            "type": [
              "null",
              "string"
            ],
            "description": "Edge-specific filter. Only meaningful for edge patterns. The lambda receives\nan `EdgeModel` (type filtering usually belongs in\n`edgePropertyFilter`; the edge's optional label is a separate,\northogonal tag).",
            "example": "return (e) =&gt; e.Label == \"friendship\";"
          },
          "minLength": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Minimum number of hops for a `VariableLengthEdge` pattern.",
            "format": "uint16",
            "default": 1,
            "example": 1
          },
          "maxLength": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Maximum number of hops for a `VariableLengthEdge` pattern.",
            "format": "uint16",
            "default": 1,
            "example": 3
          }
        },
        "description": "A single element of a subgraph pattern sequence."
      },
      "PluginDetailREST": {
        "type": "object",
        "properties": {
          "sourceCode": {
            "type": [
              "null",
              "string"
            ],
            "description": "The stored whole-type C# source; null for an entry that has none, which is what a\n    host-registered type (an \"Index\"/\"Service\" category) always is - a client must not assume\n    every listed plugin can be read back as source."
          },
          "compileDiagnostics": {
            "type": [
              "null",
              "string"
            ],
            "description": "The recompile diagnostics, present only for a `Failed` entry."
          },
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The registered name."
          },
          "category": {
            "type": [
              "null",
              "string"
            ],
            "description": "The category (\"Algorithm\" / \"Function\" / \"Index\" / \"Service\"). Only the first two can be\nregistered over REST; an \"Index\" or \"Service\" entry exists when the process hosting the\nengine registered the type itself, and is listed here like any other."
          },
          "contract": {
            "type": [
              "null",
              "string"
            ],
            "description": "The contract (\"Path\" / \"SubGraph\" / \"Analytics\" / \"GraphFunction\" / \"Index\" / \"Service\")."
          },
          "description": {
            "type": [
              "null",
              "string"
            ],
            "description": "The optional description."
          },
          "createdAt": {
            "type": "string",
            "description": "When the plugin was registered (UTC).",
            "format": "date-time"
          },
          "compileState": {
            "type": [
              "null",
              "string"
            ],
            "description": "The compile state (\"Compiled\" / \"Failed\" / \"SourceOnly\")."
          }
        },
        "description": "The full detail of a registered plugin: its summary plus the stored source (for inspection\nand manual cross-instance migration) and, for a `Failed` entry, the recompile\ndiagnostics."
      },
      "PluginSpecification": {
        "required": [
          "uniqueId",
          "pluginType"
        ],
        "type": "object",
        "properties": {
          "uniqueId": {
            "type": [
              "null",
              "string"
            ],
            "description": "A unique identifier for this plugin instance",
            "default": "indexService1",
            "example": "indexService1"
          },
          "pluginType": {
            "type": [
              "null",
              "string"
            ],
            "description": "The name of the plugin type to instantiate, resolved against the plugin contract the\ncalled endpoint needs: an INDEX plugin for `POST /index` (shipped names include\n`DictionaryIndex`, `RangeIndex`, `SingleValueIndex` and\n`VectorIndex`; `availableIndexPlugins` on `GET /status` is the live\nlist), or a SERVICE plugin for `POST /service`. No service plugin ships with\nFallen-8, so the example and default below are index names and are NOT valid for\n`POST /service`: that endpoint answers `200 false` for every value until a\nservice plugin is deployed next to the server and appears in\n`availableServicePlugins` on `GET /status`.",
            "default": "DictionaryIndex",
            "example": "DictionaryIndex"
          },
          "pluginOptions": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "$ref": "#/components/schemas/PropertySpecification"
            },
            "description": "Configuration options for the plugin as key-value pairs"
          }
        },
        "description": "Specification for creating a named plugin instance: an index (`POST /index`) or a\nservice (`POST /service`). The sample body below is the INDEX flavour; see\n`pluginType` for why no sample body can succeed on `POST /service`.",
        "example": {
          "uniqueId": "indexService1",
          "pluginType": "DictionaryIndex",
          "pluginOptions": {
            "indexProperty": {
              "propertyId": "propertyName",
              "fullQualifiedTypeName": "System.String",
              "propertyValue": "propertyValue"
            }
          }
        }
      },
      "PluginSummaryREST": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The registered name."
          },
          "category": {
            "type": [
              "null",
              "string"
            ],
            "description": "The category (\"Algorithm\" / \"Function\" / \"Index\" / \"Service\"). Only the first two can be\nregistered over REST; an \"Index\" or \"Service\" entry exists when the process hosting the\nengine registered the type itself, and is listed here like any other."
          },
          "contract": {
            "type": [
              "null",
              "string"
            ],
            "description": "The contract (\"Path\" / \"SubGraph\" / \"Analytics\" / \"GraphFunction\" / \"Index\" / \"Service\")."
          },
          "description": {
            "type": [
              "null",
              "string"
            ],
            "description": "The optional description."
          },
          "createdAt": {
            "type": "string",
            "description": "When the plugin was registered (UTC).",
            "format": "date-time"
          },
          "compileState": {
            "type": [
              "null",
              "string"
            ],
            "description": "The compile state (\"Compiled\" / \"Failed\" / \"SourceOnly\")."
          }
        },
        "description": "A summary of a registered plugin (feature plugin-registration): everything but the source."
      },
      "PluginValidationREST": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "Whether the source compiled and satisfied its contract."
          },
          "error": {
            "type": [
              "null",
              "string"
            ],
            "description": "The compiler / contract diagnostics when invalid; null when valid."
          }
        },
        "description": "The result of a side-effect-free plugin compile-check (feature plugin-registration): whether\nthe source compiled and satisfied its contract, and the diagnostics if not."
      },
      "PluginValidationSpecification": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The name the source must expose as `PluginName` (validated for equality)."
          },
          "contract": {
            "type": [
              "null",
              "string"
            ],
            "description": "The contract for an algorithm plugin (\"Path\"/\"SubGraph\"/\"Analytics\"); ignored for the function endpoint."
          },
          "sourceCode": {
            "type": [
              "null",
              "string"
            ],
            "description": "The whole-type C# source to compile-check."
          }
        },
        "description": "Request body for the side-effect-free validate endpoints\n`POST /plugins/algorithm/validate` and `POST /plugins/function/validate` (feature\nplugin-registration): compile + contract-validate source WITHOUT registering it, so the\nStudio editor can surface diagnostics. Shares the fields of the matching registration body."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": [
              "null",
              "string"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "detail": {
            "type": [
              "null",
              "string"
            ]
          },
          "instance": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "PropertySearchSpecification": {
        "required": [
          "searchTerm",
          "resultType"
        ],
        "type": "object",
        "properties": {
          "searchTerm": {
            "type": [
              "null",
              "string"
            ],
            "description": "The substring to look for across every property value (case-insensitive). Required\nand non-blank.",
            "example": "acme"
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional restrictor: only elements with exactly this label match.",
            "example": "company"
          },
          "resultType": {
            "description": "Specifies which types of graph elements to include in the results. Defaults to\nResultTypeSpecification.Both (discovery wants everything); the explicit\ninitializer is load-bearing because the enum's zero value is\nResultTypeSpecification.Vertices, so an omitted field would otherwise\ndeserialize to Vertices.",
            "default": "Both",
            "examples": [
              "Both"
            ],
            "$ref": "#/components/schemas/ResultTypeSpecification"
          }
        },
        "description": "Specification for a cold, un-indexed discovery scan across EVERY property of every\nelement: an element matches when any of its property values, rendered to text, contains\nthe search term (case-insensitive). Unlike ScanSpecification there is no\noperator or typed literal - just a substring term.",
        "example": {
          "searchTerm": "acme",
          "label": "company",
          "resultType": "Both"
        }
      },
      "PropertySpecification": {
        "required": [
          "propertyId",
          "fullQualifiedTypeName",
          "propertyValue"
        ],
        "type": "object",
        "properties": {
          "propertyId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The identifier name of the property",
            "default": "cacheSize",
            "example": "cacheSize"
          },
          "fullQualifiedTypeName": {
            "type": [
              "null",
              "string"
            ],
            "description": "The fully qualified .NET type name of the property",
            "default": "System.Int32",
            "example": "System.Int32"
          },
          "propertyValue": {
            "type": [
              "null",
              "string"
            ],
            "description": "The string representation of the property value",
            "default": "1000",
            "example": 1000
          }
        },
        "description": "Defines a property with name, type, and value for plugin configuration",
        "example": {
          "propertyId": "cacheSize",
          "fullQualifiedTypeName": "System.Int32",
          "propertyValue": "1000"
        }
      },
      "PropertyWriteSpecification": {
        "required": [
          "graphElementId",
          "propertyId",
          "fullQualifiedTypeName",
          "propertyValue"
        ],
        "type": "object",
        "properties": {
          "graphElementId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The element to write to. An in-range but absent id is a committed no-op (matching the\nsingle-element routes); an out-of-range id rolls the WHOLE batch back.",
            "format": "int32",
            "default": 0,
            "example": 42
          },
          "remove": {
            "type": "boolean",
            "description": "When `true` the property is REMOVED and the value fields are ignored. Removing an\nabsent property succeeds and changes nothing, which makes a replayed batch safe.",
            "default": false,
            "example": false
          },
          "propertyId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The identifier name of the property",
            "default": "cacheSize",
            "example": "cacheSize"
          },
          "fullQualifiedTypeName": {
            "type": [
              "null",
              "string"
            ],
            "description": "The fully qualified .NET type name of the property",
            "default": "System.Int32",
            "example": "System.Int32"
          },
          "propertyValue": {
            "type": [
              "null",
              "string"
            ],
            "description": "The string representation of the property value",
            "default": "1000",
            "example": 1000
          }
        },
        "description": "One write in a `PUT /graphelements/properties` batch (feature\nplatform-integrity-audit W2): set string PropertySpecification.PropertyId on\nint PropertyWriteSpecification.GraphElementId to the given value, or REMOVE it when bool PropertyWriteSpecification.Remove\nis `true`.\n\nWrites have REPLACE semantics, so a key that already exists is overwritten. Setting a\nkey to the value it already holds, or removing one that is already absent, is a TRUE no-op:\nit bumps no modification date and publishes no change-feed event. That is what lets a caller\nre-assert the state an external source describes without producing mutations.",
        "example": {
          "graphElementId": 42,
          "propertyId": "ip",
          "fullQualifiedTypeName": "System.String",
          "propertyValue": "10.0.0.9"
        }
      },
      "RangeIndexScanSpecification": {
        "required": [
          "indexId",
          "leftLimit",
          "rightLimit",
          "fullQualifiedTypeName",
          "resultType"
        ],
        "type": "object",
        "properties": {
          "indexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The identifier of the index to scan",
            "default": "ageIndex",
            "example": "ageIndex"
          },
          "leftLimit": {
            "type": [
              "null",
              "string"
            ],
            "description": "The lower bound of the range as a string representation",
            "default": "18",
            "example": 18
          },
          "rightLimit": {
            "type": [
              "null",
              "string"
            ],
            "description": "The upper bound of the range as a string representation",
            "default": "30",
            "example": 30
          },
          "fullQualifiedTypeName": {
            "type": [
              "null",
              "string"
            ],
            "description": "The fully qualified .NET type name of the range values",
            "default": "System.Int32",
            "example": "System.Int32"
          },
          "includeLeft": {
            "type": "boolean",
            "description": "Whether to include the lower bound value in the range (inclusive)",
            "default": true,
            "example": true
          },
          "includeRight": {
            "type": "boolean",
            "description": "Whether to include the upper bound value in the range (inclusive)",
            "default": false,
            "example": false
          },
          "resultType": {
            "description": "Specifies which types of graph elements to include in the results",
            "default": "Vertices",
            "examples": [
              "Vertices"
            ],
            "$ref": "#/components/schemas/ResultTypeSpecification"
          }
        },
        "description": "Specification for performing a range-based scan on an index",
        "example": {
          "indexId": "ageIndex",
          "leftLimit": "18",
          "rightLimit": "30",
          "fullQualifiedTypeName": "System.Int32",
          "includeLeft": true,
          "includeRight": false,
          "resultType": "Vertices"
        }
      },
      "ResultTypeSpecification": {
        "enum": [
          "Vertices",
          "Edges",
          "Both"
        ],
        "description": "Specifies which types of graph elements to include in query results",
        "example": "Vertices"
      },
      "SaveGameKpisREST": {
        "type": "object",
        "properties": {
          "vertexCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "edgeCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "usedMemoryBytes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The process's working set (physical RAM in use) when the save was taken, in bytes.",
            "format": "int64"
          },
          "indices": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/IndexDescriptionREST"
            }
          },
          "availableIndexPlugins": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          },
          "availablePathPlugins": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          },
          "availableServicePlugins": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          },
          "subGraphs": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Cheap KPIs captured at save/import time - values the engine already has, no graph scan."
      },
      "SaveGameNamespaceREST": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The namespace name at save time (restores under this name)."
          },
          "id": {
            "type": [
              "null",
              "string"
            ],
            "description": "The namespace's IMMUTABLE id at save time — what the boot chain matches on, so a\nrename never orphans a namespace's newest save and a drop+recreate (fresh id) never\nresurrects the dropped one's checkpoints. Null on pre-namespace (v1) entries, which\nnormalize to the default namespace's stable id."
          },
          "location": {
            "type": [
              "null",
              "string"
            ],
            "description": "Absolute path of this namespace's primary checkpoint file."
          },
          "fileCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Number of files belonging to this namespace's checkpoint.",
            "format": "int32"
          },
          "totalBytes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Total size of those files in bytes at registration time.",
            "format": "int64"
          },
          "kpis": {
            "$ref": "#/components/schemas/SaveGameKpisREST"
          }
        },
        "description": "One namespace inside a save game: its own checkpoint location, file facts, and KPIs\n(feature graph-namespaces, registry schema v2)."
      },
      "SaveGameREST": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "null",
              "string"
            ],
            "description": "Stable id; sortable timestamp prefix + random suffix. The REST identifier."
          },
          "savedAt": {
            "type": [
              "null",
              "string"
            ],
            "description": "ISO-8601 UTC instant the save game was created (or the file's write time for imports)."
          },
          "trigger": {
            "type": [
              "null",
              "string"
            ],
            "description": "How the entry was created: \"api\", \"shutdown\" or \"imported\"."
          },
          "location": {
            "type": [
              "null",
              "string"
            ],
            "description": "Absolute path of the primary checkpoint file."
          },
          "fileCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Number of files belonging to this save game (checkpoint + partitions + sidecars).",
            "format": "int32"
          },
          "totalBytes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Total size of those files in bytes at registration time.",
            "format": "int64"
          },
          "engineVersion": {
            "type": [
              "null",
              "string"
            ],
            "description": "The engine/assembly version that produced the entry."
          },
          "kpis": {
            "$ref": "#/components/schemas/SaveGameKpisREST"
          },
          "namespaces": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/SaveGameNamespaceREST"
            },
            "description": "The namespaces this save game contains (feature graph-namespaces, registry schema v2).\nNull on pre-namespace (v1) entries, which are read forever as \"a default-only save\"\nwhose checkpoint is string SaveGameREST.Location. On single-namespace entries the top-level\nlocation/kpis mirror the one member (v1-shaped); on multi-namespace entries the\ntop-level location is null and fileCount/totalBytes are sums across the members."
          },
          "skippedNamespaces": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "The namespaces `PUT /save/all` did NOT save because they are cataloged but not\nloaded in this process (feature namespace-startup-load): the entry therefore spans a\nstrict SUBSET of the Fallen-8, and a caller reading only `namespaces` could not tell\nthat from a Fallen-8 that has no other namespaces.\nTransient, and the ONLY field on this DTO that is: it describes one operation\nrather than the registered save game, so it is set on that response alone and is null\n(hence omitted, and absent from savegames.json) everywhere else. A header was\nrejected because namespace names may contain commas and non-ASCII characters, neither of\nwhich a header value can carry faithfully."
          },
          "activatedNamespaces": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "The namespaces `PUT /savegames/{id}/load` had to LOAD into this process before it\ncould restore into them, because they were cataloged but not loaded (feature\nnamespace-startup-load, spec decision 8.3). Their startup-load policy was set to\n`enabled` in the same request - restoring data into a namespace the next boot skips\nwould make it invisible again, which is the trap 8.3 exists to close - so this one member\nreports both halves of a single decision.\nTransient in exactly the way List&lt;string&gt; SaveGameREST.SkippedNamespaces is (see there for the\nreasoning, which is the same and lives in one place): it describes one operation, not the\nregistered save game, so it is null - hence omitted, and absent from\nsavegames.json - everywhere else."
          }
        },
        "description": "A registered save game (checkpoint) with its metadata (feature save-games)."
      },
      "SaveSpecification": {
        "type": "object",
        "properties": {
          "saveGameLocation": {
            "type": [
              "null",
              "string"
            ],
            "description": "The file path location where the Fallen-8 database should be saved",
            "example": "C:/Fallen8/database.f8s"
          },
          "savePartitions": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "The number of partitions to use when saving (optional, defaults to optimal based on processor count)",
            "format": "int32",
            "example": 8
          }
        },
        "description": "Specification for saving a Fallen-8 database to disk",
        "example": {
          "saveGameLocation": "C:/Fallen8/database.f8s",
          "savePartitions": 8
        }
      },
      "ScanSpecification": {
        "required": [
          "operator",
          "literal",
          "resultType"
        ],
        "type": "object",
        "properties": {
          "operator": {
            "description": "The binary operator to use for comparing property values, sent as its integer code:\n0 Equals, 1 Greater, 2 GreaterOrEquals, 3 Lower, 4 LowerOrEquals, 5 NotEquals.\nA member name is not accepted: unlike resultType, this enum carries no string-enum\nconverter, so the code is the wire form (this summary is the mapping's one home,\nsince the generated schema shows only \"integer\").",
            "examples": [
              0
            ],
            "$ref": "#/components/schemas/BinaryOperator"
          },
          "literal": {
            "description": "The literal value to compare against",
            "$ref": "#/components/schemas/LiteralSpecification"
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional restrictor: only elements with exactly this label match",
            "example": "person"
          },
          "resultType": {
            "description": "Specifies which types of graph elements to include in the results",
            "default": "Vertices",
            "examples": [
              "Vertices"
            ],
            "$ref": "#/components/schemas/ResultTypeSpecification"
          }
        },
        "description": "Specification for scanning the graph for elements with specific property values",
        "example": {
          "operator": 0,
          "literal": {
            "value": "John Doe",
            "fullQualifiedTypeName": "System.String"
          },
          "label": "person",
          "resultType": "Vertices"
        }
      },
      "ScoredVertexREST": {
        "type": "object",
        "properties": {
          "graphElementId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The vertex id.",
            "format": "int32",
            "example": 7
          },
          "score": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "The raw score (PageRank mass, degree, triangle count).",
            "format": "double",
            "example": 0.25
          }
        },
        "description": "One scored vertex (score algorithms), rows ordered score-descending with\n    ascending-id tie-break."
      },
      "SearchDistanceSpecification": {
        "required": [
          "indexId",
          "graphElementId",
          "distance"
        ],
        "type": "object",
        "properties": {
          "indexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The identifier of the spatial index to search",
            "default": "locationIndex",
            "example": "locationIndex"
          },
          "graphElementId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The identifier of the reference graph element for the distance calculation",
            "format": "int32",
            "default": 123,
            "example": 123
          },
          "distance": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "The maximum distance to search within",
            "format": "float",
            "default": 5,
            "example": 5.0
          }
        },
        "description": "Specification for performing spatial distance searches in the graph",
        "example": {
          "indexId": "locationIndex",
          "graphElementId": 123,
          "distance": 5.0
        }
      },
      "SemanticConfigREST": {
        "type": "object",
        "properties": {
          "embedding": {
            "description": "The embedding provider state (may be null when no provider is wired).",
            "$ref": "#/components/schemas/EmbeddingProviderStatsREST"
          },
          "chat": {
            "description": "The chat gateway state (may be null when no provider is wired).",
            "$ref": "#/components/schemas/ChatProviderStatsREST"
          }
        },
        "description": "The semantic providers (embedding + chat) grouped as one view."
      },
      "SemanticTraversalSpecification": {
        "type": "object",
        "properties": {
          "queryVector": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            },
            "description": "The query vector to score elements against."
          },
          "queryText": {
            "type": [
              "null",
              "string"
            ],
            "description": "A query TEXT to embed instead of supplying float[] SemanticTraversalSpecification.QueryVector (feature\nembedding-provider; mutually exclusive with it). Embedded ONCE, before the\ntraversal starts, by the active provider - requires the EmbeddingProvider\ncapability (403 when `Fallen8:Embedding:Enabled` is off).",
            "example": "red bicycles"
          },
          "embeddingName": {
            "type": [
              "null",
              "string"
            ],
            "description": "The embedding name to score (default \"default\").",
            "example": "default"
          },
          "metric": {
            "type": [
              "null",
              "string"
            ],
            "description": "The metric: Cosine (default), DotProduct or L2.",
            "example": "Cosine"
          },
          "minScore": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "description": "Optional declarative filter threshold: an element passes when its named embedding\nscores at least this well (at most, under L2); elements without the embedding are\nfiltered.",
            "format": "double",
            "example": 0.7
          },
          "costBySimilarity": {
            "type": "boolean",
            "description": "Optional declarative vertex cost (path requests only): Cosine maps to\n`1 - score`, L2 to the distance itself; DotProduct has no honest non-negative\nmapping and is rejected. Vertices without the embedding are filtered.",
            "example": true
          }
        },
        "description": "The declarative semantic block of a path or subgraph request (feature\nelement-embeddings). Carries the query vector for the traversal context - embedded\nONCE, before the traversal starts - plus optional code-free filter/cost derivations.\nPure data (it compiles no C#); conflicts with a C# fragment or a\nstored query owning the same delegate slot are rejected (one owner per slot).",
        "example": {
          "queryVector": [
            0.1,
            0.2
          ],
          "embeddingName": "default",
          "metric": "Cosine",
          "minScore": 0.7
        }
      },
      "StatusREST": {
        "type": "object",
        "properties": {
          "usedMemory": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The database process's working set (physical RAM currently in use), in bytes — the\nfigure an operator reads as \"memory used\" (matches /statistics processWorkingSetBytes).\nNOT the reserved virtual address space, which modern .NET makes enormous.",
            "format": "int64",
            "default": 1073741824,
            "example": 1073741824
          },
          "namespaceState": {
            "type": [
              "null",
              "string"
            ],
            "description": "The addressed namespace's residency (feature namespace-startup-load): `ready`\nnormally, `notLoaded` when this namespace is cataloged but has no engine in this\nprocess. In that state every engine-derived field on this response is ABSENT (null)\nrather than zero or empty - a zero count reads as \"healthy and empty\" both to the\nfirst-run walkthrough and to a client that deletes state because nothing asserts it any\nmore. Only this probe answers for a not-loaded namespace; every other namespace-scoped\nroute refuses with 503.",
            "example": "ready"
          },
          "vertexCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "The total number of vertices in the addressed namespace, or null when it is\n`notLoaded` (see string StatusREST.NamespaceState)",
            "format": "int32",
            "default": 10000,
            "example": 10000
          },
          "edgeCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "The total number of edges in the addressed namespace, or null when it is\n`notLoaded` (see string StatusREST.NamespaceState)",
            "format": "int32",
            "default": 25000,
            "example": 25000
          },
          "indices": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/IndexDescriptionREST"
            },
            "description": "The indices currently registered on this instance (id + plugin type) — the live\ninventory, available without running the budgeted statistics pass"
          },
          "availableIndexPlugins": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "List of available index plugins that can be used with the database",
            "example": [
              "DictionaryIndex",
              "SpatialIndex",
              "FullTextIndex"
            ]
          },
          "availablePathPlugins": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "List of available path-finding algorithm plugins",
            "example": [
              "Dijkstra",
              "AStar",
              "BellmanFord"
            ]
          },
          "availableSubGraphPlugins": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "List of available subgraph algorithm plugins (reflection-discovered built-ins unioned\nwith the addressed namespace's runtime-registered subgraph plugins)",
            "example": [
              "Breadth First Search Subgraph Algorithm"
            ]
          },
          "availableAnalyticsPlugins": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "List of available graph-analytics algorithm plugins",
            "example": [
              "PAGERANK",
              "WCC",
              "LABELPROPAGATION",
              "DEGREE",
              "TRIANGLECOUNT"
            ]
          },
          "availableServicePlugins": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "List of available service plugins that can be started with the database",
            "example": [
              "ImportService",
              "ExportService",
              "AnalyticsService"
            ]
          },
          "apiKeyRequired": {
            "type": "boolean",
            "description": "True when this server has an API key configured, i.e. every endpoint outside the\nanonymous allowlist answers 401 without a valid credential. /status itself stays\nanonymous, so it doubles as the connection probe: a caller is authorized iff\n`!ApiKeyRequired || Authenticated`.",
            "example": false
          },
          "authenticated": {
            "type": "boolean",
            "description": "True when the request that produced this status carried a valid credential\n(see bool StatusREST.ApiKeyRequired for how clients combine the two).",
            "example": false
          },
          "embedding": {
            "description": "The embedding provider state (feature embedding-provider) — here on the cheap\ndiscovery surface because it is a config read, not a graph pass; null only when\nthe host wired no provider. See EmbeddingProviderStatsREST.",
            "$ref": "#/components/schemas/EmbeddingProviderStatsREST"
          },
          "chat": {
            "description": "The chat gateway state (feature instance-config) — a config read like\nEmbeddingProviderStatsREST StatusREST.Embedding, so it rides the cheap probe for capability discovery\n(e.g. the MCP overview's chatEnabled). Null when the host wired no provider. The\nGPU field stays null here; GET /config carries the probed value.",
            "$ref": "#/components/schemas/ChatProviderStatsREST"
          },
          "ingestion": {
            "description": "The unstructured-ingestion state (feature unstructured-ingestion): a config read\nplus a cached sidecar probe, so it rides the cheap discovery surface too. Null\nonly when the host wired no ingestion options.",
            "$ref": "#/components/schemas/IngestionStatsREST"
          },
          "nlp": {
            "description": "The semantic-layer NLP enrichment state (feature semantic-layer): a config read\nplus a cached sidecar probe. Null only when the host wired no NLP options.",
            "$ref": "#/components/schemas/NlpStatsREST"
          },
          "durability": {
            "description": "Whether this namespace's writes are actually reaching disk, and whether the state being\nserved is the complete committed history or a prefix of it (feature\nplatform-integrity-audit W5). A cheap read of state the engine already publishes.",
            "$ref": "#/components/schemas/DurabilityStatusREST"
          }
        },
        "description": "Represents the current status of the Fallen-8 database",
        "example": {
          "usedMemory": 1073741824,
          "vertexCount": 10000,
          "edgeCount": 25000,
          "namespaceState": "ready",
          "indices": [
            {
              "indexId": "nameIndex",
              "pluginType": "DictionaryIndex"
            }
          ],
          "availableIndexPlugins": [
            "DictionaryIndex",
            "SpatialIndex"
          ],
          "availablePathPlugins": [
            "Dijkstra",
            "AStar"
          ],
          "availableAnalyticsPlugins": [
            "PAGERANK",
            "WCC"
          ],
          "availableServicePlugins": [
            "ImportService",
            "ExportService"
          ],
          "apiKeyRequired": false,
          "authenticated": false
        }
      },
      "StoredPathQueryBlock": {
        "type": "object",
        "properties": {
          "filter": {
            "description": "Filtering criteria for elements to include in path calculations.",
            "$ref": "#/components/schemas/PathFilterSpecification"
          },
          "cost": {
            "description": "Cost function specifications for weighting paths.",
            "$ref": "#/components/schemas/PathCostSpecification"
          }
        },
        "description": "The stored form of a path query: the `filter`/`cost` blocks of a\nPathSpecification. The numeric bounds (`maxDepth`, `maxResults`,\n`maxPathWeight`) and the algorithm name stay per-request."
      },
      "StoredQueryDetailREST": {
        "type": "object",
        "properties": {
          "specificationJson": {
            "type": [
              "null",
              "string"
            ],
            "description": "The stored specification document (JSON text): the registration request's\n`path` / `subGraph` block exactly as stored."
          },
          "compileDiagnostics": {
            "type": [
              "null",
              "string"
            ],
            "description": "The compiler diagnostics of a failed rehydration recompile; null unless\nstring StoredQuerySummaryREST.CompileState is `Failed`."
          },
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The stored query name.",
            "example": "adults-shortest"
          },
          "kind": {
            "type": [
              "null",
              "string"
            ],
            "description": "The stored query kind (`Path` or `SubGraph`).",
            "example": "Path"
          },
          "description": {
            "type": [
              "null",
              "string"
            ],
            "description": "The optional description."
          },
          "createdAt": {
            "type": "string",
            "description": "When the query was registered (UTC).",
            "format": "date-time"
          },
          "compileState": {
            "type": [
              "null",
              "string"
            ],
            "description": "The compile state: `Compiled` (invocable), `Failed` (a rehydration\nrecompile failed - see the detail response's diagnostics; invoking returns 409), or\n`SourceOnly` (loaded without a compiler).",
            "example": "Compiled"
          }
        },
        "description": "Full detail of a registered stored query, INCLUDING its source specification - the\nlibrary is transparent to its operator (and `GET` covers manual migration between\ninstances)."
      },
      "StoredQuerySpecification": {
        "required": [
          "name",
          "kind"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The unique name to register the query under. Restricted to\n`^[A-Za-z0-9_-]{1,128}$` (always a safe URL path segment); compared\ncase-sensitively.",
            "example": "adults-shortest"
          },
          "kind": {
            "type": [
              "null",
              "string"
            ],
            "description": "The stored query kind: `Path` (a filter/cost set for `POST /path`) or\n`SubGraph` (a pattern template for `PUT /subgraph`).",
            "example": "Path"
          },
          "description": {
            "type": [
              "null",
              "string"
            ],
            "description": "An optional human-readable description.",
            "example": "age&gt;30 vertices, weight-by-distance"
          },
          "path": {
            "description": "The path filter/cost block (required iff string StoredQuerySpecification.Kind is `Path`).",
            "$ref": "#/components/schemas/StoredPathQueryBlock"
          },
          "subGraph": {
            "description": "The subgraph pattern template block (required iff string StoredQuerySpecification.Kind is\n`SubGraph`). The subgraph instance name and additional information stay\nper-request on `PUT /subgraph` and are not part of the stored template.",
            "$ref": "#/components/schemas/StoredSubGraphQueryBlock"
          }
        },
        "description": "Specification for registering a stored query (feature stored-query-library): a named,\nvalidated, pre-compiled query definition that the path/subgraph endpoints can afterwards\nreference by name - invocation compiles nothing (the pinned artifact runs).",
        "example": {
          "name": "adults-shortest",
          "kind": "Path",
          "description": "age&gt;30 vertices, weight-by-distance",
          "path": {
            "filter": {
              "vertexFilter": "return (v) =&gt; v.TryGetProperty(out int age, \"age\") &amp;&amp; age &gt; 30;"
            },
            "cost": {
              "edgeCost": "return (e) =&gt; 1.0;"
            }
          }
        }
      },
      "StoredQuerySummaryREST": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The stored query name.",
            "example": "adults-shortest"
          },
          "kind": {
            "type": [
              "null",
              "string"
            ],
            "description": "The stored query kind (`Path` or `SubGraph`).",
            "example": "Path"
          },
          "description": {
            "type": [
              "null",
              "string"
            ],
            "description": "The optional description."
          },
          "createdAt": {
            "type": "string",
            "description": "When the query was registered (UTC).",
            "format": "date-time"
          },
          "compileState": {
            "type": [
              "null",
              "string"
            ],
            "description": "The compile state: `Compiled` (invocable), `Failed` (a rehydration\nrecompile failed - see the detail response's diagnostics; invoking returns 409), or\n`SourceOnly` (loaded without a compiler).",
            "example": "Compiled"
          }
        },
        "description": "Summary of a registered stored query (list/detail responses)."
      },
      "StoredSubGraphQueryBlock": {
        "type": "object",
        "properties": {
          "vertexFilter": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional pre-filter selecting which vertices are copied into the subgraph\n(a C# fragment receiving a `VertexModel`).",
            "example": "return (v) =&gt; v.Label == \"person\";"
          },
          "edgeFilter": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional pre-filter selecting which edges are copied into the subgraph\n(a C# fragment receiving an `EdgeModel`; filter by type via\n`e.EdgePropertyId`).",
            "example": "return (e) =&gt; e.EdgePropertyId == \"knows\";"
          },
          "patterns": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PatternSpecification"
            },
            "description": "Ordered pattern sequence describing the paths to keep (see\nList&lt;PatternSpecification&gt; SubGraphSpecification.Patterns)."
          }
        },
        "description": "The stored form of a subgraph query: a SubGraphSpecification WITHOUT the\nper-instance `name`/`additionalInformation` fields."
      },
      "SubGraphPatternThresholdSummary": {
        "type": "object",
        "properties": {
          "pattern": {
            "type": [
              "null",
              "string"
            ],
            "description": "The step's `patternName`, or its zero-based index when unnamed."
          },
          "minScore": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "The step's threshold.",
            "format": "double"
          }
        },
        "description": "One vertex pattern step's semantic threshold, identified by name or position."
      },
      "SubGraphSemanticSummary": {
        "type": "object",
        "properties": {
          "embeddingName": {
            "type": [
              "null",
              "string"
            ],
            "description": "The named embedding the subgraph's filters score (effective, so never null)."
          },
          "metric": {
            "type": [
              "null",
              "string"
            ],
            "description": "The metric the scores are computed under (effective, so never null)."
          },
          "dimension": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The dimension of the bound query vector.",
            "format": "int32"
          },
          "queryText": {
            "type": [
              "null",
              "string"
            ],
            "description": "The query text the vector was resolved from at registration, when the subgraph was\ncreated via `semantic.queryText`; null for client-supplied vectors. Documents\nintent - the bound vector remains the truth and is never re-embedded."
          },
          "minScore": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "description": "The top-level vertex pre-filter threshold (`semantic.minScore`), when set.",
            "format": "double"
          },
          "patternThresholds": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/SubGraphPatternThresholdSummary"
            },
            "description": "The vertex pattern steps carrying a `semanticMinScore`, when any."
          }
        },
        "description": "The bound semantic state of a registered subgraph (feature\nsubgraph-semantic-thresholds), echoed on its summary: the query the subgraph's\nfilters were registered against and where its thresholds sit. The raw query vector is\ndeliberately NOT part of the echo - only its dimension; a registered subgraph reveals\nits binding, not its payload.",
        "example": {
          "embeddingName": "default",
          "metric": "Cosine",
          "dimension": 384,
          "queryText": "red bicycles",
          "minScore": 0.7,
          "patternThresholds": [
            {
              "pattern": "start",
              "minScore": 0.6
            }
          ]
        }
      },
      "SubGraphSpecification": {
        "required": [
          "name"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "Unique name the subgraph is registered under.",
            "example": "friends-of-alice"
          },
          "additionalInformation": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "type": "string"
            },
            "description": "Optional metadata attached to the subgraph definition."
          },
          "vertexFilter": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional pre-filter selecting which vertices are copied into the subgraph.\nNull or empty copies all vertices. The lambda receives a `VertexModel`.",
            "example": "return (v) =&gt; v.Label == \"person\";"
          },
          "edgeFilter": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional pre-filter selecting which edges are copied into the subgraph. Null\nor empty copies all edges whose endpoints were copied. The lambda receives an\n`EdgeModel`; filter by type via `e.EdgePropertyId`.",
            "example": "return (e) =&gt; e.EdgePropertyId == \"knows\";"
          },
          "patterns": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PatternSpecification"
            },
            "description": "Ordered pattern sequence describing the paths to keep. Should alternate\nvertex ↔ edge and start with a vertex pattern. Empty means \"no pruning\"."
          },
          "algorithm": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional name of the subgraph algorithm plugin that performs the extraction, as\nreported by the plugin's `PluginName`. Accepts a built-in name or the name a\nplugin of contract `SubGraph` was registered under in this namespace (the set\n`GET /status` reports as `availableSubGraphPlugins`); an unknown name is a\n400, never a silent fallback. Omitted (null or empty) selects the built-in\nbreadth-first search algorithm, which is what every request without this field gets.\nThe selected name is stored with the subgraph, so a recalculation re-resolves the same\nplugin.",
            "example": "Breadth First Search Subgraph Algorithm"
          },
          "storedQuery": {
            "type": [
              "null",
              "string"
            ],
            "description": "The name of a registered stored query of kind `SubGraph` to instantiate instead\nof inline string SubGraphSpecification.VertexFilter/string SubGraphSpecification.EdgeFilter/List&lt;PatternSpecification&gt; SubGraphSpecification.Patterns\nfragments (feature stored-query-library). Mutually exclusive with them (400 when\nmixed); string SubGraphSpecification.Name (and optional Dictionary&lt;string, string&gt; SubGraphSpecification.AdditionalInformation) stay\nrequired per instance. A stored-query request compiles nothing (the pinned template\nis instantiated).",
            "example": "person-net"
          },
          "semantic": {
            "description": "The declarative semantic block (feature element-embeddings): the query vector the\ncompiled filters' traversal context carries, plus an optional code-free\n`minScore` vertex pre-filter. Bound at REGISTRATION time - recalculation\nreuses the same delegates and never embeds anything. Pure data (it compiles no C#);\nmutually exclusive with string SubGraphSpecification.StoredQuery and, when\n`minScore` is set, with an inline string SubGraphSpecification.VertexFilter fragment.",
            "$ref": "#/components/schemas/SemanticTraversalSpecification"
          }
        },
        "description": "Specification for creating a subgraph by pattern matching against the graph.",
        "example": {
          "name": "friends-of-alice",
          "vertexFilter": "return (v) =&gt; v.Label == \"person\";",
          "edgeFilter": "return (e) =&gt; e.EdgePropertyId == \"knows\";",
          "patterns": [
            {
              "type": "Vertex",
              "patternName": "start",
              "vertexFilter": "return (v) =&gt; v.Label == \"person\";"
            },
            {
              "type": "Edge",
              "patternName": "rel",
              "direction": "OutgoingEdge",
              "edgePropertyFilter": "return (p) =&gt; p == \"knows\";"
            },
            {
              "type": "Vertex",
              "patternName": "end",
              "vertexFilter": "return (v) =&gt; v.Label == \"person\";"
            }
          ]
        }
      },
      "SubGraphSummary": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ],
            "description": "The name the subgraph is registered under."
          },
          "vertexCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Number of vertices in the extracted subgraph.",
            "format": "int32"
          },
          "edgeCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Number of edges in the extracted subgraph.",
            "format": "int32"
          },
          "algorithmPluginName": {
            "type": [
              "null",
              "string"
            ],
            "description": "The algorithm plugin used to create the subgraph."
          },
          "sourceFallen8Id": {
            "type": "string",
            "description": "The id of the source graph the subgraph was created from.",
            "format": "uuid"
          },
          "canRecalculate": {
            "type": "boolean",
            "description": "Whether this subgraph can be recalculated against its source."
          },
          "additionalInformation": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "type": "string"
            },
            "description": "Metadata attached to the subgraph definition."
          },
          "semantic": {
            "description": "The bound semantic state (feature subgraph-semantic-thresholds), projected from the\npersisted recipe; absent for non-semantic subgraphs and for subgraphs without a\nrecipe (direct-delegate engine use).",
            "$ref": "#/components/schemas/SubGraphSemanticSummary"
          }
        },
        "description": "A lightweight summary of a registered subgraph (metadata and element counts),\nwithout the full vertex/edge payload.",
        "example": {
          "name": "friends-of-alice",
          "vertexCount": 3,
          "edgeCount": 2,
          "algorithmPluginName": "Breadth First Search Subgraph Algorithm",
          "sourceFallen8Id": "6f1e...",
          "canRecalculate": true,
          "additionalInformation": {
            "category": "social"
          }
        }
      },
      "ValidateDelegateSpecification": {
        "required": [
          "delegateKind"
        ],
        "type": "object",
        "properties": {
          "delegateKind": {
            "type": [
              "null",
              "string"
            ],
            "description": "The delegate kind the fragment must compile against",
            "default": "VertexFilter",
            "example": "VertexFilter"
          },
          "fragment": {
            "type": [
              "null",
              "string"
            ],
            "description": "The C# fragment to validate: a method body returning a lambda",
            "example": "return (v) =&gt; v.Label == \"person\";"
          }
        },
        "description": "Request to compile-check a single delegate fragment (feature web-ui, gap G-2)",
        "example": {
          "delegateKind": "VertexFilter",
          "fragment": "return (v) =&gt; v.Label == \"person\";"
        }
      },
      "VectorIndexAddSpecification": {
        "required": [
          "graphElementId"
        ],
        "type": "object",
        "properties": {
          "graphElementId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The element to index.",
            "format": "int32",
            "example": 42
          },
          "vector": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            },
            "description": "The embedding vector (explicit mode). Must match the index dimension."
          },
          "propertyId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The element property holding the vector (property mode); the property must\n    be a float[] of the index dimension.",
            "example": "embedding"
          }
        },
        "description": "Adds (or replaces) an element's vector in a vector index (feature vector-index).\nExactly one mode: an explicit float[] VectorIndexAddSpecification.Vector, or string VectorIndexAddSpecification.PropertyId naming\na `float[]` property on the element to read the vector from.",
        "example": {
          "graphElementId": 42,
          "vector": [
            0.12,
            -0.5,
            0.33
          ]
        }
      },
      "VectorIndexScanSpecification": {
        "required": [
          "indexId",
          "query",
          "k"
        ],
        "type": "object",
        "properties": {
          "indexId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The vector index to query.",
            "example": "myEmbeddings"
          },
          "query": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
              "type": [
                "number",
                "string"
              ],
              "format": "float"
            },
            "description": "The query vector; must match the index dimension."
          },
          "k": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "How many nearest neighbours to return (1..1024).",
            "format": "int32",
            "example": 10
          },
          "kind": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional element-kind constraint: vertex, edge, or any (default).",
            "example": "vertex"
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "Optional exact (case-sensitive) label constraint; an unlabeled element never\n    matches.",
            "example": "person"
          }
        },
        "description": "A k-nearest-neighbour query against a vector index (feature vector-index).",
        "example": {
          "indexId": "myEmbeddings",
          "query": [
            0.1,
            0.2,
            0.3
          ],
          "k": 10,
          "kind": "vertex",
          "label": "person"
        }
      },
      "VectorScoredElementREST": {
        "type": "object",
        "properties": {
          "graphElementId": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The element id.",
            "format": "int32",
            "example": 7
          },
          "score": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "The raw score (no normalization; interpret via metric/higherIsBetter).",
            "format": "float",
            "example": 0.93
          }
        },
        "description": "One kNN hit: the element id and its RAW score under the index metric."
      },
      "VectorSearchResultREST": {
        "type": "object",
        "properties": {
          "metric": {
            "type": [
              "null",
              "string"
            ],
            "description": "The index's metric: Cosine, DotProduct or L2.",
            "example": "Cosine"
          },
          "higherIsBetter": {
            "type": "boolean",
            "description": "Whether a HIGHER score is better (false for L2).",
            "example": true
          },
          "results": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/VectorScoredElementREST"
            },
            "description": "The hits, best first; ties broken by ascending element id."
          }
        },
        "description": "A kNN result: hits best-first plus the metric and its direction, so an L2 distance can\nnever be misread as a similarity."
      },
      "Vertex": {
        "required": [
          "id",
          "creationDate",
          "modificationDate"
        ],
        "type": "object",
        "properties": {
          "outEdges": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "type": "array",
              "items": {
                "pattern": "^-?(?:0|[1-9]\\d*)$",
                "type": [
                  "integer",
                  "string"
                ],
                "format": "int32"
              }
            },
            "description": "Dictionary of outgoing edges grouped by edge property type"
          },
          "inEdges": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "type": "array",
              "items": {
                "pattern": "^-?(?:0|[1-9]\\d*)$",
                "type": [
                  "integer",
                  "string"
                ],
                "format": "int32"
              }
            },
            "description": "Dictionary of incoming edges grouped by edge property type"
          },
          "id": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The unique identifier of the graph element",
            "format": "int32",
            "default": 123,
            "example": 123
          },
          "creationDate": {
            "type": "string",
            "description": "The date and time when the element was created",
            "format": "date-time",
            "example": "2025-04-22T10:00:00Z"
          },
          "modificationDate": {
            "type": "string",
            "description": "The date and time when the element was last modified",
            "format": "date-time",
            "example": "2025-04-22T10:00:00Z"
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "The type label of the graph element used for categorization",
            "default": "person",
            "example": "person"
          },
          "properties": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PropertySpecification"
            },
            "description": "The collection of properties (key-value pairs) associated with the graph element"
          }
        },
        "description": "Represents a vertex (node) in the graph with its properties and connected edges",
        "example": {
          "id": 1,
          "creationDate": "2025-04-22T10:00:00Z",
          "modificationDate": "2025-04-22T10:00:00Z",
          "label": "person",
          "properties": [
            {
              "propertyId": "name",
              "fullQualifiedTypeName": "System.String",
              "propertyValue": "John Doe"
            },
            {
              "propertyId": "age",
              "fullQualifiedTypeName": "System.Int32",
              "propertyValue": "30"
            }
          ],
          "outEdges": {
            "knows": [
              10,
              15
            ]
          },
          "inEdges": {
            "knows": [
              5
            ]
          }
        }
      },
      "VertexSpecification": {
        "required": [
          "creationDate"
        ],
        "type": "object",
        "properties": {
          "creationDate": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "The creation date of the vertex as a Unix timestamp",
            "format": "uint32",
            "default": 0,
            "example": 1713862800
          },
          "label": {
            "type": [
              "null",
              "string"
            ],
            "description": "The label of the vertex used for categorization",
            "example": "person"
          },
          "properties": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/PropertySpecification"
            },
            "description": "The properties of the vertex as key-value pairs"
          }
        },
        "description": "Specification for creating a new vertex in the graph",
        "example": {
          "label": "person",
          "creationDate": 1713862800,
          "properties": [
            {
              "propertyId": "name",
              "propertyValue": "John Doe",
              "fullQualifiedTypeName": "System.String"
            },
            {
              "propertyId": "age",
              "propertyValue": 30,
              "fullQualifiedTypeName": "System.Int32"
            }
          ]
        }
      },
      "WriteBackResultREST": {
        "type": "object",
        "properties": {
          "propertyKey": {
            "type": [
              "null",
              "string"
            ],
            "description": "The property key the values were written under.",
            "example": "analytics.pagerank"
          },
          "verticesWritten": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "How many vertex writes the committed chunks carried. A vertex removed\n    concurrently between the run and its chunk is a silent no-op on the writer yet\n    still counted - the fuzzy-consistency story applies to write-back too.",
            "format": "int32",
            "example": 2500000
          },
          "chunks": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "How many DelegateTransaction chunks carried the write-back (each chunk is\n    atomic; the whole write-back is not - re-run to remedy a mid-way failure).",
            "format": "int32",
            "example": 50
          }
        },
        "description": "The write-back report when the request opted in."
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "description": "The Fallen-8 API key. An \"Authorization: Bearer <key>\" header is accepted as well. Required only on an instance that configures Fallen8:Security:ApiKey - an instance without a key runs unauthenticated.",
        "name": "X-Api-Key",
        "in": "header"
      }
    }
  },
  "security": [
    {
      "ApiKey": [ ]
    }
  ],
  "tags": [
    {
      "name": "Admin"
    },
    {
      "name": "Analytics"
    },
    {
      "name": "Benchmark"
    },
    {
      "name": "Bulk"
    },
    {
      "name": "ChangeFeed"
    },
    {
      "name": "Chat"
    },
    {
      "name": "Delegates"
    },
    {
      "name": "Document"
    },
    {
      "name": "Embedding"
    },
    {
      "name": "Graph"
    },
    {
      "name": "Integrations"
    },
    {
      "name": "Namespaces"
    },
    {
      "name": "Plugins"
    },
    {
      "name": "SampleGraph"
    },
    {
      "name": "SaveGames"
    },
    {
      "name": "Statistics"
    },
    {
      "name": "StoredQueries"
    },
    {
      "name": "SubGraph"
    }
  ]
}