Expand description
Deployment configuration: KYAML with OmegaConf-style interpolation.
§Why KYAML
Principle 5 is KYAML-first, and this file is where it starts. KYAML is a
strict subset of YAML 1.2 — explicit {} and [], every string
double-quoted, indentation carrying no meaning — so any YAML parser reads it
and no YAML parser can guess wrong about it.
The guessing is the point. An unquoted scalar is resolved by pattern-match
against a table, and which table depends on the YAML version and the
implementation. The famous case — a replica honestly named no becoming the
boolean false — is YAML 1.1, and does not happen with the parser below.
Measured against that parser, these do:
node: False→Boolean(false)→ the string"false", case flipped.node: 0x1f→Integer(31)→ the string"31". The text changed.node: null→Null, which reads as “key absent”, so the default is used and nothing is reported.
A different parser, or the same one a major version later, has a different list. That is the real argument: the correct reading of an unquoted scalar is not a property of the document. Quoting makes it one, for four characters, and a generating model gets the same guarantee a careful human would — which is why the principle exists.
Enforcement is scalar: every value Mira reads out of this file is a
string, so anything that arrived as another type is refused at boot with a
message saying to quote it. A list or a map never reaches a value at all, so
check_keys refuses those, by path — quoting is not the fix for a shape.
§Why there is a config file at all
Principle 2c is “self-driving, no tuning knobs”, which this appears to violate and does not. The distinction that matters:
- A knob is a number the engine could work out for itself and instead
asks a human to guess — block size, buffer depth, flush interval, cache
sizes, compaction thresholds. None of those are here, and none of them will
be. They live in
pipeline::Config, derived, with no path from this file. - Deployment description is what the engine cannot know: which addresses to listen on, which directory is the data directory, how long the retention policy is, what this replica is called. That is not tuning. Refusing to accept it does not make an engine self-driving, it makes it unusable.
The boundary is structural rather than documentary: this struct has no field
that affects how the engine performs, only where it runs — with one
deliberate exception, ingest.wal, which is not a number to guess but a
choice between two correct durability promises that no measurement can make
for the operator. Its own doc comment argues that.
§Interpolation
{
"node": "${env:HOSTNAME,mira-0}", # env var, default after the comma
"storage": {
"dir": "/var/lib/${node}", # another key, by dotted path
"retention": "7d",
},
}${env:NAME}— required; a missing variable is a startup error, not an empty string. Silently defaulting is how a staging cluster ends up writing to a production bucket.${env:NAME,default}— everything after the first comma is the default, verbatim, including further${...}.${dotted.path}— another key in this file. Resolved recursively; a cycle is a startup error naming the cycle.$${— a literal${.
Resolution is lazy: only keys actually read are expanded, so an unused key with a broken reference cannot stop the process from booting.
There is deliberately no second MIRA_* environment-override mechanism.
${env:...} already covers every case, explicitly and visibly in one file,
and two ways to set the same value is exactly the complexity this is meant to
avoid.
Structs§
Constants§
- KNOWN 🔒
- Every path this file may contain, in the order
Config::parsereads them.
Functions§
- boolean
trueorfalse, and nothing else.- bytes
4MiB,512k,1048576. Binary units, because every other size in this system — page, block, mmap — is binary and aMBthat meant 10^6 next to a block size that meant 2^20 would be a trap.- check_
keys 🔒 - Refuse a key Mira does not read, or a shape it cannot read.
- closing_
brace 🔒 - Offset of the
}that closes a${already consumed. - duration
500ms,30s,5m,2h,7d. A bare number is seconds.- expand 🔒
- get 🔒
- lookup 🔒
- positive
- A count of things, which must be at least one.
- resolve 🔒
- Expand every
${...}inraw.stackcarries the config paths currently being resolved, so a reference cycle is reported rather than overflowing. - scalar 🔒
- Every value Mira reads from the config file is a string — an address, a path, a name, a duration. So the rule is simply that it must have arrived as one.
- whole
- A count of things where zero is an answer rather than a mistake — see
Config::shards, where it means “ask the machine”.