D304 - The repair searched for an index it could compute
decided · 2026-08-26 · audit --repair
ran for five hours on thirty-three names
Growing a vocabulary renumbers every derivation index built from it
(D213), which is ordinary and expected - the loop invalidating its own
earlier records is the price of the loop working.
audit --repair re-derives them in one sweep, and after a
morning's vocabulary work it was given thirty-three names and did not
finish in five hours.
Not a hard problem. Pattern::name_at is a
mixed-radix decode: each part contributes a digit,
least-significant last, and the index is read off by repeated division.
Its inverse is the same arithmetic backwards. But
solve::derive does not invert it - it
searches:
for pattern in patterns {
for index in 0..pattern.len() {
if pattern.write_at(index, &mut buffer) && buffer == wanted { … }A linear scan of a space this project measures at 1.52 trillion candidates, thirty-three times over, for something a division answers.
So Pattern::index_of computes it: split the name against
the pattern's own vocabularies - backtracking where a slot has several
words that could start the remainder - then combine the chosen positions
as the mixed-radix number name_at would have decoded.
Bounded by vocabulary size times pattern depth, not by their
product.
The search stays for the case it was written for.
derive is also what answers "could this repository have
produced this name at all?" for a name with no
record - and there the pattern is unknown, so there is nothing
to invert against and walking is the only honest answer. That is
--deep, it is documented as slow, and it is a different
question from "this name was generated by that pattern and the
vocabulary moved underneath it".
Worth stating because the failure was invisible from the outside: a repair that has not finished looks exactly like a repair that is being thorough, and the gate stays red either way with nothing saying which.