Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration

Config lives at $XDG_CONFIG_HOME/hallouminate/config.toml (~/.config/hallouminate/config.toml by default). Two layers combine per request: an XDG baseline loaded once at daemon boot, and a repo layer discovered fresh on every request from the client’s working directory.

hallouminate config init       # scaffold the baseline
hallouminate config show       # the effective merged config for this cwd
hallouminate config validate   # parse + flag unknown top-level keys

Sections

SectionHolds
[[corpus]]Explicit named corpora (name, paths, globs, exclude rules).
[[repository]]Repo declarations; each derives repo:NAME:wiki and repo:NAME:corpus.
[search]Read-side defaults (top_files_default, chunks_per_file_default, …).
[embeddings]Embedding model and toggle (below).
[logging]Process-wide log rotation and retention limits.
[watch]File-watch settings.
[storage]Ground-directory location.

The XDG baseline vs the repo layer

The baseline owns explicit [[corpus]] entries, [[repository]] declarations, and the [search]/[embeddings]/[logging]/[watch]/[storage] defaults. It is loaded once at daemon startup — change it and restart the daemon. [logging] is process-wide and baseline-owned — a repo layer that sets a non-default [logging] errors, naming the repo config path.

The repo layer is <repo>/.hallouminate/config.toml, found by walking up from the cwd to the first .git boundary. It overrides scalars and adds repo-local corpora, and is re-read on every request — so repo-layer edits take effect without a daemon restart. The repo layer is required: a CLI invocation from a directory with no ancestor .hallouminate/config.toml errors out. An empty file satisfies the check.

A repo declares itself like this repo does:

[[repository]]
name = "hallouminate"
path = "."

path = "." resolves against the repo root (the parent of .hallouminate/), so the wiki lands at <repo>/.hallouminate/wiki and is searchable as repo:hallouminate:wiki from any checkout.

Merge rules

  • Array entries ([[corpus]], [[repository]]) — repo entries append after baseline entries; duplicate names error.
  • Scalars — the repo wins if it sets a non-default value; conflicting non-default values error and name both source paths. [logging] stays baseline-owned: a repo layer that sets a non-default [logging] is an ERROR naming the repo config path, rather than being silently ignored.

Logging

The active process log is $XDG_STATE_HOME/hallouminate/hallouminate.log (default ~/.local/state/hallouminate/hallouminate.log). Size rotation creates numbered archives hallouminate.log.1, .2, and so on, with .1 newest.

[logging]
max_file_bytes = 10485760   # 10 MiB
max_total_bytes = 104857600 # 100 MiB

Every active or archived file is capped at max_file_bytes. Retention keeps at most floor(max_total_bytes / max_file_bytes) files including the active file, so defaults retain the active file plus nine archives and never exceed 100 MiB. Both limits must be nonzero and the total must be at least the per-file limit.

HALLOUMINATE_LOG_MAX_FILE_BYTES and HALLOUMINATE_LOG_MAX_TOTAL_BYTES override the baseline limits. Invalid values stop startup and name the offending variable. Log filtering remains HALLOUMINATE_LOG, then RUST_LOG, then hallouminate=info.

Watcher failure reminders

[watch].failure_reminder_secs defaults to 60. Identical watcher reindex failures (same path and rendered error) log once, then the next occurrence at or after the interval reports how many messages were suppressed. Distinct failures remain immediate. Set the value to 0 to disable suppression, or use HALLOUMINATE_WATCH_FAILURE_REMINDER_SECS as a process override.

Embeddings

Dense embeddings are on by default, using snowflake/snowflake-arctic-embed-s. On first index hallouminate downloads that model and fuses its vector signal with lexical search.

Supported models

All embed to 384-dim vectors. Omitting embeddings.model selects the default.

ModelNotes
snowflake/snowflake-arctic-embed-sDefault. English, symmetric retrieval.
BAAI/bge-small-en-v1.5English, symmetric retrieval.
intfloat/multilingual-e5-smallMultilingual, asymmetric retrieval; no quantized variant.

Turning embeddings off

Run lexically only — full-text search + ripgrep + rerank, no embedding model downloaded (just the tokenizer used for chunking):

[embeddings]
enabled = false

Changing the embedding mode (or model) for a ground directory already indexed under a different mode trips the store’s mismatch guard on the next run. Delete the ground directory and re-index to rebuild:

rm -rf ~/.local/share/hallouminate/ground
hallouminate index

To pre-fetch the model so the first index doesn’t pay the download cost:

hallouminate config download

Paths at a glance

WhatDefault
Baseline config$XDG_CONFIG_HOME/hallouminate/config.toml
Repo-layer config<repo>/.hallouminate/config.toml
Active process log$XDG_STATE_HOME/hallouminate/hallouminate.log (state-dir fallback)
Rotated process logshallouminate.log.1 through .9 with default limits
Ground (LanceDB) directory~/.local/share/hallouminate/ground
Model cache~/.cache/hallouminate/fastembed
Daemon socket$XDG_RUNTIME_DIR/hallouminate/daemon.sock (cache-dir fallback)