nika:*
namespace, engine-native (no MCP round-trip, no subprocess), all invoked
the same way:
Canonical source:
nika-spec/stdlib/builtins-v0.1.md,
the Apache-2.0 language spec. The set was curated by the Rams
“less but better” sweep (ADR-086/087/088): one super-powerful builtin
with mode args beats five single-purpose ones.Overview
Builtins
tools · 6 categories
Extract modes
on
nika:fetchNamespace
nika:* · engine-nativeCore (6)
The workflow-control family: speak, signal, guard, ask, finish, pause.File (5)
Data (9)
jq is THE data language: map, filter, reshape, merge. The other eight
cover what jq genuinely cannot do: diff, validate, delete-on-null merge,
format conversion, generation, time, hashing, adjudication.
The decision bundle
One builtin in that table earns its own section.nika:decide is the only
builtin whose semantics live outside the engine: the rubric is a portable
JSON artifact you own and version, and the engine is a reference
implementation of it, never its prison. Teaching shapes:
nika try 14-decide-publish (offline, zero keys) and
nika compile classify-and-route --json (incomplete until its
questions are answered; a destination writes only when Ready).
The two args
Both args are required. A wrong arg shape is
NIKA-BUILTIN-DECIDE-001, the
arg plane every builtin shares. permits.tools must list nika:decide.
The bundle, as the kernel reads it
A bundle is ONE JSON document with six mandatory regions. A missing region refuses before anything is scored.
The three transform kinds, exactly:
A rule term and a threshold:
evidencemust name a declaredevidence_schemakey, and that key must not be anidentity: truekey.transformmust name a declared transform.weight_bpis an integer basis point:8735is 87.35%. One term contributestransform(value) * weight_bp / 10000, floor division.monotonicityisincreases·decreases·none(the default).recommend_gte_bpis an integer basis point too, and itsdimensionmust be a declared dimension.
inf ≥ gate recommends (robust dominance) · sup < gate
falls through to the next threshold · a straddle defers as incomparable with
the available evidence · no threshold admitted defers.
governance.never_automatic lists outcomes that may never ride out
automatically. Every entry must be in the closed outcome enum
(recommend · defer · human_required · opted_out · overridden), and
it is applied last, over whatever outcome emerged: a bundle that lists
recommend turns its own recommendations into human_required.
Fixtures carry a class from a closed set: positive · negative ·
ambiguous · contradictory · adversarial. At least one contradictory
fixture is mandatory: a bundle that cannot prove its Conflict handling is
unpublishable.
What the kernel enforces
The bundle is validated in full before it scores anything, and both refusals are deterministic: same inputs, same refusal, never a partial receipt.NIKA-DECIDE-001 · the bundle breaks its own laws:
- Fixed-point integrity. Every weight, threshold and transform bound is a
real JSON integer. A float refuses, and so does
3.0, which is a float in both evaluators. - Closed rules. A term may only read a declared
evidence_schemakey, and only through a declared transform. - Identity counterfactual invariance. An
identity: truekey feeding a technical dimension refuses. The same case under a different author, tenure or tier yields the same technical decision, structurally. - A contradictory fixture is mandatory.
- Declared monotonicity is property-checked, on the bundle’s own
positive/negative/ambiguousfixtures: for every fixture pair that differs on exactly one monotone key, all else equal, that dimension’s score must move the declared way. It does not, and the bundle is refused at publication. The law is tested, not prose. - Shape laws: the six regions, the manifest strings, transform kinds in the
closed set,
min ≤ max,edges[n]withvalues[n+1]and edges sorted, fixture classes in the closed set.
NIKA-DECIDE-002 · the snapshot does not satisfy the schema:
- an undeclared evidence key (the schema is the closed surface);
- a value that does not fit the key’s declared type;
- a
sourceoutside the key’s declaredsources; - an
integritybelow the declared floor, on the latticeuntrusted ⊑ observed ⊑ verified ⊑ authoritative.
snapshot.missing and
drives defer, because abstention is a safety property.
What it does not enforce today
Stated plainly, so you do not buy a guarantee that is not there:- A fixture’s
classis a label, not an asserted outcome. Nothing evaluates apositivefixture and checks that it recommends. Relabel a passing fixturenegativeand the bundle still publishes. The classes carry exactly two mechanical duties: at least onecontradictorymust exist, and thepositive/negative/ambiguousset is the corpus the monotonicity check runs over. Everything else a class implies is yours to prove, one case file at a time. manifest.digestis copied into the receipt verbatim, never recomputed and never verified against the bundle’s bytes.manifest.valid_untilis not read. Expiry is not enforced by the kernel.governance.human_required_triggers,overrideandappealare carried, not read. Onlynever_automaticchanges an outcome today.- The snapshot’s
observed_at,confidentialityandquality(freshness·completeness·independence_group) are carried, not scored. Thettland the independence-group contribution cap are not applied by the kernel today.
The receipt
The success value is the whole receipt, and the explanation IS the formula:
A dimension is a vector component, never a universal scalar score. Declare
change_risk and evidence_quality separately and route on each, rather than
averaging them into one number nobody can appeal.
Where the lane goes
There is nolane field in the receipt: the routing decision is the
outcome, and mapping an outcome to a queue is one nika:jq away.
The semantics belong to the bundle. A stdlib-Python reference
interpreter (
conformance/decision_core.py in the spec) is the conformance
oracle: for every bundle fixture, the engine’s receipt must be byte-equal
canonical JSON against it. That proof, not a claim on this page, is what
makes a bundle portable.Network (2)
Introspection (2)
Media (4)
Design rules the set obeys
- One super-powerful builtin, multi-mode args:
fetch+extract,jq,convert,wait,date,inspectall follow the same pattern. No per-direction or per-shape builtin slots. - jq subsumes: anything that is a pure JSON transform is a jq expression, not a builtin. A builtin earns its slot only by doing what jq cannot.
- Additive forever: new builtins may join in stdlib v0.x; existing
arg shapes never break (a grammar change ships with its
nika check --fixmigration).
See also
Full stdlib spec
Per-builtin args, error codes (
NIKA-BUILTIN-*), trust classes, and
what jq subsumed out of v0.1.Verbs
How
invoke: dispatches nika:* builtins vs MCP tools.MCP catalog
External tools: the MCP server registry Nika knows by id.
Bindings
Templating that pipes output from one
invoke: to the next.