The build's switches — the vaelii.* JVM system properties and the VAELII_*
environment variables — read in one place, each against a domain, and refused when
the value is outside it.
This is kb/check-opts!'s invariant one layer out: an option that is not read is not
an option. A switch are indistinguishable from a membership test or an equality against one spelling has
no wrong value — every misspelling falls to the other branch — so under that reading
vaelii.disk.auto-compact=disabled is compaction on and vaelii.disk.fsync=always
is the three-second tick, which is the durability level the operator is trying to
leave. A process that reports itself configured and is not is the failure
check-opts! exists to prevent, on the property that decides whether a crash loses
data. So no switch is read that way here.
truthy and falsy below, case-insensitively, and nothing else: every boolean switch
reads the same words, so a spelling that works on one works on all of them and a
spelling that works on none is an error rather than the opposite setting. A blank
value is unset — an exported-but-empty environment variable is the shell's way of
saying nothing.
check! reads every switch at kb/open-kb, so a wrong value fails the open — before a
record is written and while what the operator typed is still legible. It reads the
whole set rather than the ones this KB's backend uses, because gating the check on the
configuration is how a wrong value in the configuration escapes it.
Where each switch is read besides that is the :read-at column of switches, and
read-at-kinds says what the three values mean. It is a column rather than a list of
names here for the reason check! is a walk rather than a list of calls: a roster
spelled twice is one that can disagree with itself, and this one had.
The two that make the eager read worth its cost are visible there as :worker and
:load. A :worker row is read inside fsync-all's catch Throwable, which logs an
exception's class name and nothing else — an unattributable line repeating every three
seconds with auto-compaction silently dead. A :load row is the root value of a var
and cannot be deferred at all; it refuses at that namespace's load, naming itself, for
guard/max-body-bytes' reason: a silent fallback leaves an operator believing a setting
they never made, and a raw parse failure out of a def reports as a namespace that
would not load rather than as the typo it is. log-level is :load for a different
reason — it is the one switch whose effect is an install, and the entry point it belongs at
is the moment the engine is loaded rather than the moment a KB is opened.
Five switches name a path or a label with no domain to check — vaelii.disk.dir,
vaelii.kb.path, vaelii.kb.catalog, vaelii.build, vaelii.clingo.lib — and one
names a member of a registry that resolves it itself: vaelii.llm.provider
(llm.provider/configured). vaelii.web.port / VAELII_WEB_PORT is the browser's
own, read at web/default-port, where an unparseable value falls through to the next
source rather than stopping a start over a convenience variable (docs/web.md).
Three more belong to the two servers and are read at vaelii.impl.guard, which both
of them read: VAELII_API_TOKEN and VAELII_ALLOWED_HOSTS are a secret and a host
list, neither of which has a domain to hold them to, and the ceiling
VAELII_MAX_BODY_BYTES refuses at guard/max-body-bytes for the reason
arbitrate-constraints? refuses at load — it is the root value of a var.
The build's switches — the `vaelii.*` JVM system properties and the `VAELII_*` environment variables — read in one place, each against a domain, and **refused when the value is outside it**. This is `kb/check-opts!`'s invariant one layer out: *an option that is not read is not an option*. A switch are indistinguishable from a membership test or an equality against one spelling has no wrong value — every misspelling falls to the other branch — so under that reading `vaelii.disk.auto-compact=disabled` is compaction **on** and `vaelii.disk.fsync=always` is the three-second tick, which is the durability level the operator is trying to leave. A process that reports itself configured and is not is the failure `check-opts!` exists to prevent, on the property that decides whether a crash loses data. So no switch is read that way here. ## One vocabulary for the boolean switches `truthy` and `falsy` below, case-insensitively, and nothing else: every boolean switch reads the same words, so a spelling that works on one works on all of them and a spelling that works on none is an error rather than the opposite setting. A blank value is *unset* — an exported-but-empty environment variable is the shell's way of saying nothing. ## Where a refusal lands `check!` reads every switch at `kb/open-kb`, so a wrong value fails the open — before a record is written and while what the operator typed is still legible. It reads the whole set rather than the ones this KB's backend uses, because gating the check on the configuration is how a wrong value in the configuration escapes it. Where each switch is read **besides** that is the `:read-at` column of `switches`, and `read-at-kinds` says what the three values mean. It is a column rather than a list of names here for the reason `check!` is a walk rather than a list of calls: a roster spelled twice is one that can disagree with itself, and this one had. The two that make the eager read worth its cost are visible there as `:worker` and `:load`. A `:worker` row is read inside `fsync-all`'s `catch Throwable`, which logs an exception's class name and nothing else — an unattributable line repeating every three seconds with auto-compaction silently dead. A `:load` row is the root value of a var and cannot be deferred at all; it refuses at that namespace's load, naming itself, for `guard/max-body-bytes`' reason: a silent fallback leaves an operator believing a setting they never made, and a raw parse failure out of a `def` reports as a namespace that would not load rather than as the typo it is. `log-level` is `:load` for a different reason — it is the one switch whose effect is an *install*, and the entry point it belongs at is the moment the engine is loaded rather than the moment a KB is opened. ## What is not checkable here Five switches name a path or a label with no domain to check — `vaelii.disk.dir`, `vaelii.kb.path`, `vaelii.kb.catalog`, `vaelii.build`, `vaelii.clingo.lib` — and one names a member of a registry that resolves it itself: `vaelii.llm.provider` (`llm.provider/configured`). `vaelii.web.port` / `VAELII_WEB_PORT` is the browser's own, read at `web/default-port`, where an unparseable value falls through to the next source rather than stopping a start over a convenience variable (docs/web.md). Three more belong to the two servers and are read at `vaelii.impl.guard`, which both of them read: `VAELII_API_TOKEN` and `VAELII_ALLOWED_HOSTS` are a secret and a host list, neither of which has a domain to hold them to, and the ceiling `VAELII_MAX_BODY_BYTES` refuses at `guard/max-body-bytes` for the reason `arbitrate-constraints?` refuses at load — it is the root value of a var.
(arbitrate-constraints?)Does the process default to arbitrating a definitional clash rather than refusing it
(VAELII_ARBITRATE_CONSTRAINTS, default off)? A KB naming a :constraints policy
overrides it.
Does the process default to arbitrating a definitional clash rather than refusing it (`VAELII_ARBITRATE_CONSTRAINTS`, default off)? A KB naming a `:constraints` policy overrides it.
(asp-solver)Which ASP backend solves (vaelii.asp.solver, else VAELII_ASP_SOLVER), or nil
for auto. The property is read first, and both spellings refuse a name outside the
roster: are indistinguishable from a bare (keyword …) a misspelt backend became a keyword nothing
matches and the selector's fallback arm ran auto, so a run pinned to clasp could
silently use clingo and report a clean pass for a backend nothing exercised.
Which ASP backend solves (`vaelii.asp.solver`, else `VAELII_ASP_SOLVER`), or **nil** for auto. The property is read first, and both spellings refuse a name outside the roster: are indistinguishable from a bare `(keyword …)` a misspelt backend became a keyword nothing matches and the selector's fallback arm ran **auto**, so a run pinned to clasp could silently use clingo and report a clean pass for a backend nothing exercised.
What the ASP backend switch reads, one spelling per backend. Unset is auto —
in-process clingo when it loads, else clasp — which is why the reader's default is nil
rather than a backend: auto is the absence of a choice, not a third one to name.
What the ASP backend switch reads, one spelling per backend. Unset is **auto** — in-process clingo when it loads, else clasp — which is why the reader's default is nil rather than a backend: `auto` is the absence of a choice, not a third one to name.
(asp-time-limit)The seconds one ASP solve may run before the backend is interrupted
(VAELII_ASP_TIME_LIMIT, default 60; 0 lifts the limit). Both backends honour it —
clasp through --time-limit, in-process clingo by cancelling the solve handle — and
an interrupted solve reports :interrupted, which no consumer is indistinguishable from an answer
(asp.edge): the edge solver decides nothing and an imperative refuses.
A solve runs on the single writer, so an unbounded one holds every write behind it —
but an operation makes as many solves as it needs, each with the whole budget: two
for a classification, three for do/labeling, one per defeat round for a settle.
docs/asp.md tabulates the multipliers, and a test pins the counts so the table cannot
drift from them.
The seconds **one ASP solve** may run before the backend is interrupted (`VAELII_ASP_TIME_LIMIT`, default 60; 0 lifts the limit). Both backends honour it — clasp through `--time-limit`, in-process clingo by cancelling the solve handle — and an interrupted solve reports `:interrupted`, which no consumer is indistinguishable from an answer (`asp.edge`): the edge solver decides nothing and an imperative refuses. A solve runs on the single writer, so an unbounded one holds every write behind it — but an **operation** makes as many solves as it needs, each with the whole budget: two for a classification, three for `do/labeling`, one per defeat round for a settle. docs/asp.md tabulates the multipliers, and a test pins the counts so the table cannot drift from them.
(assertive-arg-types?)Do the argument constraints entail as well as constrain (VAELII_ASSERTIVE_ARG_TYPES,
default off)?
Do the argument constraints entail as well as constrain (`VAELII_ASSERTIVE_ARG_TYPES`, default off)?
(belief-snapshot?)Is the belief certificate written on a full recover and read on the next cold open
(vaelii.belief.snapshot, default off)? When on, a clean disk KB's cold open skips the
closing settle's definitional-clash scan and rederives identical belief
(vaelii.impl.disk.belief-snapshot). Off is byte-identical to never having the file.
Is the belief certificate written on a full recover and read on the next cold open (`vaelii.belief.snapshot`, default off)? When on, a clean disk KB's cold open skips the closing settle's definitional-clash scan and rederives identical belief (`vaelii.impl.disk.belief-snapshot`). Off is byte-identical to never having the file.
(check!)Read every switch once, refusing the first whose value is outside its domain.
kb/open-kb calls it, which is the earliest entry point that exists for the properties the
durability daemon would otherwise read on a tick.
Every switch and not this KB's: a :memory KB with vaelii.disk.fsync=always set is
a process one directory away from a durability guarantee it does not have, and the
next open is not a better place to hear about it.
A walk of switches rather than a list of calls, so the set it reads is the set the
roster declares and cannot be a subset of it.
Read every switch once, refusing the first whose value is outside its domain. `kb/open-kb` calls it, which is the earliest entry point that exists for the properties the durability daemon would otherwise read on a tick. Every switch and not this KB's: a `:memory` KB with `vaelii.disk.fsync=always` set is a process one directory away from a durability guarantee it does not have, and the next open is not a better place to hear about it. A walk of `switches` rather than a list of calls, so the set it reads is the set the roster declares and cannot be a subset of it.
(clingo-max-program-bytes)The plain-ASP program size above which auto routes to clasp even where clingo
loads (VAELII_CLINGO_MAX_BYTES, default 3000). An explicit backend ignores it.
The plain-ASP program size above which **auto** routes to clasp even where clingo loads (`VAELII_CLINGO_MAX_BYTES`, default 3000). An explicit backend ignores it.
(disk-auto-compact?)Is background and opportunistic compaction on (vaelii.disk.auto-compact, default
on)? Read by the fsync tick and by the close path — one knob, not two.
Is background and opportunistic compaction on (`vaelii.disk.auto-compact`, default on)? Read by the fsync tick and by the close path — one knob, not two.
(disk-cache-capacity)Hot records held per kind (vaelii.disk.cache, default 65536; 0 disables the cache).
A count, so it is read at the record store's open rather than at namespace load: a
Long/parseLong in a top-level def turns =64k into a namespace that will not
load, which reports the typo as a broken build.
Hot records held per kind (`vaelii.disk.cache`, default 65536; 0 disables the cache). A count, so it is read at the record store's open rather than at namespace load: a `Long/parseLong` in a top-level `def` turns `=64k` into a namespace that will not load, which reports the typo as a broken build.
(disk-compact-dead-ratio)The dead ratio a log must reach to be worth compacting
(vaelii.disk.compact-dead-ratio, default 0.5). A ratio, so outside 0–1 it is a
threshold that either never fires or fires on every tick.
The dead ratio a log must reach to be worth compacting (`vaelii.disk.compact-dead-ratio`, default 0.5). A ratio, so outside 0–1 it is a threshold that either never fires or fires on every tick.
(disk-compact-min-interval-ms)The floor between two auto-compactions of one backend
(vaelii.disk.compact-min-interval-ms, default 300000).
The floor between two auto-compactions of one backend (`vaelii.disk.compact-min-interval-ms`, default 300000).
(disk-compress)vaelii.disk.compress: :zstd, :lz4, or nil for uncompressed frames (the
default). A case with a nil default arm is what made =gzip and =zstdd read as
no compression at all — a store written smaller than the operator asked for, with
nothing to say so.
`vaelii.disk.compress`: `:zstd`, `:lz4`, or nil for uncompressed frames (the default). A `case` with a nil default arm is what made `=gzip` and `=zstdd` read as no compression at all — a store written smaller than the operator asked for, with nothing to say so.
(disk-fsync-mode)vaelii.disk.fsync: :dsync opens every log rwd, so an append is durable when it
returns; :tick (the default, and what unset means) leaves durability to the
vaelii.disk.sync-ms daemon.
`vaelii.disk.fsync`: `:dsync` opens every log `rwd`, so an append is durable when it returns; `:tick` (the default, and what unset means) leaves durability to the `vaelii.disk.sync-ms` daemon.
(disk-lock?)Is the single-writer FileLock taken when a directory opens (vaelii.disk.lock,
default on)? Off is for a filesystem whose FileLock is unreliable, and it removes
the enforcement rather than the contract.
Is the single-writer `FileLock` taken when a directory opens (`vaelii.disk.lock`, default on)? Off is for a filesystem whose `FileLock` is unreliable, and it removes the enforcement rather than the contract.
(disk-sync-ms)The durability daemon's tick, in milliseconds (vaelii.disk.sync-ms, default 3000;
0 disables the daemon).
The durability daemon's tick, in milliseconds (`vaelii.disk.sync-ms`, default 3000; 0 disables the daemon).
(disk-tokens?)Are sentex bodies written as token ids (vaelii.disk.tokens, default off)? Off
because it is the one part of the record store that adds a durable ground truth, so a
store opts in. Reading is never gated on it — a frame carries its own tag.
Are sentex bodies written as token ids (`vaelii.disk.tokens`, default off)? Off because it is the one part of the record store that adds a durable ground truth, so a store opts in. *Reading* is never gated on it — a frame carries its own tag.
The spellings that mean off. Wider than "false" because the disk switches
document 0 / off / no as well, and removing an accepted spelling breaks a setup
that works.
The spellings that mean **off**. Wider than `"false"` because the disk switches document `0` / `off` / `no` as well, and removing an accepted spelling breaks a setup that works.
(index-snapshot-drift)How far the live index may drift from its image before the writer refreshes it
(vaelii.index.snapshot-drift, default 0.5) — a ratio, as
vaelii.disk.compact-dead-ratio is, and read the same way.
Drift is measured in indexed roots: the count now, against the count the image
holds, over the count the image holds. Roots rather than trie nodes because a node
count is a measurement the store has to take and a root count is one it already has —
the same lesson disk/durability.clj learned when it found the record store scanning
every .idx to answer a dead ratio on a three-second tick.
How far the live index may drift from its image before the writer refreshes it (`vaelii.index.snapshot-drift`, default 0.5) — a ratio, as `vaelii.disk.compact-dead-ratio` is, and read the same way. Drift is measured in **indexed roots**: the count now, against the count the image holds, over the count the image holds. Roots rather than trie nodes because a node count is a measurement the store has to take and a root count is one it already has — the same lesson `disk/durability.clj` learned when it found the record store scanning every `.idx` to answer a dead ratio on a three-second tick.
(index-snapshot?)Refuse vaelii.index.snapshot, naming the backend that selects the image instead.
The image is an index representation, and a representation is named in the opts map
where a reader of the KB's own configuration can see it: {:backend :disk-snapshot},
the one pairing there is. A process-wide property cannot say that — the same opts map
means a mapped index on one machine and an hour of reindex on another, with nothing
on the KB to tell them apart, which is the failure this namespace's check! exists to
close.
Refused rather than are indistinguishable from a default, on the argument kb/reserved-backend-names
makes for :disk: a switch that silently does nothing is discovered by the operator
running out of the resource they thought they had bought.
Read through raw rather than a prop-* helper because the domain is empty: there
is no value to parse and no default to fall back to. The name is still one the build
reads, so it is on the pinned configuration surface with every other switch
(config_surface_test) and carries its own row in docs/operations.md — an operator
whose unit file sets it meets a refusal at the open, and a refusal naming a switch no
document admits to leaves them reading the source for it.
Refuse `vaelii.index.snapshot`, naming the backend that selects the image instead.
The image is an index **representation**, and a representation is named in the opts map
where a reader of the KB's own configuration can see it: `{:backend :disk-snapshot}`,
the one pairing there is. A process-wide property cannot say that — the same opts map
means a mapped index on one machine and an hour of `reindex` on another, with nothing
on the KB to tell them apart, which is the failure this namespace's `check!` exists to
close.
Refused rather than are indistinguishable from a default, on the argument `kb/reserved-backend-names`
makes for `:disk`: a switch that silently does nothing is discovered by the operator
running out of the resource they thought they had bought.
Read through `raw` rather than a `prop-*` helper because the domain is **empty**: there
is no value to parse and no default to fall back to. The name is still one the build
reads, so it is on the pinned configuration surface with every other switch
(`config_surface_test`) and carries its own row in docs/operations.md — an operator
whose unit file sets it meets a refusal at the open, and a refusal naming a switch no
document admits to leaves them reading the source for it.(log-level)The level the engine's own logging prints at (VAELII_LOG_LEVEL), or nil when
unset — and nil is a setting rather than a default: with it unset the engine installs
no backend at all, leaving whatever the host application put in
taoensso.trove/*log-fn* (vaelii.impl.logging). So there is no default to name
here, and =verbose is refused rather than read as the one there would have been.
The level the engine's own logging prints at (`VAELII_LOG_LEVEL`), or **nil** when unset — and nil is a setting rather than a default: with it unset the engine installs no backend at all, leaving whatever the host application put in `taoensso.trove/*log-fn*` (`vaelii.impl.logging`). So there is no default to name here, and `=verbose` is refused rather than read as the one there would have been.
What VAELII_LOG_LEVEL reads, one spelling per level the dial takes. A def rather
than a literal inside the reader so that the environment and
vaelii.core/set-log-level can be checked to admit the same five: two rosters for one
dial is one of them wrong.
What `VAELII_LOG_LEVEL` reads, one spelling per level the dial takes. A def rather than a literal inside the reader so that the environment and `vaelii.core/set-log-level` can be checked to admit the same five: two rosters for one dial is one of them wrong.
(max-query-depth)The rule-expansion ceiling the daemon holds every bounded read to
(VAELII_MAX_QUERY_DEPTH, default 256; 0 lifts it). A request may name a smaller
:max-depth and is refused for naming a larger one (vaelii.impl.serve).
256 because it is the largest depth the API's own defaults name — why's — so every
documented call sits inside it, and a depth past it is a search a remote caller sized
rather than the engine.
The rule-expansion ceiling the daemon holds every bounded read to (`VAELII_MAX_QUERY_DEPTH`, default 256; 0 lifts it). A request may name a smaller `:max-depth` and is refused for naming a larger one (`vaelii.impl.serve`). 256 because it is the largest depth the API's own defaults name — `why`'s — so every documented call sits inside it, and a depth past it is a search a remote caller sized rather than the engine.
(max-query-ms)The wall-clock ceiling the daemon holds every bounded read to
(VAELII_MAX_QUERY_MS, default 30000; 0 lifts it). A request may name a smaller
:max-ms and is refused for naming a larger one (vaelii.impl.serve).
30 seconds because that is when the caller stops listening. The zero-dep client's
own read timeout is 30 s (vaelii.impl.client), and every op runs under the daemon's
single write monitor — so a read still going after that is holding every other
caller's request behind an answer nobody is waiting for.
The wall-clock ceiling the daemon holds every bounded read to (`VAELII_MAX_QUERY_MS`, default 30000; 0 lifts it). A request may name a smaller `:max-ms` and is refused for naming a larger one (`vaelii.impl.serve`). **30 seconds because that is when the caller stops listening.** The zero-dep client's own read timeout is 30 s (`vaelii.impl.client`), and every op runs under the daemon's single write monitor — so a read still going after that is holding every other caller's request behind an answer nobody is waiting for.
(profiler-port)The port the profiler's UI binds (VAELII_PROFILER_PORT, default 8080). Read only
when profiler? says to start one.
The port the profiler's UI binds (`VAELII_PROFILER_PORT`, default 8080). Read only when `profiler?` says to start one.
(profiler?)Should the sampling profiler's UI be started with the browser (VAELII_PROFILER,
default off)?
Off by default and asked for explicitly, because starting it is not free and not private: the profiler attaches an agent to this JVM and serves flamegraphs on a second port with no authentication of its own. A reader who wants one says so.
Should the sampling profiler's UI be started with the browser (`VAELII_PROFILER`, default off)? Off by default and asked for explicitly, because starting it is not free and not private: the profiler attaches an agent to this JVM and serves flamegraphs on a second port with no authentication of its own. A reader who wants one says so.
(prop-bool nm default)nm as a boolean, default when unset. Anything outside truthy / falsy is
refused rather than read as the falsy branch, which is where =disabled meaning
enabled came from.
`nm` as a boolean, `default` when unset. Anything outside `truthy` / `falsy` is refused rather than read as the falsy branch, which is where `=disabled` meaning *enabled* came from.
(prop-double nm default lo hi)nm as a double, default when unset, bounded by lo/hi as prop-long is.
`nm` as a double, `default` when unset, bounded by `lo`/`hi` as `prop-long` is.
(prop-enum nm accepted default want)nm as the value accepted maps its (lower-cased) spelling to, default when unset.
want is the prose the refusal offers instead — a roster alone answers what is
legal and not what the legal one does, and the second is what the operator who
typed the wrong one needs.
`nm` as the value `accepted` maps its (lower-cased) spelling to, `default` when unset. `want` is the prose the refusal offers instead — a roster alone answers *what is legal* and not *what the legal one does*, and the second is what the operator who typed the wrong one needs.
(prop-long nm default lo hi)nm as a long, default when unset. lo/hi bound it — every count read here is a
duration or a capacity, so one below zero is a typo rather than a setting.
`nm` as a long, `default` when unset. `lo`/`hi` bound it — every count read here is a duration or a capacity, so one below zero is a typo rather than a setting.
Where a switch's value is read besides check! — closed, because an open set of
keywords would be a roster again, with the same drift and none of the checking.
:open an entry point a caller is standing at: a store or log open, the daemon's start, a
request. A wrong value already stops that call and names itself, so
check! moves an existing refusal earlier rather than inventing one.:load the root value of a var in another namespace, read at that namespace's
load. check! is not its first reader and cannot be — a var root cannot be
deferred — so the refusal lands at load, naming the switch.:worker read again after the open: on the fsync tick, per write, per solve. A throw
there is swallowed by a catch Throwable that logs a class name, or repeats
every three seconds with the feature silently dead. These are the rows
check! exists for.Where a switch's value is read **besides** `check!` — closed, because an open set of
keywords would be a roster again, with the same drift and none of the checking.
- `:open` an entry point a caller is standing at: a store or log open, the daemon's start, a
request. A wrong value already stops that call and names itself, so
`check!` moves an existing refusal earlier rather than inventing one.
- `:load` the root value of a var in another namespace, read at *that* namespace's
load. `check!` is not its first reader and cannot be — a var root cannot be
deferred — so the refusal lands at load, naming the switch.
- `:worker` read again after the open: on the fsync tick, per write, per solve. A throw
there is swallowed by a `catch Throwable` that logs a class name, or repeats
every three seconds with the feature silently dead. **These are the rows
`check!` exists for.**Every spelling on the roster, sorted. opts/check!'s promise at the process entry point: a
caller who can ask whether a name is one the build reads does not have to find out from
a run that ignored it. config_surface_test holds it to the names the sources
actually name, so a row cannot claim a switch nothing reads.
Every spelling on the roster, sorted. `opts/check!`'s promise at the process entry point: a caller who can ask whether a name is one the build reads does not have to find out from a run that ignored it. `config_surface_test` holds it to the names the sources actually name, so a row cannot claim a switch nothing reads.
Every switch this namespace reads, one row per reader: :names — the spellings it
reads, in the order it reads them — :reader, and :read-at from read-at-kinds.
One roster, not two. An accessor per switch and a hand-written call per switch in
check! are the same set spelled twice, and nothing notices a reader that reaches one
spelling and not the other. What that leaves is this namespace's own failure — a
process that reports itself configured and is not — on the properties that decide
whether a crash loses data. So check! walks this table, and check-switches! refuses
a reader without a row at load.
:read-at carries as a column what the ns docstring's Where a refusal lands section
says about each row. Prose naming switches by hand is a roster too, and one nothing can
check.
Every switch this namespace reads, one row per reader: `:names` — the spellings it reads, in the order it reads them — `:reader`, and `:read-at` from `read-at-kinds`. **One roster, not two.** An accessor per switch and a hand-written call per switch in `check!` are the same set spelled twice, and nothing notices a reader that reaches one spelling and not the other. What that leaves is this namespace's own failure — a process that reports itself configured and is not — on the properties that decide whether a crash loses data. So `check!` walks this table, and `check-switches!` refuses a reader without a row at load. `:read-at` carries as a column what the ns docstring's *Where a refusal lands* section says about each row. Prose naming switches by hand is a roster too, and one nothing can check.
The spellings that mean on, for every boolean switch. One vocabulary rather than
one per switch: a word that works for one switch works for all of them, so nothing is
learned about vaelii.disk.tokens that is false of vaelii.disk.auto-compact.
The spellings that mean **on**, for every boolean switch. One vocabulary rather than one per switch: a word that works for one switch works for all of them, so nothing is learned about `vaelii.disk.tokens` that is false of `vaelii.disk.auto-compact`.
(web-dev?)Is the browser a development server (VAELII_DEV, default off)? A value, not mere
presence: VAELII_DEV=0 says off and read as presence it said on.
Is the browser a development server (`VAELII_DEV`, default off)? A value, not mere presence: `VAELII_DEV=0` says off and read as presence it said on.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |