{
  "$defs": {
    "BindingConfiguration": {
      "additionalProperties": false,
      "description": "The `[providers.binding]` table. The binding provider maps references to the\ndefinitions they can name from syntax facts alone; each phase of that work runs\nunder one of these bounds, and a build that breaches a bound keeps the prior\nbinding publication.",
      "properties": {
        "enabled": {
          "default": true,
          "description": "Whether the binding provider runs at all.",
          "type": "boolean"
        },
        "max_graph_links": {
          "default": 500000,
          "description": "Links one publication's graph may hold, at most.",
          "format": "uint64",
          "maximum": 5000000,
          "minimum": 1,
          "type": "integer"
        },
        "max_graph_nodes": {
          "default": 2000000,
          "description": "Scopes, definitions, and references one publication's graph may hold together, at most.",
          "format": "uint64",
          "maximum": 20000000,
          "minimum": 1,
          "type": "integer"
        },
        "max_path_depth": {
          "default": 64,
          "description": "Steps one resolution work item may accumulate, at most.",
          "format": "uint64",
          "maximum": 640,
          "minimum": 1,
          "type": "integer"
        },
        "max_publication_work": {
          "default": 50000000,
          "description": "Work items one publication may enqueue across every reference, at most.",
          "format": "uint64",
          "maximum": 5000000000,
          "minimum": 1,
          "type": "integer"
        },
        "max_reference_targets": {
          "default": 64,
          "description": "Definitions one reference may resolve to, at most.",
          "format": "uint64",
          "maximum": 256,
          "minimum": 1,
          "type": "integer"
        },
        "max_reference_work": {
          "default": 4096,
          "description": "Work items one reference may enqueue during resolution, at most.",
          "format": "uint64",
          "maximum": 409600,
          "minimum": 1,
          "type": "integer"
        },
        "max_unit_definitions": {
          "default": 16384,
          "description": "Definitions one source unit may contribute, at most.",
          "format": "uint64",
          "maximum": 163840,
          "minimum": 1,
          "type": "integer"
        },
        "max_unit_links": {
          "default": 4096,
          "description": "Links one source unit may contribute, at most.",
          "format": "uint64",
          "maximum": 40960,
          "minimum": 1,
          "type": "integer"
        },
        "max_unit_references": {
          "default": 65536,
          "description": "References one source unit may contribute, at most.",
          "format": "uint64",
          "maximum": 655360,
          "minimum": 1,
          "type": "integer"
        },
        "max_unit_scopes": {
          "default": 4096,
          "description": "Scopes one source unit may contribute, at most.",
          "format": "uint64",
          "maximum": 40960,
          "minimum": 1,
          "type": "integer"
        }
      },
      "type": "object"
    },
    "ByteSize": {
      "description": "A byte size: an integer magnitude with a required unit suffix `b`, `kb`, `mb`, `gb`, or `tb`; units are binary, so `1kb` is 1024 bytes.",
      "pattern": "^(?:0|[1-9][0-9]*)(?:b|kb|mb|gb|tb)$",
      "type": "string"
    },
    "ChangedPaths": {
      "description": "Whether the changed project paths ride the hook's command line.",
      "oneOf": [
        {
          "const": "none",
          "description": "The command runs exactly as configured.",
          "type": "string"
        },
        {
          "const": "append",
          "description": "The changed project paths follow the configured command, in byte\norder, for a tool that takes files.",
          "type": "string"
        }
      ]
    },
    "CommandHook": {
      "additionalProperties": false,
      "allOf": [
        {
          "if": {
            "properties": {
              "writes": {
                "const": "changed_paths"
              }
            }
          },
          "then": {
            "properties": {
              "guarantees": {
                "maxItems": 0
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "writes": {
                "const": "workspace"
              }
            }
          },
          "then": {
            "properties": {
              "guarantees": {
                "maxItems": 0
              }
            }
          }
        }
      ],
      "description": "One `[[hooks]]` command the server runs inside the changed tree.",
      "properties": {
        "changed_paths": {
          "$ref": "#/$defs/ChangedPaths",
          "default": "none",
          "description": "Whether the server appends changed project paths after the configured command, in byte order."
        },
        "command": {
          "$ref": "#/$defs/CommandInput",
          "description": "Executable and literal arguments. Rift starts it directly without a shell."
        },
        "determinism": {
          "$ref": "#/$defs/Determinism",
          "description": "Whether an identical tree and environment are expected to reproduce the result."
        },
        "environment": {
          "additionalProperties": {
            "type": "string"
          },
          "default": {},
          "description": "Environment values added to the environment the server inherited.",
          "maxProperties": 64,
          "type": "object"
        },
        "exclude": {
          "default": [],
          "description": "Project-relative path patterns removed from hook selection.",
          "items": {
            "$ref": "#/$defs/PathPattern"
          },
          "maxItems": 64,
          "type": "array"
        },
        "failure_severity": {
          "$ref": "#/$defs/HookFailureSeverity",
          "default": "error",
          "description": "Severity the server reports when the hook does not pass."
        },
        "guarantees": {
          "default": [],
          "description": "What a passing validation establishes. Transform hooks cannot declare guarantees.",
          "items": {
            "$ref": "#/$defs/HookGuarantee"
          },
          "maxItems": 16,
          "type": "array"
        },
        "id": {
          "description": "Label for this hook's results, unique within the list.",
          "maxLength": 64,
          "minLength": 1,
          "pattern": "^[A-Za-z0-9._-]+$",
          "type": "string"
        },
        "include": {
          "default": [],
          "description": "Project-relative path patterns that select this hook. Empty selects every change.",
          "items": {
            "$ref": "#/$defs/PathPattern"
          },
          "maxItems": 64,
          "type": "array"
        },
        "kind": {
          "$ref": "#/$defs/HookKind",
          "description": "What the hook is: a formatter, test suite, linter, build, or another command."
        },
        "output_limit": {
          "$ref": "#/$defs/ByteSize",
          "default": "4kb",
          "description": "Bytes of each output stream the server keeps, 256b to 4kb. The full size is still reported.",
          "rift:range": {
            "max": "4kb",
            "min": "256b"
          }
        },
        "timeout": {
          "$ref": "#/$defs/Duration",
          "default": "2m",
          "description": "Wall-clock bound before the server kills the process, 1ms to 1h.",
          "rift:range": {
            "max": "1h",
            "min": "1ms"
          }
        },
        "working_directory": {
          "$ref": "#/$defs/ProjectPath",
          "default": "",
          "description": "Directory the process starts in, relative to the changed tree's root. Empty selects the\nroot. Absolute paths and `.` or `..` segments are refused."
        },
        "writes": {
          "$ref": "#/$defs/HookWrites",
          "default": "none",
          "description": "Source files the server permits the hook to change."
        }
      },
      "required": [
        "id",
        "kind",
        "command",
        "determinism"
      ],
      "type": "object"
    },
    "CommandInput": {
      "oneOf": [
        {
          "minLength": 1,
          "pattern": "^\\S+$",
          "type": "string"
        },
        {
          "items": {
            "maxLength": 4096,
            "type": "string"
          },
          "maxItems": 65,
          "minItems": 1,
          "prefixItems": [
            {
              "maxLength": 4096,
              "minLength": 1,
              "type": "string"
            }
          ],
          "type": "array"
        }
      ]
    },
    "CoverageReach": {
      "description": "How far the claim reaches.",
      "oneOf": [
        {
          "const": "request",
          "description": "Only what this request touched.",
          "type": "string"
        },
        {
          "const": "project",
          "description": "Every visible file of the workspace.",
          "type": "string"
        },
        {
          "const": "dependencies",
          "description": "The workspace's resolved dependencies.",
          "type": "string"
        },
        {
          "const": "all",
          "description": "The workspace, its dependencies, and the standard library together.",
          "type": "string"
        }
      ]
    },
    "CoverageScope": {
      "description": "What a completeness statement covers - everything the request asked for, one file, or a\nstanding scope the answer holds over.",
      "oneOf": [
        {
          "additionalProperties": false,
          "description": "A standing scope identified by its name.",
          "properties": {
            "kind": {
              "const": "reach",
              "type": "string"
            },
            "reach": {
              "$ref": "#/$defs/CoverageReach",
              "description": "How far the claim reaches."
            }
          },
          "required": [
            "kind",
            "reach"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "A single unit is just a file: the claim holds for that path and says nothing about any other.",
          "properties": {
            "kind": {
              "const": "unit",
              "type": "string"
            },
            "unit": {
              "$ref": "#/$defs/FileId",
              "description": "The file the claim is about."
            }
          },
          "required": [
            "kind",
            "unit"
          ],
          "type": "object"
        }
      ]
    },
    "Determinism": {
      "description": "Whether an identical tree and environment are expected to reproduce a\nhook's result.",
      "oneOf": [
        {
          "const": "deterministic",
          "description": "The same tree and environment give the same answer.",
          "type": "string"
        },
        {
          "const": "best_effort",
          "description": "The result may vary between identical runs.",
          "type": "string"
        }
      ]
    },
    "Duration": {
      "description": "A duration: an integer magnitude with a required unit suffix `ms`, `s`, `m`, `h`, or `d`.",
      "pattern": "^(?:0|[1-9][0-9]*)(?:ms|s|m|h|d)$",
      "type": "string"
    },
    "EmbeddedEngine": {
      "description": "One engine this build links in, served in process without a command.",
      "oneOf": [
        {
          "const": "ty",
          "description": "The ty type checker, serving Python semantics in process.",
          "type": "string"
        }
      ]
    },
    "ExecutionConfiguration": {
      "additionalProperties": false,
      "description": "The `[execution]` table. Exact language entries enable execution; this\ntable owns the workspace-wide bounds.",
      "properties": {
        "max_code": {
          "$ref": "#/$defs/ByteSize",
          "default": "16kb",
          "description": "Bytes one submitted block may hold, 1b to 32kb.",
          "rift:range": {
            "max": "32kb",
            "min": "1b"
          }
        },
        "max_concurrent": {
          "default": 2,
          "description": "Evaluations running at once across the whole workspace.",
          "format": "uint64",
          "maximum": 64,
          "minimum": 1,
          "type": "integer"
        },
        "max_output": {
          "$ref": "#/$defs/ByteSize",
          "default": "8kb",
          "description": "Bytes each captured stream keeps, up to 16kb.",
          "rift:range": {
            "max": "16kb",
            "min": "0b"
          }
        },
        "max_timeout": {
          "$ref": "#/$defs/Duration",
          "default": "30s",
          "description": "Wall-clock bound per evaluation, 1ms to 1d.",
          "rift:range": {
            "max": "1d",
            "min": "1ms"
          }
        }
      },
      "type": "object"
    },
    "FileId": {
      "description": "Identity of one file in the tree a request targets. The path after `rift://file/` is a\n`ProjectPath` in canonical percent-encoding. The server re-validates the decoded path\nwherever a `FileId` arrives, so the `ProjectPath` exclusions hold for every consumer,\nwhatever schema its implementation generated from.",
      "examples": [
        "rift://file/src/lib.rs"
      ],
      "maxLength": 8192,
      "minLength": 13,
      "pattern": "^rift://file/(?:[A-Za-z0-9._~!$&'()*+,;=:@/-]|%[0-9A-F]{2}){1,1000}$",
      "type": "string"
    },
    "GuaranteeKind": {
      "description": "A property a verifier can establish about an applied change.",
      "oneOf": [
        {
          "const": "syntax_validated",
          "description": "The changed source parses.",
          "type": "string"
        },
        {
          "const": "bindings_preserved",
          "description": "Names still resolve to what they resolved to before the change.",
          "type": "string"
        },
        {
          "const": "references_updated",
          "description": "References to the changed declarations were updated with them.",
          "type": "string"
        },
        {
          "const": "behavior_checked",
          "description": "The change's behavior was exercised, such as by a test suite.",
          "type": "string"
        }
      ]
    },
    "HistoryConfiguration": {
      "additionalProperties": false,
      "description": "The `[providers.history]` table. The history provider's cost scales with\nhow far back it walks, so its depth is the budget worth setting.",
      "properties": {
        "enabled": {
          "default": true,
          "description": "Whether the history provider runs at all.",
          "type": "boolean"
        },
        "max_revisions": {
          "default": 500,
          "description": "Revisions the walk covers from the current head, newest first.",
          "format": "uint64",
          "maximum": 100000,
          "minimum": 1,
          "type": "integer"
        }
      },
      "type": "object"
    },
    "HookFailureSeverity": {
      "description": "Severity the server reports when a hook does not pass.",
      "oneOf": [
        {
          "const": "warning",
          "description": "The hook result reports a warning.",
          "type": "string"
        },
        {
          "const": "error",
          "description": "The hook result reports an error.",
          "type": "string"
        }
      ]
    },
    "HookGuarantee": {
      "additionalProperties": false,
      "description": "What a passing run of one hook establishes about the change it checked.",
      "properties": {
        "detail": {
          "description": "The exact property the hook checks, and the limits on reading a pass.",
          "maxLength": 1024,
          "minLength": 1,
          "type": "string"
        },
        "kind": {
          "$ref": "#/$defs/GuaranteeKind",
          "description": "Which property a pass establishes."
        },
        "scope": {
          "$ref": "#/$defs/CoverageScope",
          "description": "What the check covers."
        }
      },
      "required": [
        "kind",
        "scope",
        "detail"
      ],
      "type": "object"
    },
    "HookKind": {
      "description": "What a hook is, as workspace configuration presents it.",
      "oneOf": [
        {
          "const": "format",
          "description": "A source formatter.",
          "type": "string"
        },
        {
          "const": "test",
          "description": "A test suite.",
          "type": "string"
        },
        {
          "const": "lint",
          "description": "A linter.",
          "type": "string"
        },
        {
          "const": "build",
          "description": "A build.",
          "type": "string"
        },
        {
          "const": "other",
          "description": "A hook none of the other kinds describe.",
          "type": "string"
        }
      ]
    },
    "HookWrites": {
      "description": "Source writes the server may retain from one hook.",
      "oneOf": [
        {
          "const": "none",
          "description": "A validation hook that may not change source files.",
          "type": "string"
        },
        {
          "const": "changed_paths",
          "description": "A transform hook that may change only paths changed before hooks ran.",
          "type": "string"
        },
        {
          "const": "workspace",
          "description": "A transform hook that may change any source file in the workspace.",
          "type": "string"
        }
      ]
    },
    "LanguageConfiguration": {
      "additionalProperties": false,
      "description": "One exact `[languages.<identity>]` entry.",
      "properties": {
        "enabled": {
          "default": true,
          "description": "Whether syntax, LSP service, and execution are enabled for matched paths.",
          "type": "boolean"
        },
        "exclude": {
          "default": [],
          "description": "Path patterns removed from this language's effective matches.",
          "items": {
            "$ref": "#/$defs/PathPattern"
          },
          "maxItems": 64,
          "type": "array"
        },
        "execution": {
          "default": false,
          "description": "Whether caller-provided code may execute under this exact language.",
          "type": "boolean"
        },
        "include": {
          "default": null,
          "description": "Replacement path patterns. Absence keeps shipped patterns; an empty list matches none.",
          "items": {
            "$ref": "#/$defs/PathPattern"
          },
          "maxItems": 64,
          "type": [
            "array",
            "null"
          ]
        },
        "lsp": {
          "anyOf": [
            {
              "$ref": "#/$defs/LanguageLspConfiguration"
            },
            {
              "type": "null"
            }
          ],
          "description": "Inline LSP process or name of one shared process."
        }
      },
      "type": "object"
    },
    "LanguageLspConfiguration": {
      "anyOf": [
        {
          "description": "Name of one shared top-level `[lsp.<name>]` process.",
          "type": "string"
        },
        {
          "$ref": "#/$defs/LspConfiguration",
          "description": "Process used only by this exact language entry."
        }
      ],
      "description": "How one exact language selects an LSP process."
    },
    "LexicalSearchConfiguration": {
      "additionalProperties": false,
      "description": "The `[search.lexical]` table: what the lexical ranking contributes to a\nfused score.",
      "properties": {
        "weight": {
          "default": 0.7,
          "description": "The lexical ranking's share of a fused score, 0.0 to 1.0. It and\n`[search.semantic].weight` must sum to 1: a fused score is the weighted\naverage of the two rankings, and a pair summing to anything else scales\nevery score rather than trading one ranking against the other.",
          "format": "double",
          "maximum": 1.0,
          "minimum": 0.0,
          "type": "number"
        }
      },
      "type": "object"
    },
    "LogsConfiguration": {
      "additionalProperties": false,
      "description": "The `[logs]` table. The server records its own diagnostics in the workspace\ndatabase, where `rift://logs` reads them back, and this table bounds how\nmany records the store keeps, how many one read returns, and which targets\nare captured at all. The server reads the table at startup, so a change\napplies on the next start.",
      "properties": {
        "capture": {
          "default": "rift=info,rift_mcp=info,rift_server=info",
          "description": "Which targets are recorded, in the `RUST_LOG` spelling `tracing` takes:\ncomma-separated `target=level` pairs. A target this filter excludes\nnever reaches the store, whatever the stderr diagnostics carry.",
          "maxLength": 512,
          "type": "string"
        },
        "page_records": {
          "default": 500,
          "description": "Records one `rift://logs` read returns at most, 1 to 5000.",
          "format": "uint64",
          "maximum": 5000,
          "minimum": 1,
          "type": "integer"
        },
        "retention_records": {
          "default": 50000,
          "description": "Records the store keeps before the oldest are dropped, 100 to 1000000.",
          "format": "uint64",
          "maximum": 1000000,
          "minimum": 100,
          "type": "integer"
        }
      },
      "type": "object"
    },
    "LspConfiguration": {
      "additionalProperties": false,
      "allOf": [
        {
          "oneOf": [
            {
              "required": [
                "command"
              ]
            },
            {
              "required": [
                "embedded"
              ]
            }
          ]
        }
      ],
      "description": "One external LSP process Rift may start.",
      "properties": {
        "command": {
          "anyOf": [
            {
              "$ref": "#/$defs/CommandInput"
            },
            {
              "type": "null"
            }
          ],
          "description": "Executable and literal arguments. Rift starts it directly without a\nshell. Exactly one of `command` and `embedded` is present."
        },
        "embedded": {
          "anyOf": [
            {
              "$ref": "#/$defs/EmbeddedEngine"
            },
            {
              "type": "null"
            }
          ],
          "description": "Engine linked into the server, run in process in place of a spawned\ncommand. Exactly one of `command` and `embedded` is present, and an\nembedded engine takes no `environment` and no\n`initialization_options`."
        },
        "environment": {
          "additionalProperties": {
            "type": "string"
          },
          "default": {},
          "description": "Environment values added on top of the environment the server\ninherited.",
          "maxProperties": 64,
          "type": "object"
        },
        "initialization_options": {
          "description": "Options handed to the process at initialize. Must be a JSON object\nwhen present; the LSP server defines its meaning.",
          "type": "object"
        },
        "output_limit": {
          "$ref": "#/$defs/ByteSize",
          "default": "4kb",
          "description": "Bytes of the process's standard error Rift keeps, 1kb to 8mb. The\nfull size is still reported.",
          "rift:range": {
            "max": "8mb",
            "min": "1kb"
          }
        },
        "request_timeout": {
          "$ref": "#/$defs/Duration",
          "default": "1m",
          "description": "Wall-clock bound on each later LSP request, 1s to 10m.",
          "rift:range": {
            "max": "10m",
            "min": "1s"
          }
        },
        "restart": {
          "$ref": "#/$defs/RestartPolicy",
          "default": {
            "attempts": 3,
            "window": "5m"
          },
          "description": "How often Rift replaces this process on its own, and over what\nwindow; the budget spent, the process's own failure surfaces."
        },
        "retry": {
          "$ref": "#/$defs/RetryPolicy",
          "default": {
            "attempts": 8,
            "delay": "250ms",
            "delay_limit": "2s"
          },
          "description": "How often Rift sends this process the same request again while its\nanswer stays unsettled - a refusal the process invites again, or an\nanswer it gave while still analyzing - and how the waits between\nthose attempts grow."
        },
        "startup_timeout": {
          "$ref": "#/$defs/Duration",
          "default": "30s",
          "description": "Wall-clock bound on the process's initialize handshake, 1s to 10m.",
          "rift:range": {
            "max": "10m",
            "min": "1s"
          }
        }
      },
      "type": "object"
    },
    "PathPattern": {
      "description": "Project-relative glob using *, ?, **, and character classes. Forward-slash separated on\nevery platform, whatever separator the host OS uses natively.",
      "examples": [
        "src/**"
      ],
      "pattern": "^(?!/)(?!\\.\\.?(/|$))(?!.*(/\\.\\.?)(/|$))[^\\\\\\u0000-\\u001F\\u007F]+$",
      "type": "string"
    },
    "PortRange": {
      "additionalProperties": false,
      "description": "The `server.port_range` table: the inclusive loopback range the server\npicks the first free port from.",
      "properties": {
        "max": {
          "description": "The highest port the server may bind, at or above `min`.",
          "format": "uint16",
          "maximum": 65535,
          "minimum": 1024,
          "type": "integer"
        },
        "min": {
          "description": "The lowest port the server may bind, 1024 or above.",
          "format": "uint16",
          "maximum": 65535,
          "minimum": 1024,
          "type": "integer"
        }
      },
      "required": [
        "min",
        "max"
      ],
      "type": "object"
    },
    "ProjectPath": {
      "description": "One path below the workspace root, using forward slashes and UTF-8 in Unicode NFC - Rift\nnormalizes what it emits and what it accepts, and compares byte-for-byte. The empty path\nnames the root itself. Absolute paths, backslashes, control characters, empty segments,\nand `.` or `..` segments are refused before the filesystem is touched. The limit is 1000\nUTF-8 bytes, not characters. A workspace holding two entries whose NFC forms are equal\nfails the read that touches them with `content_unavailable`.",
      "examples": [
        "src/lib.rs"
      ],
      "maxLength": 1000,
      "pattern": "^(?:$|(?!\\.rift(?:/|$))(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*//)[^\\\\\\u0000-\\u001F\\u007F/]+(?:/[^\\\\\\u0000-\\u001F\\u007F/]+)*)$",
      "type": "string"
    },
    "ProvidersConfiguration": {
      "additionalProperties": false,
      "description": "The `[providers]` table: the built-in providers run without\nconfiguration, and this table bounds or disables them.",
      "properties": {
        "binding": {
          "$ref": "#/$defs/BindingConfiguration",
          "default": {
            "enabled": true,
            "max_graph_links": 500000,
            "max_graph_nodes": 2000000,
            "max_path_depth": 64,
            "max_publication_work": 50000000,
            "max_reference_targets": 64,
            "max_reference_work": 4096,
            "max_unit_definitions": 16384,
            "max_unit_links": 4096,
            "max_unit_references": 65536,
            "max_unit_scopes": 4096
          },
          "description": "The binding provider's switch and bounds."
        },
        "history": {
          "$ref": "#/$defs/HistoryConfiguration",
          "default": {
            "enabled": true,
            "max_revisions": 500
          },
          "description": "The history provider's budget."
        }
      },
      "type": "object"
    },
    "RestartPolicy": {
      "additionalProperties": false,
      "description": "How often Rift may replace one language engine on its own, and over\nwhat window.\n\nA restart is any start after the first: the first is the start, and\nevery start that follows it replaces an engine that ended, failed to\nstart, or stopped answering. A restart older than `window` no longer\ncounts, so a workspace whose engine dies once a day keeps its full\nbudget while a crash-looping one spends it and stops.",
      "properties": {
        "attempts": {
          "default": 3,
          "description": "Restarts allowed inside one window, 0 to 16. Zero never restarts.",
          "format": "uint64",
          "maximum": 16,
          "minimum": 0,
          "type": "integer"
        },
        "window": {
          "$ref": "#/$defs/Duration",
          "default": "5m",
          "description": "Span the restarts are counted over, 1s to 1d.",
          "rift:range": {
            "max": "1d",
            "min": "1s"
          }
        }
      },
      "type": "object"
    },
    "RetryPolicy": {
      "additionalProperties": false,
      "description": "How often one unsettled operation is attempted again, and how the\nwaits between attempts grow.\n\nAttempts are numbered from one and the first is counted, so\n`attempts = 1` never resends. Each wait is twice the one before it,\nheld at `delay_limit`; a `delay_limit` below `delay` therefore holds\nevery wait at `delay_limit`.\n\nThe waits carry no jitter. Jitter spreads a set of independent retriers\napart so they stop arriving together; requests to one language engine\nserialize on that engine's own slot, so there is never such a set, and\nthe sequence stays a function of the attempt number alone.",
      "properties": {
        "attempts": {
          "default": 8,
          "description": "Attempts one operation takes, the first counted, 1 to 64.",
          "format": "uint64",
          "maximum": 64,
          "minimum": 1,
          "type": "integer"
        },
        "delay": {
          "$ref": "#/$defs/Duration",
          "default": "250ms",
          "description": "Wait before the second attempt, 1ms to 1m. Every later wait\ndoubles the one before it.",
          "rift:range": {
            "max": "1m",
            "min": "1ms"
          }
        },
        "delay_limit": {
          "$ref": "#/$defs/Duration",
          "default": "2s",
          "description": "Longest wait between two attempts, 1ms to 10m.",
          "rift:range": {
            "max": "10m",
            "min": "1ms"
          }
        }
      },
      "type": "object"
    },
    "SearchConfiguration": {
      "additionalProperties": false,
      "description": "The `[search]` table. Search fuses a lexical ranking with a semantic one:\n`lexical` and `semantic` weigh the two against each other, `fusion_k` sets\nhow sharply a top rank counts, `pool_slots` and `busy_timeout` bound the\nshared `SQLite` connections behind search and logs, and `text` bounds\nlexical chunks derived from visible text files.",
      "properties": {
        "busy_timeout": {
          "$ref": "#/$defs/Duration",
          "default": "5s",
          "description": "Wall-clock budget one connection waits for a database lock held by\nanother process before `SQLITE_BUSY`, 100ms to 30s.",
          "rift:range": {
            "max": "30s",
            "min": "100ms"
          }
        },
        "fusion_k": {
          "default": 60,
          "description": "The reciprocal-rank fusion constant, 1 to 1000. A result scores as the\nweighted sum of `1 / (k + rank)` over the rankings that returned it, so\na larger value flattens the contribution curve and lets agreement\nbetween the two rankings outweigh one ranking's top position.",
          "format": "uint64",
          "maximum": 1000,
          "minimum": 1,
          "type": "integer"
        },
        "lexical": {
          "$ref": "#/$defs/LexicalSearchConfiguration",
          "default": {
            "weight": 0.7
          },
          "description": "The lexical ranking's share of a fused score."
        },
        "pool_slots": {
          "default": 4,
          "description": "Pooled `SQLite` connections the workspace database may open at once,\n1 to 16. Search reads and stored logs share this pool.",
          "format": "uint64",
          "maximum": 16,
          "minimum": 1,
          "type": "integer"
        },
        "semantic": {
          "$ref": "#/$defs/SemanticSearchConfiguration",
          "default": {
            "batch_declarations": 32,
            "candidates": 200,
            "candidates_per_file": 3,
            "disabled": false,
            "download_attempts": 3,
            "download_timeout": "5m",
            "max_tokens": 256,
            "max_vectors": 200000,
            "model": "minishlab/potion-retrieval-32M",
            "source": "hf",
            "weight": 0.3
          },
          "description": "The embedding model that adds semantic ranking, and the bounds its\npreparation runs under."
        },
        "text": {
          "$ref": "#/$defs/TextSearchConfiguration",
          "default": {
            "include": [
              "**"
            ],
            "max_chunk": "1mb"
          },
          "description": "Chunking policy for visible text files in lexical search."
        }
      },
      "type": "object"
    },
    "SemanticSearchConfiguration": {
      "additionalProperties": false,
      "description": "The `[search.semantic]` table: the embedding model that ranks a query\nagainst code sharing no word with it, and the bounds its preparation runs\nunder.\n\nPreparation runs behind the answers. A search issued before the vectors are\nin is answered lexically and carries a warning naming what is still\nmissing.",
      "properties": {
        "batch_declarations": {
          "default": 32,
          "description": "Declarations one embedding pass hands the encoder at once, 1 to 256.\nAttention memory grows with the square of `max_tokens`, so a raised\ntoken window wants a lowered batch.",
          "format": "uint64",
          "maximum": 256,
          "minimum": 1,
          "type": "integer"
        },
        "candidates": {
          "default": 200,
          "description": "Declarations the semantic ranking returns before the two rankings are\nfused, 1 to 1000.",
          "format": "uint64",
          "maximum": 1000,
          "minimum": 1,
          "type": "integer"
        },
        "candidates_per_file": {
          "default": 3,
          "description": "Declarations one file may contribute to the semantic ranking before\nthe rest of its declarations are dropped, 1 to 64. Without the bound\none file whose declarations all rank well fills `candidates` on its\nown, and no other file reaches the candidate list however well it\nwould have ranked.",
          "format": "uint64",
          "maximum": 64,
          "minimum": 1,
          "type": "integer"
        },
        "disabled": {
          "default": false,
          "description": "Whether semantic ranking is off. Set it when the workspace must not\nfetch model weights: search then answers lexically alone and raises no\npreparation warning.",
          "type": "boolean"
        },
        "download_attempts": {
          "default": 3,
          "description": "Attempts one model download makes before semantic ranking degrades to\nlexical for the life of the server, 1 to 10.",
          "format": "uint64",
          "maximum": 10,
          "minimum": 1,
          "type": "integer"
        },
        "download_timeout": {
          "$ref": "#/$defs/Duration",
          "default": "5m",
          "description": "Wall-clock budget one model download has, 10s to 1h.",
          "rift:range": {
            "max": "1h",
            "min": "10s"
          }
        },
        "max_tokens": {
          "default": 256,
          "description": "Tokens the encoder reads from one declaration, 32 to 512. What follows\nthem is truncated.",
          "format": "uint64",
          "maximum": 512,
          "minimum": 32,
          "type": "integer"
        },
        "max_vectors": {
          "default": 200000,
          "description": "Vectors the workspace may hold, 1000 to 1000000. Embedding stops at the\nbound and the search warning says so; each vector costs the model's\ndimension in single-precision floats.",
          "format": "uint64",
          "maximum": 1000000,
          "minimum": 1000,
          "type": "integer"
        },
        "model": {
          "default": "minishlab/potion-retrieval-32M",
          "description": "Which weights: under `hf` a repository identifier such as\n`minishlab/potion-retrieval-32M`, optionally carrying a revision after\n`@`; under `directory` a workspace-relative directory holding them.\nVectors are stored per model, so changing the value embeds the\nworkspace again.\n\nThe model's own `config.json` decides how it is read. A `model_type` of\n`model2vec` is a static model, which embeds a declaration by averaging\none row per token; anything else is read as a BERT checkpoint, which\nruns a forward pass per batch and costs minutes rather than seconds\nover a whole workspace.",
          "maxLength": 128,
          "minLength": 1,
          "type": "string"
        },
        "source": {
          "$ref": "#/$defs/SemanticSource",
          "default": "hf",
          "description": "Where the weights come from, which decides how `model` reads."
        },
        "weight": {
          "default": 0.3,
          "description": "The semantic ranking's share of a fused score, 0.0 to 1.0. It and\n`[search.lexical].weight` must sum to 1.",
          "format": "double",
          "maximum": 1.0,
          "minimum": 0.0,
          "type": "number"
        }
      },
      "type": "object"
    },
    "SemanticSource": {
      "description": "Where the semantic ranking's model weights come from.",
      "oneOf": [
        {
          "const": "hf",
          "description": "Weights come from a Hugging Face repository, cached where every\nother Hugging Face client on the machine caches them.",
          "type": "string"
        },
        {
          "const": "directory",
          "description": "Weights are a directory the workspace already holds. Nothing is\ndownloaded.",
          "type": "string"
        }
      ]
    },
    "ServerConfiguration": {
      "additionalProperties": false,
      "allOf": [
        {
          "description": "server.port and server.port_range are mutually exclusive",
          "not": {
            "required": [
              "port",
              "port_range"
            ]
          }
        }
      ],
      "description": "The `[server]` table. Filesystem scans and parses run on a bounded\nworker pool; this table sets the worker count, bounds the queue wait,\nsets how long the server serves with no request before it stops, and\nselects the loopback port. The server reads the table at startup, so a\nchange applies on the next start.",
      "properties": {
        "idle_timeout": {
          "$ref": "#/$defs/Duration",
          "default": "30m",
          "description": "Wall-clock span after the last served request completes that stops\nthe server while no request remains active, 1s to 1d.",
          "rift:range": {
            "max": "1d",
            "min": "1s"
          }
        },
        "num_workers": {
          "default": 4,
          "description": "Workers running blocking filesystem and parser operations at once, 1 to 64.",
          "format": "uint64",
          "maximum": 64,
          "minimum": 1,
          "type": "integer"
        },
        "port": {
          "default": null,
          "description": "The exact loopback port the server binds, 1024 or above. Excludes\n`port_range`; omitted, the server picks from `port_range` or the\ndefault serving range.",
          "format": "uint16",
          "maximum": 65535,
          "minimum": 1024,
          "type": [
            "integer",
            "null"
          ]
        },
        "port_range": {
          "anyOf": [
            {
              "$ref": "#/$defs/PortRange"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "The loopback range the server picks its port from. Excludes `port`;\nomitted, the default serving range applies."
        },
        "readiness_timeout": {
          "$ref": "#/$defs/Duration",
          "default": "30s",
          "description": "Wall-clock bound one request waits for the workspace's index and\nits language services to prove they are ready to answer, 1s to 1h.\nOne deadline: index validation starts it, and once a request\nresolves the languages it needs, waiting on those services spends\nwhat remains of it.",
          "rift:range": {
            "max": "1h",
            "min": "1s"
          }
        },
        "worker_queue_timeout": {
          "$ref": "#/$defs/Duration",
          "default": "30s",
          "description": "Wall-clock bound one request waits for a free worker, 1ms to 1h.",
          "rift:range": {
            "max": "1h",
            "min": "1ms"
          }
        }
      },
      "type": "object"
    },
    "SourceConfiguration": {
      "additionalProperties": false,
      "description": "The `[source]` table: which files below the workspace root the index and reads consider\nvisible. `.git`, `.rift`, and `target` stay invisible whatever this table says.",
      "properties": {
        "exclude": {
          "default": [],
          "description": "Exact file paths or globs dropped from visibility, in [`PathPattern`] syntax. A match\nhere is dropped even when `include` also matches it.",
          "items": {
            "$ref": "#/$defs/PathPattern"
          },
          "maxItems": 512,
          "type": "array"
        },
        "include": {
          "default": [],
          "description": "Exact file paths or globs a file must match to stay visible, in [`PathPattern`] syntax.\nEmpty includes every file `exclude` and `.gitignore` leave standing.",
          "items": {
            "$ref": "#/$defs/PathPattern"
          },
          "maxItems": 512,
          "type": "array"
        },
        "respect_gitignore": {
          "default": true,
          "description": "Whether the workspace's own `.gitignore` files, root and nested, hide the paths they\nmatch. Global and parent-directory gitignore sources are never read.",
          "type": "boolean"
        }
      },
      "type": "object"
    },
    "TextSearchConfiguration": {
      "additionalProperties": false,
      "description": "The `[search.text]` table. `include` selects which visible paths join the\ntext index once every language entry has had its claim, and `max_chunk`\nbounds the lexical units derived from them.",
      "properties": {
        "include": {
          "default": [
            "**"
          ],
          "description": "Project-relative path patterns included as plain text when no language claims them.\nThe default `[\"**\"]` selects every unclaimed visible path; an empty list selects none.",
          "items": {
            "$ref": "#/$defs/PathPattern"
          },
          "maxItems": 64,
          "type": "array"
        },
        "max_chunk": {
          "$ref": "#/$defs/ByteSize",
          "default": "1mb",
          "description": "Bytes one lexical chunk may hold, 1kb to 16mb. Larger files are indexed as\nseveral chunks of at most this size.",
          "rift:range": {
            "max": "16mb",
            "min": "1kb"
          }
        }
      },
      "type": "object"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "description": "The whole `rift.toml`. Every table is optional and defaults to the\nbehavior documented on it; any key outside these definitions refuses the\nfile as `configuration_invalid`.",
  "properties": {
    "execution": {
      "$ref": "#/$defs/ExecutionConfiguration",
      "default": {
        "max_code": "16kb",
        "max_concurrent": 2,
        "max_output": "8kb",
        "max_timeout": "30s"
      },
      "description": "Enablement and limits for caller-provided code."
    },
    "hooks": {
      "default": [],
      "description": "Hooks run in the changed tree, in list order, each time a change\napplies.",
      "items": {
        "$ref": "#/$defs/CommandHook"
      },
      "maxItems": 32,
      "type": "array"
    },
    "languages": {
      "additionalProperties": {
        "$ref": "#/$defs/LanguageConfiguration"
      },
      "default": {},
      "description": "Exact language entries keyed by their `name` or `name:dialect` identity segment.",
      "maxProperties": 64,
      "propertyNames": {
        "pattern": "^[a-z][a-z0-9._-]*(?::[a-z][a-z0-9._-]*)?$"
      },
      "type": "object"
    },
    "logs": {
      "$ref": "#/$defs/LogsConfiguration",
      "default": {
        "capture": "rift=info,rift_mcp=info,rift_server=info",
        "page_records": 500,
        "retention_records": 50000
      },
      "description": "The server's own log records: how many the workspace database keeps,\nhow many one read returns, and which targets are captured."
    },
    "lsp": {
      "additionalProperties": {
        "$ref": "#/$defs/LspConfiguration"
      },
      "default": {},
      "description": "Shared LSP processes keyed by name. Language entries select them explicitly.",
      "maxProperties": 16,
      "propertyNames": {
        "pattern": "^[a-z][a-z0-9._-]*$"
      },
      "type": "object"
    },
    "providers": {
      "$ref": "#/$defs/ProvidersConfiguration",
      "default": {
        "binding": {
          "enabled": true,
          "max_graph_links": 500000,
          "max_graph_nodes": 2000000,
          "max_path_depth": 64,
          "max_publication_work": 50000000,
          "max_reference_targets": 64,
          "max_reference_work": 4096,
          "max_unit_definitions": 16384,
          "max_unit_links": 4096,
          "max_unit_references": 65536,
          "max_unit_scopes": 4096
        },
        "history": {
          "enabled": true,
          "max_revisions": 500
        }
      },
      "description": "Bounds and switches for the built-in providers."
    },
    "search": {
      "$ref": "#/$defs/SearchConfiguration",
      "default": {
        "busy_timeout": "5s",
        "fusion_k": 60,
        "lexical": {
          "weight": 0.7
        },
        "pool_slots": 4,
        "semantic": {
          "batch_declarations": 32,
          "candidates": 200,
          "candidates_per_file": 3,
          "disabled": false,
          "download_attempts": 3,
          "download_timeout": "5m",
          "max_tokens": 256,
          "max_vectors": 200000,
          "model": "minishlab/potion-retrieval-32M",
          "source": "hf",
          "weight": 0.3
        },
        "text": {
          "include": [
            "**"
          ],
          "max_chunk": "1mb"
        }
      },
      "description": "Search ranking, visible text chunking, and storage bounds."
    },
    "server": {
      "$ref": "#/$defs/ServerConfiguration",
      "default": {
        "idle_timeout": "30m",
        "num_workers": 4,
        "port": null,
        "port_range": null,
        "readiness_timeout": "30s",
        "worker_queue_timeout": "30s"
      },
      "description": "The server's own blocking-work bounds: worker count and queue wait."
    },
    "source": {
      "$ref": "#/$defs/SourceConfiguration",
      "default": {
        "exclude": [],
        "include": [],
        "respect_gitignore": true
      },
      "description": "Which files below the workspace root the index and reads consider visible."
    }
  },
  "title": "WorkspaceConfiguration",
  "type": "object"
}
