nikaia describe Is a Nikaia Program, Because This Language Has To Be Written InStatus: Superseded by ADR-290 — its D1-D5 are D11-D15 there
Date: September 22, 2026
Target Version: Nikaia 0.0.155
Answers: open-decisions.md’s is nikaia
describe written in Nikaia? — option A, and the owner’s reason is not the
one that page led with
Narrows: ADR-193 D4’s second step, a real parser (syn)
replaces the scraper — the parser is a grammar
Related: ADR-002 D4 (the pre-lowering this ships by),
ADR-104 D4 and D5 (what the command reads, and that its draft is
reviewed), ADR-194 D1 (the subtraction that puts an OS resource in
std), ADR-009 D4 (measure before choosing a shape — and where
that rule does not apply)
nikaia describe reads a Rust crate’s pub signatures and writes a draft
ledger. It is 843 lines, and the half that reads is a hand-written character
scanner — split_top_level, items_of, fields_at, line_starts,
signature_at, matching — which its own module header apologises for: a
signature scraper and not a Rust parser.
ADR-193 D4 said the answer was syn. The owner asked whether the
command should be written in Nikaia instead, where the reading half is a
grammar — which is this language’s headline feature.
And the page that carried the question got the shape of the decision wrong. It recommended writing a grammar first as a measurement that would settle the question. That was a category error, and correcting it is D5.
nikaia describe is written in Nikaia, and the reason is that this language has to be written in.Eat your own dog food. Not as a slogan: a language whose own toolchain is
written in another one has no user who is forced to live with its gaps, and
every gap this tree has found was found by running something. describe is
the first tool that can be written in Nikaia without anything else moving, so it
is the one that gets written in it.
This is a decision about the project and not about the shape, which is why no number stands behind it.
std’s own Nikaia half does.The compiler compiles without describe: NK2504 names the command and a
person runs it. So there is no cycle to break.
It ships by ADR-002 D4’s route, unchanged — the .nika kept
beside the .rs, pre-lowered at release, so a binary install compiles the
.rs and needs no compiler to do it. nikaia lower-std is the release step
that already does this for std; describe rides the same one.
syn step is replaced by it.Everything else in that record’s five steps stands: the column, the note, the
unsafe impl Send/Sync flag, the call graph, the use table. What changes is
which parser.
And the grammar removes the class rather than the instance. All three of the
scraper’s named limits come from its being a scanner; the one that survives a
real parser — an item a macro generates — survives syn too, and for a reason
that is neither parser’s (ADR-001 D1, the same wall that keeps
rustdoc-JSON out).
std gains a directory walk and a subprocess.A crate is read by reading its .rs files, and ADR-193 D4’s first
step wants cargo metadata. std has neither today.
Both are operating-system resources of exactly the kind
ADR-194 D1 just put the socket in std for, so
ADR-069 D2’s subtraction covers them without a new argument: what
was pushed out of std was the protocol and the framework, and a directory is
no more HTTP-shaped than a socket is.
The entry this record answers proposed writing the grammar first, as a
measurement that would settle the question. It would not have.
ADR-009 D4’s measure before choosing a shape applies where two
shapes are genuinely on the table — Rc against Arc, a match against a
perfect hash, a boxed future against impl AsyncFn. Here the choice is made on
a reason about the project, and no number could have moved it.
So what a number would mean here is different, and it is worth saying once for
every record that comes after. If the Nikaia describe turns out slower than
the scraper, that is a finding about this compiler and an amount of work
owed — not a reason to go back. A measurement that cannot change the decision
is still worth taking; calling it the reason for the decision is what this
record refuses.
describe is the right first one, because its output is reviewed by a
person (ADR-104 D5). A tool that stands between a program and
a foreign crate is security-adjacent (ADR-193 D3’s asymmetry),
and a reviewed draft is where that risk is bearable.std grows by two, and both were coming anyway: every real tool walks a
directory and most run something.std pieces, a grammar over a subset of Rust, and
the command rewritten — against 843 lines of which the scanner is the part
that has been wrong three named ways.describe needs is pub fn,
pub struct and impl headers and the type grammar under them; what it
cannot translate it writes ?, which is ADR-104 D4’s own
sentence and does not change.threads note’s own steps, which are ADR-193 D4’s and
stand.Nothing yet. The order of work, and the first step is usable on its own:
examples/foreign-runtime/ already has,
against the scraper’s own output — not as a gate, but because a parser is
worth having before the program around it;fs gains a directory walk, and a subprocess beside cli;.nika, in the sysroot, pre-lowered at release
by nikaia lower-std’s own step;use
table, the call graph, the unsafe impl flag.#124 carries it.