ablative docs
↑↓ move↵ openesc close
Stack Notebook ablative.com.au

Configuration

Every service, door and HTTP MCP setting, with its type, default, limit and refusal.

Open .md

Reading a configuration

These fields come from the service configuration in serve/cli.rs, the door configuration in door/config.rs and the HTTP policy in mcp/http/config.rs at main commit 84b9497a. Query, embedding and retention limits are resolved by their own settings structs before the store opens. No Cargo command is needed to read or use these files.

JSON numbers must be whole numbers of the stated type. A positive integer excludes zero. A platform-sized integer fits usize, which is 64 bits on the Mac used for these examples. An unsigned 64-bit integer ends at 18446744073709551615. A wrong type, negative number, fraction or overflow is a decode refusal. Optional does not mean that null is accepted unless the field says so.

There is no service configuration check subcommand. serve validates and then opens the store. door reads its credential and discovery document before listening. mcp-http validates its HTTP policy before binding. Do not use a running production store to experiment with settings.

The service file

{
  "data_dir": "/var/lib/haematite/ward",
  "socket": "/run/haematite/ward.sock",
  "branch_cache_bytes_per_shard": 67108864,
  "max_frame": 4194304,
  "max_clients": 32,
  "max_page": 500,
  "timeout_ms": 30000,
  "create": {
    "shards": 4,
    "cache_bytes_total": 268435456,
    "executor_threads": 4
  },
  "query_worker": "/opt/haematite/ward-bundle/bin/haematite-jq",
  "query_time_ms": 30000,
  "query_memory_bytes": 67108864,
  "query_outputs_per_record": 10000,
  "query_scan_records": 10000,
  "query_max_running": 2
}

The query worker path must name an installed haematite-jq. Change the data and socket paths to paths owned by the service user. Create the socket parent with mode 0700 before starting. The data directory is created by serve --create; leave --create off when opening an existing store.

data_dir
Required absolute path. Creation needs an existing parent and a new final directory. A relative path is refused as data_dir and socket must be absolute paths; resolution failures are invalid_data_dir.
socket
Optional absolute socket path or null. Omission resolves the store name in the private OS runtime directory. Its parent must exist, belong to this user and have mode 0700. invalid_socket, invalid_runtime_location and endpoint_too_long name invalid paths, ownership and length.
name
Optional string or null. Defaults to the canonical data directory basename. From 1 to 128 UTF-8 bytes, excluding /, backslash, NUL, . and ... Otherwise invalid_store_name. A name already owned by another service is refused.
branch_cache_bytes_per_shard
Required positive platform-sized integer. Bytes of node cache for each opened branch shard. Zero, null, a fraction, a negative number or overflow is a service config decode refusal.
max_frame
Required integer from 1 to 4294967295. Maximum transport frame bytes, negotiated with each client. A frame too small for hello or receipts can prevent useful calls. Invalid numbers are service config decode refusals.
max_clients
Required positive platform-sized integer. Maximum simultaneous store clients. Invalid numbers are service config decode refusals; the running service refuses excess admissions.
max_page
Required integer from 1 to 4294967295. Maximum ordinary page rows. Requests above it are page_limit. Invalid numbers are service config decode refusals.
timeout_ms
Required integer from 1 to 18446744073709551615. Bounds each frame exchange in milliseconds. Zero is a decode refusal. A duration outside the monotonic clock is refused as timeout cannot be represented by the monotonic clock.
create
Optional object or null, needed by serve --create only. Its three fields are required positive platform-sized integers: shards, cache_bytes_total and executor_threads. They set shard count, total node cache bytes and executor threads. Unknown fields or invalid numbers are service config decode refusals. Omission with --create is refused as --create needs a create section in the configuration.
append_prune_keep_ceiling
Integer from 1 to 4294967295, default 4096. Highest keep value accepted by document.append_prune. Zero is append_prune_keep_ceiling_zero; a request above it is append_prune_keep_limit.
append_prune_removal_cap
Integer from 1 to 4294967295, default 64. Maximum records removed by one append and prune. Zero is append_prune_removal_cap_zero. The setting is independent of max_page.
changes_scan_records
Positive u64, default 10000. Maximum changes examined per changes.list page, including denied rows. One is refused as changes_scan_records must be at least 2; zero is a decode refusal.
changes_node_budget
Positive platform-sized integer, default 65536. Tree nodes one shard diff may load per changes.list call. Zero or overflow is a decode refusal. Exhaustion during a read is changes_node_budget.
changes_max_page
Integer from 1 to 4294967295, default 1000. Maximum requested changes.list rows, independent of max_page. An excessive request is page_limit.
kept_versions
Integer from 1 to 4096, default 64. Previous heads held directly by each branch record. Older retained versions have history rows; this setting alone does not release them. Values outside the range name kept_versions in the decode refusal.
retention
Optional object, default the release settings below. Null is not an object. Unknown fields are refused.
lys
Optional object or null. Omission leaves a private owner-only socket service without Lys decisions. Fields below configure verification and placement, never grants.
mcp_http
Optional object or null. It is consumed by the separate mcp-http command, which requires it explicitly. serve does not start HTTP or validate its listener policy. Its fields are listed below.

The service decodes mcp_http as part of the file, including its field types and unknown-field checks. Its address, origins and path are validated by mcp-http, rather than by serve.

Queries

Omit all six query fields to disable query execution. If any is present, all six are required. Missing members are listed as missing query settings. An explicit null is refused as query setting followed by the field and the decode reason.

query_worker
Required with the other five query settings. Absolute path string to haematite-jq. A relative value is query setting query_worker must be an absolute path. Missing, non-file or non-executable workers produce a named query_worker refusal at the startup probe.
query_time_ms
Required with the query group. Positive u64 milliseconds within the monotonic clock. Zero is query setting query_time_ms must be positive; overflow of the clock names its range. Runtime exhaustion is query_time_limit.
query_memory_bytes
Required with the query group. Positive u64 worker memory bytes. Zero is query setting query_memory_bytes must be positive. Runtime exhaustion is query_memory_limit.
query_outputs_per_record
Required with the query group. Positive u64 maximum outputs per source record. Zero names the setting; runtime exhaustion is query_output_limit.
query_scan_records
Required with the query group. u64 from 2 upward. Zero names positivity; one is refused because every page must move beyond the record it rereads. Runtime exhaustion is query_scan_limit.
query_max_running
Required with the query group. Positive u64 fitting a platform-sized count. Zero names positivity; platform overflow names query_max_running. Excess concurrent queries are query_busy.

A startup probe checks the worker exchange. A failed probe leaves other store verbs available and retains the named failure for queries. An executable path by itself is not proof of a usable worker. Read the startup diagnostic and run a query.

Embedding

Omit the fourteen required embedding fields to disable embedding. Supplying any required member, a window setting or embed_writer_wait_ms requires the full group. A missing group is listed as missing embed settings. The restart settings and question-worker switch have their own defaults.

embed_worker
Required in the embedding group. Absolute worker path string. A relative path names embed_worker; absent or non-executable files produce embed_worker_missing, embed_worker_not_file or embed_worker_not_executable.
embed_model_dir
Required absolute model folder string. A relative value is embed_limits: model_dir must be absolute. The worker reads the model from this folder.
embed_model_sha256
Required string. Expected model manifest identity, compared with Ready. The config parser does not validate its hexadecimal shape. The worker identity must be 64 lowercase hexadecimal digits; a different manifest is embed_model_mismatch.
embed_memory_bytes
Required positive u64 worker memory bound. Zero is embed_limits.
embed_threads
Required positive u64 worker thread count. Zero is embed_limits.
embed_batch_items
Required positive u64 fitting a platform-sized count. Maximum texts in one worker batch. Zero is embed_limits; platform overflow names a positive count.
embed_input_bytes
Required positive u64 maximum input text bytes. Zero is embed_limits. Excess input is embed_input_too_large.
embed_tokens
Required positive u64 token bound. Must fit the model maximum and leave room for special tokens, prefix tokens and one content token. Invalid model limits are embed_limits.
embed_frame_bytes
Required u32 from 8192 to 4294967295. Must also fit the largest legal batch of vectors for the model dimensions and any windows. Otherwise embed_limits.
embed_ready_ms
Required positive u64 milliseconds within the monotonic clock. Zero or an unrepresentable duration names embed_ready_ms. Startup exhaustion is embed_worker_start_timeout.
embed_call_ms
Required positive u64 milliseconds within the monotonic clock. Zero or an unrepresentable duration names embed_call_ms. A document call with windows allows this duration for each possible window.
embed_waiting
Required positive u64 fitting a platform-sized count. Maximum callers waiting for the worker. Zero or overflow names a positive count. Full admission is embed_busy.
embed_request_items
Required positive u64 fitting a platform-sized count. Maximum texts in one request. Zero or overflow names a positive count. Excess requests are embed_request_too_large.
embed_page_records
Required integer from 1 to 1024. Records read and committed per embedding walk page. Zero names a positive count; above 1024 names the allowed range.
embed_writer_wait_ms
Optional positive u64 milliseconds, default 1000. Foreground admission wait for an embedding commit. Zero or clock overflow names embed_writer_wait_ms; exhaustion is embed_admission_wait_exceeded.
embed_windows
Optional boolean, default false. Embed long document text in overlapping windows. Setting it alone requires the whole embedding group. Text search questions still have to fit the model.
embed_max_windows
Optional u64 from 2 to 1024, default 32 when windows are on. Giving it while windows are off is refused as requiring embed_windows true. An out-of-range value names embed_max_windows. Excess text is windows_over_cap.
embed_window_overlap_tokens
Optional u64, default 64 when windows are on. Must be below embed_tokens and the model content-token capacity. Zero is allowed. Giving it with windows off is refused; excessive overlap is embed_limits.
embed_restart_ms
Optional positive u64 milliseconds, default 1000. Initial backoff after repeated worker deaths. Zero or clock overflow names embed_restart_ms. The first restart is immediate.
embed_restart_most_ms
Optional positive u64 milliseconds, default 300000. Maximum backoff, at least embed_restart_ms. Zero, clock overflow or a smaller maximum names the setting.
embed_question_worker
Optional boolean, default true. With embedding enabled, text searches use a separate worker and model copy. Memory for document and question workers can total twice embed_memory_bytes. With embedding absent there is no question worker.

The worker checks the model and its largest answer after startup. A configuration can decode successfully and still receive embed_limits, embed_model_missing or embed_model_mismatch from the worker. A model identity is not a licence to change an existing embedded field to another model. That is refused as embed_model_change_not_available.

The service configuration does not accept embed_workers. A helper with that name in the source is not a served configuration field. An unknown field is refused rather than ignored.

History retention

retention.release_max_rows
u64 from 1 to 65536, default 1024. Maximum rows considered in one release. Zero or above the cap names retention.release_max_rows.
retention.release_batch
Positive u64 fitting a platform-sized count, default 256. Branch advances between release work. Zero or platform overflow names retention.release_batch.
retention.keep
Optional object. Its versions and days are optional u64 values or null. If either is absent or null, the release driver keeps every history row and reports which setting is unset.
retention.keep.versions
Positive u64 or null, default unset. Keep at least this many versions, including the head. Zero is refused as the head is always kept.
retention.keep.days
u64 from 0 to 36500 or null, default unset. Keep versions within this age as well as the version count. Above 36500 names retention.keep.days. Both protections must allow a release.

The head stays kept. The branch record’s recent-head window and the history release policy are separate. Lowering kept_versions does not by itself delete the older history rows. See History and time.

Store permissions

{
  "lys": {
    "issuer": "https://lys.example.au",
    "database": "wards",
    "placement_credential_file": "/etc/haematite/lys-app-credential"
  }
}
lys.issuer
Required HTTP or HTTPS origin string without an API mount, path, credentials, query or fragment. A mounted URL is lys_origin_required. Invalid addresses are endpoint_refused or contract_refused.
lys.database
Required nonempty string of ASCII letters, digits, _ or -. Its Lys resource kind is haematite.database. Invalid input is refused as lys database id must be letters, digits, _ or - only.
lys.placement_credential_file
Optional absolute path string or null. File containing one line of the haematite Lys app credential, at most 4096 bytes. Invalid files are named without showing their contents. Enables collection and branch placement under the database and app-authenticated live checks. Without it no automatic placement is made.

The app credential is for placement and live questions to Lys. It is not the caller’s pass. Each person or agent still presents its own pass. See Sign-in and permissions.

The door file

{
  "listen": "127.0.0.1:7741",
  "origin": "https://studio.example.au",
  "files": "/opt/haematite/studio",
  "stores": {
    "wards": "/run/haematite/ward.sock"
  },
  "lys": {
    "issuer": "https://lys.example.au",
    "client_id": "haematite-studio",
    "secret_file": "/etc/haematite/lys-app-credential",
    "redirect": "https://studio.example.au/callback"
  }
}

All top-level fields other than timeout_ms and max_connections are required. The lys object is required and has no default members. Unknown top-level or Lys fields are refused as the door configuration is not valid, followed by the decode reason.

listen
Required socket address string with a numeric loopback IP and a port. Public binding is refused as listen must be a loopback address behind a TLS proxy.
origin
Required canonical HTTPS origin string, without a path or trailing slash. Otherwise origin must be an https origin with no path, as the browser sends it.
files
Required absolute folder path string for built Studio assets. Relative paths are files must be an absolute folder. Missing files are refused when requested.
stores
Required nonempty object mapping names to absolute socket path strings. Names use ASCII letters, digits, - or _. An empty map, invalid name or relative socket is refused by the field name. The map lists endpoints; Lys still decides each act.
timeout_ms
Positive u64 milliseconds, default 30000, for store connection steps. Zero, null or wrong types are the door configuration is not valid with the serde reason.
max_connections
Positive platform-sized integer, default 64. Maximum simultaneous browser connections. Invalid numbers are configuration decode refusals.
lys.issuer
Required HTTP or HTTPS address string for discovery. Invalid input is lys issuer is not an address or lys issuer must be an http or https address. The sign-in client also requires an origin.
lys.client_id
Required nonempty string without control characters. Otherwise lys client_id must be a name with no control character.
lys.secret_file
Required absolute path string. One line of app credential, at most 4096 bytes, read once before listening. A relative value is lys secret_file must be an absolute path; unreadable or invalid contents name the file only.
lys.redirect
Required string equal to origin plus /callback. Otherwise lys redirect must be the origin's /callback.

The door has fixed request bounds: 16384 bytes for the request head, 1048576 bytes for the body and ten seconds for each browser read or write. These are not JSON fields. Its configuration file is limited to 1048576 bytes.

HAEMATITE_PENDING_SIGNINS
Positive platform-sized count, default 512. Maximum pending sign-in states.
HAEMATITE_SESSION_SECONDS
Positive u64 seconds, default 43200. Server-side session lifetime. In release 0.20.1, the browser session cookie is issued for a fixed 12 hours. Preview main 622ec037 instead uses the configured session lifetime for the cookie too. Recheck this difference at the next release.
HAEMATITE_LYS_CONNECT_TIMEOUT_MS
Positive u64 milliseconds, default 5000. Connection allowance for door sign-in and schema HTTP requests. Must not exceed HAEMATITE_LYS_TIMEOUT_MS.
HAEMATITE_LYS_TIMEOUT_MS
Positive u64 milliseconds within the monotonic clock, default 30000. Whole Lys request allowance. Invalid environment values name the variable and require a positive integer.

These environment bounds also apply to schema HTTP requests where relevant. They do not change the store’s live permission client’s separate five-second connect and fifteen-second whole-request bounds.

HTTP MCP

{
  "mcp_http": {
    "listen": "127.0.0.1:7742",
    "allowed_origins": [
      "https://studio.example.au"
    ],
    "path": "/mcp",
    "resource_metadata_url": "https://studio.example.au/.well-known/oauth-protected-resource"
  }
}

mcp-http requires an absolute configuration path and reads at most 1048576 bytes. Its configuration errors carry mcp_http_config_invalid. The HTTP listener and the store socket have separate admission limits.

mcp_http.listen
Required numeric loopback socket address string. A non-loopback address is mcp_http_config_invalid: listen must be a loopback address behind a TLS proxy.
mcp_http.allowed_origins
Required array of canonical origin strings, treated as a set. An empty array permits callers that omit Origin and permits no browser origin. Origins have no path, trailing slash, fragment or query, use lowercase canonical hosts and omit default ports. HTTPS is required except for literal loopback HTTP IPs. Otherwise mcp_http_config_invalid names the URL or canonical-origin rule.
mcp_http.path
Optional string, default /mcp. From 2 to 256 ASCII bytes, beginning with /, no trailing / or //, and only letters, digits, /, -, _ and dots. Otherwise mcp_http_config_invalid: path must be an absolute request path of plain segments.
mcp_http.resource_metadata_url
Optional URL string or null, default unset. URL placed in the 401 challenge. Absolute ASCII HTTPS or literal loopback HTTP, without credentials, fragment, quotes or backslashes. At most 2048 bytes and safe as one header value. Otherwise mcp_http_config_invalid names the URL or safe-header rule. The MCP server does not create the metadata document.
mcp_http.max_connections
Positive platform-sized integer, default 64. HTTP connection admission limit, separate from the store client count.
mcp_http.header_timeout_ms
Positive u64 milliseconds, default 2000. Request-header deadline. A duration outside the monotonic clock is mcp_http_config_invalid: HTTP deadline is not representable.
mcp_http.body_timeout_ms
Positive u64 milliseconds, default 5000. Request-body deadline with the same clock-range rule. Zero, null, wrong types and unknown HTTP fields are mcp_http_config_invalid: service configuration is not valid.

An omitted Origin is allowed. A present one must be in allowed_origins, even for an agent. This is an origin check, not permission to read the store. Every request still needs exactly one bearer sign-in. Place TLS in front of the loopback listener and serve the configured resource metadata document at the proxy or another HTTP service.

Verify the change

Start each process with its own file. Confirm the store readiness line, run collections.list, then call one MCP tool or open Studio. A successful JSON decode does not verify a credential, a proxy, model files or a worker. Refusals names the next act for each failure.