# Sample configuration for the OSS `jammi-server`.
#
# The OSS server is single-tenant — the deployer's network is the
# auth boundary. Run one server per tenant, or front it with a
# reverse proxy that enforces tenancy at the HTTP layer.
#
# Persisted state lives under `artifact_dir`. The OSS image's
# Dockerfile declares `/var/lib/jammi` as a volume; mount a named
# Docker volume (so distroless's nonroot uid 65532 gets ownership)
# or `chown 65532:65532` your bind-mount host directory.

artifact_dir = "/var/lib/jammi"

[server]
# HTTP side-channel: `/healthz`, `/readyz`, `/metrics`.
health_listen = "0.0.0.0:8080"
# gRPC + Flight SQL surface. The core tier (SessionService, EmbeddingService,
# InferenceService, MutableTableService, ChannelService, AuditService) and
# Flight SQL are always mounted; the optional tiers below are runtime-selectable.
flight_listen = "0.0.0.0:8081"
# Models to preload into memory at startup. Empty by default.
preload_models = []
# Service tiers this deployment mounts, beyond the always-on core tier. One
# binary scales to many shapes without a rebuild:
#
#   services = "all"             # all-in-one: every tier compiled in (default)
#   services = ["event"]         # serve + event box (TriggerService)
#   services = ["train"]         # serve + training box (FineTuneService)
#   services = ["eval"]          # serve + eval tooling (EvalService)
#   services = []                # serve-only: core tier only
#
# A tier requested here whose feature is compiled out (e.g. `train` on a
# `--no-default-features` build) is a startup error, not a silent drop. The
# mounted set is reported over the wire via `SessionService.GetServerInfo`
# (`services`), so a client knows which verbs are reachable. Defaults to "all".
services = "all"

[logging]
level = "info"
format = "json"

# Training-worker lease/heartbeat/poll timing (used by the `train` tier).
# Defaults reproduce the engine's built-in timing, so this section is optional.
# The heartbeat must leave a real margin under the lease
# (heartbeat_interval_secs * 2 < lease_duration_secs) so a live worker renews
# strictly before the lease expires; a config that does not is rejected at
# startup, never silently clamped. idle_poll_secs must be > 0.
[training]
# How long a claim leases a job before it is reclaimable.
lease_duration_secs = 30
# How often the worker renews the lease while a job runs.
heartbeat_interval_secs = 10
# How often an idle worker polls for a queued job (and reclaims expired leases).
idle_poll_secs = 1

# ─── Coming in v0.9 (S4 catalog/broker config) ──────────────────────
#
# After the S4 work lands, the OSS server will accept first-class
# catalog and broker selection. Until then the SQLite catalog +
# in-memory broker defaults apply.
#
# [catalog]
# kind = "postgres"
# url = "postgres://jammi:secret@postgres:5432/jammi"
#
# [broker]
# kind = "jetstream"
# url = "nats://nats:4222"
