D353 - The harvest is a command, and writing it twice found a bug
decided ยท 2026-08-27
D352 widened the FreeBSD checkout and harvested 903 constants - with
a throwaway script that existed nowhere afterwards.
docs/REFERENCES.md sets the standard the table then failed:
"anyone should be able to fetch the same material and follow the
same reasoning to the same table." Nobody could.
orbistoun-gen constants <checkout> --revision <commit>
is the fix, and it is not a new shape - orbistoun-gen is
already one module per generated table, and
orbistoun-cli harvest already does exactly this for names.
The source path becomes an argument, which matters more than it did this
morning: the throwaway script hardcoded
<clones>/freebsd-src, and everything moved to
<OOPS> an hour later.
--revision is required. A table that
does not say which revision it came from cannot be checked against
anything, which is most of the reason to harvest rather than
remember.
Writing it twice found a bug in the first one
The command produced 911 constants where the script produced 903. The eight it had been silently dropping:
AT_EACCESS AT_RESOLVE_BENEATH FD_RESOLVE_BENEATH IP_MULTICAST_IF
KERN_PROC_INC_THREAD NET_RT_IFLISTL O_RESOLVE_BENEATH ST_INFO_HW_HPREC
Every one has a comment that runs onto the next
line. The script's regex required the comment to close on the
same line, so it rejected the whole definition rather than the comment -
losing AT_EACCESS = 0x0100 and
IP_MULTICAST_IF = 9 entirely, with nothing saying so.
That is the failure this project keeps meeting from a new direction. A harvest that silently drops what it cannot parse produces a table that looks complete, and there is no way to tell a constant that is absent because it does not exist from one absent because the extractor tripped. It was found by having two implementations disagree, which is the only reason anybody looked.
And the fix had the same shape one level down
Taking those eight meant their comments end mid-sentence.
AT_EACCESS would have been described as "Check access
using effective user" - which stops precisely where it stops
meaning anything, and reads as a whole sentence. An unterminated comment
now ends in .... One character, and the difference between
a description and a description-shaped fragment.
What is deliberately not harvested
#define X (Y | Z) is skipped rather than evaluated.
Working out what it comes to means reproducing a decision somebody made
about how to compose it, and the number is not the point - where it came
from is. Function-like macros are code. Lower-case names are
internal.
The headers are a list, not a directory walk: every entry is one somebody needed, and a walk would pull in hundreds nobody has looked at, making the file larger, the provenance question vaguer, and "why is this constant here" harder to answer.