Kronika documentation

Configuration

Kronika has no configuration file of its own. Behavior is set by CLI flags (defaults in cli), Brama access by environment variables, and the sync loop by the per-repository manifest described in sync.

Environment

Variable Required Purpose
BRAMA_URL yes, for check/write/sync Brama origin for model commands
BRAMA_API_KEY_ROLE yes, for check/write/sync ROLE#FIELD reference resolved through stado credentials get --role; not a secret value or vault item name
WISENT_APP_AGENT_ID optional request-signing agent identity
WISENT_APP_AGENT_AUTH_SECRET_ROLE with the signing agent identity ROLE#FIELD reference for the request-signing secret
KRONIKA_MODEL optional default --model selector; any when unset
STADO_BIN optional Credential resolver executable; otherwise stado on PATH
KRONIKA_CREDENTIALS_FILE explicit alternative without Stado Owner-only JSON object mapping role to field to secret value; never committed

init, gui, sources, onboarding and help need no Brama credentials. Model operations refuse a missing URL or BRAMA_API_KEY_ROLE. Only role references travel in the environment: the bearer and signing secret are resolved when needed. The signing identity and secret must be supplied together. Credential resolution failures identify the role, field and failed operation. The opened credentials descriptor must be a regular file owned by the caller and deny group and other access before any secret is read from that same descriptor. Its JSON must hold a nonempty string for the requested field. A present blank file declaration refuses instead of selecting Stado; file refusals name the declaration, path and actual cause.

The Brama request

Every model interaction is one POST to <BRAMA_URL>/v1/chat/completions (trailing slashes on the URL are stripped) with an OpenAI-compatible body: model and messages, plus max_tokens only when declared. Headers:

  • authorization: Bearer <resolved bearer> — always.
  • When the signing pair is set: x-agent-id, x-agent-timestamp (Unix seconds), and x-agent-signature — an HMAC-SHA256 over <agentId>:<timestamp>:<sha256-hex-of-body> keyed with the secret, so the signature commits to the exact JSON body.

The request has no time limit: it ends with Brama's answer or a transport error. A non-2xx response surfaces as Brama returned HTTP <status> with the server's error detail. The response may carry content directly or the OpenAI choices[0].message.content shape (string or text parts); an empty completion is the error Brama returned no documentation content. Every transport sentence, with meaning and fix, is in the runbook.

Model selection

--model (default KRONIKA_MODEL, then any) is passed through to Brama as the model field. Kronika does not resolve providers or models itself — Brama owns client authorization, model selection, and inference. In the sync loop, a per-document model in the manifest overrides the flag.

Budgets

Every budget is an optional flag with a per-document override in the sync manifest, and none has a default: --max-input-bytes and --max-file-bytes bound the source payload (sources), --max-tokens bounds the completion, and --max-diff-bytes bounds the audited Git diff — an oversized diff is refused, never truncated. Unset, every source is read whole, the whole diff is audited, and Brama's alias sets its own output limit.

The site pipeline's endpoint

The kronika-site pipeline resolves BRAMA_URL, otherwise the address published by Stado in ~/.stado/forwards/brama.local. If neither is available, the refusal names both declarations; no endpoint is built in. An unreachable endpoint exits 69. Generation sampling belongs to the Brama route, and failed HTTP responses retain their complete error body. See site pipeline.