Configuration
Ster has no application configuration file. Runtime behavior is fully selected by CLI arguments or the equivalent ster request body fields, plus compile-time Cargo features and two Candle CPU thread environment variables. There is no
Overview#
Ster has no application configuration file. Runtime behavior is fully selected by CLI arguments or the equivalent ster request body fields, plus compile-time Cargo features and two Candle CPU thread environment variables. There is no precedence stack: omitted choices take the defaults below, and every training, sampling and judging number is required — Ster assumes none, and a command or body without one is refused naming it.
CLI keys#
These are all runtime CLI keys. --help and --version are clap controls, not Ster configuration.
| Command | Key | Type | Default | Contract |
|---|---|---|---|---|
| train, optimize, evaluate, generate, extract, pairs synthesize | --model | string | required | Existing local directory or Hugging Face model id. |
| same | --revision | string | main for Hub, none for local | Hub ref; local metadata only. |
| same | --device | enum | cpu | cpu, metal, or cuda. |
same, plus the five ster tune subcommands that load a model | --precision | enum | f32 | f32, f16, or bf16; the dtype the frozen base weights are mapped at. bf16 is refused on cpu at load. |
| same | --chat-template | enum | auto | auto or off; there is no on. auto applies the checkpoint's own conversation format when it publishes one. Accepted and ignored by pairs synthesize --generator brama. |
| train | --pairs | path | required | Pair-set JSON. |
| train | --output | path | required | Steering artifact destination. |
| train | --layers | layer expression | all | Single indices, comma lists, or half-open ranges. |
| train | --method | enum | caa | caa, pca, logistic. |
| optimize | --pairs | path | required | Pair-set JSON. |
| optimize | --output | path | required | Winning artifact destination. |
| optimize | --layers | layer expression | all | Candidate layer set. |
| optimize | --holdout | f64 | required | Fraction of the pairs held out to rank candidates on, in (0, 1); both sides need at least one pair. |
| evaluate | --pairs | path | required | Evaluation pair-set JSON. |
| evaluate | --vector | path | required | Steering artifact. |
| generate | --prompt | string | required | Nonblank prompt shorter than context. |
| generate | --vector | path | none | Omit for baseline generation. |
| generate | --strength | f64 | required with --vector, refused without one | Signed shared steering scale. |
| generate | --max-new-tokens | usize | required | Must be greater than zero. |
| generate | --temperature | f64 | required | <= 0 means argmax; positive means sampling. |
| generate | --top-p | f64 | none | Used only with positive temperature; none samples the whole distribution. |
| generate | --seed | u64 | required | Used by sampling; argmax is deterministic. |
| extract | --input | path | required | JSON shaped {"prompts":["..."]}. |
| extract | --output | path | required | Activation artifact destination. |
| extract | --layers | layer expression | all | Layers to export. |
| inspect | positional ARTIFACT | path | required | Steering artifact to validate/print. |
| pairs inspect | --pairs | path | required | Pair-set JSON to audit; no model is loaded. |
| pairs inspect, pairs synthesize | --dedupe-bits | u32 | required | SimHash Hamming distance at or below which two pairs are near-duplicates. |
| same | --dedupe-bands | u32 | required | Banded-LSH band count; must divide the 64-bit fingerprint evenly. |
| same | --refusal-threshold | f32 | required | Score at or above which a side reads as a refusal. |
| pairs inspect | --unbalanced-ratio | f64 | required | Longer-over-shorter character ratio above which a pair counts as unbalanced. |
| pairs add | --pairs | path | required | Pair-set JSON; created, with its parents, when it does not exist. |
| pairs add | --positive, --negative | strings | required | The two sides of the new pair; neither may be blank. |
| pairs add | --trait | string | none | Sets or replaces the set's trait_name. |
| pairs remove | --pairs | path | required | Existing pair-set JSON. |
| pairs remove | --index | usize | required | Zero-based position of the pair to drop. |
| pairs synthesize | --trait | string | required | One-sentence description of the trait the positive side shows. |
| pairs synthesize | --count | usize | required | Pairs to keep; must be above zero. |
| pairs synthesize | --output | path | required | Destination pair-set JSON. |
| pairs synthesize | --trait-name | string | the whole trait description | Label written into the set. |
| pairs synthesize | --opposite | string | derived with one generation | Skips the opposite-trait step and uses this text. |
| pairs synthesize | --retry-multiplier | usize | required | Attempt budget is --count times this value. |
| pairs synthesize | --max-new-tokens | usize | required | Token budget per generated answer. |
| pairs synthesize | --temperature | f64 | required | Must be above zero; argmax generation would repeat one pair. |
| pairs synthesize | --top-p | f64 | required | Nucleus the sampler draws from. |
| pairs synthesize | --seed | u64 | required | Advances by one on every model call, so one seed reproduces a run. |
| calibrate, decisions benchmark | --ece-bins | usize | required | Equal-width confidence bins the calibration error is measured over; recorded as ece_bins. |
| tune sft, dpo, reward, grpo | --rank, --alpha, --learning-rate, --accumulation, --max-sequence, --seed | numbers | required | The LoRA and optimizer settings of the run; recorded in its report. |
| tune sft, dpo, reward | --epochs, --batch-size | usize | required | Passes over the rows and rows per forward. |
| tune dpo, grpo | --beta | f64 | required | Reference pull (DPO) or KL weight (GRPO). |
| tune grpo | --group, --iterations, --max-new-tokens, --temperature, --top-p | numbers | required | Sampling settings of the policy loop. |
| tune evaluate | --max-sequence, --batch-size | usize | required | Must match the run an adapter is compared against. |
Exact command behavior: CLI reference. Layer grammar: layer selection.
Ster passes temperature/top-p values to Candle without an additional range check. Invalid sampling parameters may therefore surface as a Candle error; use temperature > 0 and 0 < top_p <= 1. Strength is not clipped.
Request body keys#
Request JSON uses camelCase. Unknown JSON fields are ignored by serde. Choices with a default are filled before required-field validation; a required number that is missing is refused at deserialization, naming it (missing field \learningRate\`). All path values are paths on the filesystem of the ster request` process, and relative paths use its working directory.
| Operation | Key | Type | Default |
|---|---|---|---|
| train, optimize, evaluate, generate, extract, pairs/synthesize | model | string | required |
| same | revision | string or null | null (Hub resolver defaults to main) |
| same | device | string | cpu |
same, plus the five tune/* operations that load a model | precision | string | f32 |
| same | chatTemplate | string | auto |
| train | pairs, output | string paths | required |
| train | layers | string | all |
| train | method | string | caa |
| optimize | pairs, output | string paths | required |
| optimize | layers | string | all |
| optimize | holdout | number | required |
| evaluate | pairs, vector | string paths | required |
| generate | prompt | string | required |
| generate | vector | string or null | null; blank also means baseline |
| generate | strength | number | required with vector; absent without one |
| generate | maxNewTokens | unsigned integer | required |
| generate | temperature | number | required |
| generate | topP | number or null | null |
| generate | seed | unsigned integer | required |
| extract | input, output | string paths | required |
| extract | layers | string | all |
| inspect | artifact | string path | required |
| pairs/inspect | pairs | string path | required |
| pairs/inspect | dedupeBits, dedupeBands, refusalThreshold, unbalancedRatio | numbers | required |
| pairs/save | path | string path | required |
| pairs/save | traitName | string | "" |
| pairs/save | entries | array of {positive, negative} | required, at least one entry |
| pairs/synthesize | trait, count, output | string, unsigned integer, string path | required; count above zero |
| pairs/synthesize | traitName, opposite | string, string or null | "" (the whole trait description), null (derived) |
| pairs/synthesize | retryMultiplier, dedupeBits, dedupeBands, refusalThreshold | numbers | required |
| pairs/synthesize | maxNewTokens, temperature, topP, seed | numbers | required |
| pairs/import | seed | unsigned integer | required |
| calibrate | eceBins | unsigned integer | required |
| tune/sft, tune/dpo, tune/reward, tune/grpo | rank, alpha, learningRate, accumulation, maxSequence, seed | numbers | required |
| tune/sft, tune/dpo, tune/reward | epochs, batchSize | unsigned integers | required |
| tune/dpo, tune/grpo | beta | number | required |
| tune/grpo | group, iterations, maxNewTokens, temperature, topP | numbers | required |
| tune/evaluate | maxSequence, batchSize | unsigned integers | required |
The protocol, events, exit statuses and serialization behavior are in the desktop request reference.
Build-time features#
| Cargo feature | Default | Effect |
|---|---|---|
metal | off | Enables Candle Metal and makes --device metal select device 0. |
cuda | off | Enables Candle CUDA and makes --device cuda select device 0. |
The default feature set is empty. Devices never auto-detect and there is no runtime fallback: a CPU-only binary refuses metal/cuda. Every backend defaults to F32. --precision f16 and --precision bf16 map the frozen base weights at half width instead, and what a run trains stays F32 regardless; bf16 has no CPU matmul kernel in Candle and is refused on cpu at load (precision).
Environment and local files#
Ster source reads exactly two environment variables, and both belong to the optional Brama pair generator: BRAMA_URL, read by base_url, and BRAMA_BEARER, read by bearer — the only two env::var calls in the whole source, both in src/brama.rs.
| Variable | Valid value | Fallback |
|---|---|---|
BRAMA_URL | an https:// base, or an explicit http:// loopback base; trailing slashes are trimmed | none: an unset or empty value is refused as BRAMA_URL is unset or empty; export the Brama gateway base Ster should call |
BRAMA_BEARER | a non-empty bearer, trimmed | none: the generator refuses without it |
Both are read on one code path only — the Brama generator behind `ster pairs synthesize` and its ster request pairs/synthesize equivalent. Every other command ignores them, so neither variable changes how a model is resolved, trained, or steered.
Ster's Candle dependency honors two CPU thread knobs of its own:
| Variable | Valid value | Fallback |
|---|---|---|
RAYON_NUM_THREADS | positive integer | physical CPU/P-core count, at least 1 |
CANDLE_NUM_THREADS | positive integer | physical CPU/P-core count, at least 1 |
RAYON_NUM_THREADS sizes Candle's Rayon pool and CPU matmul parallelism; CANDLE_NUM_THREADS sizes its barrier pool. Missing, non-integer, zero, or negative values silently use the hardware fallback.
Hub resolution calls hf-hub Api::new, not its environment-aware builder. Consequently HF_HOME and HF_ENDPOINT do not change Ster 0.13. The default client uses:
- cache:
~/.cache/huggingface/hub; - optional bearer token file:
~/.cache/huggingface/token.
Apart from those two Brama variables there is no Ster environment key for model, device, revision, cache, offline mode, output directory, or log level: each of those is a CLI flag or a ster request body field. The only endpoint and token Ster takes from the environment are the pair generator's, never the model's.
Model config keys#
Ster does not own a separate model-config schema. It requires top-level model_type: "llama", then deserializes the whole config.json through Candle 0.11's LlamaConfig. Dimensions, heads, rope settings, EOS ids, context length, norm epsilon, and tied embeddings therefore come from the checkpoint, not Ster flags. Required files and resolution rules are documented in model resolution.
Repository release metadata, and the Stado install path#
.wisent-release.json configures repository delivery, not the installed binary. Its complete present key tree is: schema_version, product, releases; version_source.{kind,path,pattern}; platforms.<name>.{runner_platform,quality,build.argv,stage}; and promotion.{channels,reconcile}, inputs, deliveries. It declares darwin-arm64 and linux-amd64, both built by sh scripts/build-release.sh, promoted on stable, with no quality commands, inputs, or deliveries. Changing it cannot configure a running Ster process.
The reader of that manifest is Stado, which is how a built Ster actually reaches a machine. stado product status ster --surface cli reports the recipe it installs from — kind stado-release, repository wisent-ai/ster, manifest .wisent-release.json — together with the source_revision it was built from and the paths it wrote:
$ stado product status ster --surface cli
product = ster
surface = cli
status = stale
recipe = {'surface': 'cli', 'kind': 'stado-release', 'repository': 'wisent-ai/ster', 'manifest': '.wisent-release.json'}
installed_paths = ['/Users/<you>/.stado/bin/ster', '/Users/<you>/.local/bin/ster']
source_revision = 155908c5c5260ce96d83a864f9600218d8547d97The lifecycle verbs are Stado's, not Ster's:
| Command | Effect |
|---|---|
stado product install ster --surface cli | Build from the canonical recipe and write the binary. |
stado product status ster --surface cli | Read the recorded state: recipe, source_revision, installed paths, retained generations. |
stado product update ster --surface cli | Re-run the recipe, retaining the replaced installation for rollback. |
stado product rollback ster --surface cli | Restore the most recent retained installation. |
stado product remove ster --surface cli | Remove the surface and the files it recorded. |
Each update copies the binary it replaces under ~/.stado/products/ster/backups/<timestamp>/ster, which is what stado product rollback restores; on this machine that directory held 17 retained generations when this page was written. scripts/build-release.sh exists to serve this path: it leaves the bare binary beside the tarball because, in its own words, "a stado-release install copies individual bin/ members out of .wisent-output and never unpacks a tarball". A status of stale means the installed revision is behind origin/main, which stado product update (or stado product sync) resolves.
None of this configures a running Ster process, and Ster never calls Stado: the dependency runs one way, from the installer to the installed binary. cargo install remains the path that needs no Stado at all.
Local pair-set workspace#
Ster has no behavior configuration file, but imported user data has durable state. It lives under $XDG_DATA_HOME/ster when XDG_DATA_HOME is set, otherwise ~/.local/share/ster. workspace.json indexes canonical copies under pairs/ and names one active set. The manifest and accepted pair files are written atomically; credentials and prompt contents are never printed by workspace show.