This is the addendum I promised at the end of the first post. The day after it went up, my father's development notes arrived: 1,114 pages of journal, dated from August 1996 to three weeks ago. The right way to use a record like that is not to read it front to back; it is to ask it questions. I gave it to the same agent that built the service and had it cross-reference every finding I had sent him against the journal, page numbers and all, then read the entries that mattered with the findings beside them. Then I rebuilt the parts of the service the notes said I had done the long way round. This post is what changed, with the pictures I did not have the first time.
What the journal settled
Seven of my twelve findings turned out to be design choices or known corners, written down
years before I tripped over them. The temp-file collision that made me serialise transfers
is a 2019 decision to seed the file-name generator from the init file so compiles are
repeatable; daemon children inherit the seed. The root jail without /tmp is a
2023 choice from the web-server work. The period at the end of every statement is a parser
hint: with it, a different grammar rule wins. Reaping is switched off in the shipped build,
from July 2025, and a receive deliberately runs the engine's inference pass. The "scared"
rule that never fired is vocabulary: the word is both an adjective label and a verb in this
word list. And the motive map format I had called undocumented is described twice, in 2017
and again this July.
The biggest thing in the notes was not a finding at all. From December 2023 on, the journal describes a peer layer built into the engine: websocket links between running copies, with protocols for one copy sharing its context with another, for two copies trading contexts, and for querying another copy's memory store. His reply confirmed it: he has not run the text daemon in years; this is how he works. I had built the service on the daemon and the console because that is what the release's help text shows. So round two starts there.
His peer layer, measured
Every knowledge node now also runs the engine's web server, and the shim can open a peer link
between two nodes with one console command on the first: wsconnect <ip> 4145
node-a node-b bhpeer. From then on, every statement made on either node reaches the
other as it is said. No transfer, no image on disk. Here is one statement crossing, drawn to
scale from the measured numbers:
Three things the console path could not do, this one does. A rule taught on one node fires on
the other. why? keeps its referent on the receiving side, which the whole-context
transfer loses. And it costs nothing per transfer, because there are no transfers. The
trade-off is honest too: only what is said after the link opens travels, and a link is not
forwarded. I tested both of those properly because the difference matters for any design that
wants knowledge to spread.
So a mesh works because every pair has its own link, and a chain stops after one hop. If you want a fact to reach everyone, you link everyone, or you use the transfer for what it is good at: seeding a node with everything another one knows.
Motives, which were blocked, now run
The whitepaper's Phase 2 needed a motive map, and the release ships none. The journal has the
format, so I wrote one: three motives, core, kitchen and
garden, with deliberately overlapping vocabulary and two trigger sentences. It
loaded on the first try. Say "i am hungry" and the engine shifts into the kitchen motive,
asks the question that motive carries, and still answers everything it knew before. Two
practical things surfaced on the way: the engine compiles each motive file to a binary beside
the source, so the directory has to be writable, and a motive's pending question is repeated
after every input until you answer it. Both went into the tests.
What a hub remembers
The first post left one number open: a node that gathered everyone else's context seemed to hit a ceiling around the sixteenth merge. I now have the picture instead of the number, and the picture says something different. First, the starting state, with twenty-four nodes each holding five secrets nobody else has:
Then every node's context is transferred into node-01 in turn, and after each merge the hub is asked every donor's first secret again. Reading down a column is one donor's secret over time; reading across a row is what the hub answered right after that merge:
That block-wise flush is not a merge count. I ran the same gather three ways. With one question per merge, the hub still answered every donor after all twenty-three merges. With five questions per donor, it kept fifteen. With every donor re-asked after every merge, as in the grid above, it kept two. What the hub retains depends on how much is asked between merges, because every question is itself an entry in the context, and the context is a bounded buffer that lets go wholesale. The journal describes it as a buffer that is "continually preened," in a 2012 entry. The question for him is now what decides what stays, and whether that depth is something the service can set.
Where the milliseconds go
I also went back and did the benchmarking properly. The shim now times each turn in four phases, and a separate harness talks HTTP to it directly instead of paying for a client process per turn, which is where round one's numbers had about 20 ms of overhead hiding.
Over three hundred single-threaded turns the shim-side mean is 68 ms with a p95 of 88, and a sixty-turn conversation grows its image by about 240 bytes a turn without the restore and capture getting slower. For a symbolic engine parsing and inferring on every turn, on one core, with its whole context loaded and saved either side, I still find nothing to complain about.
One new thing for the list
A node whose peer partner has been restarted keeps working, and keeps listing the link as open, until its next console receive, and then its child dies. It took a specific sequence of my own test suites to expose it, and it is reproduced cleanly in a spike with the log lines. The service works around it by tearing peer links down before it transfers, and by reopening dead children once. It goes back to him as finding thirteen, with the retention question, a request for a motive map of his own, and the newer vocabulary he says we are behind on.
Who actually wrote this, again
Same as last time, and it still matters for how far to trust the numbers. The engine and the notes are my father's. The shim changes, the two new test suites, the dissemination harness, the benchmark harness, the chart pages these figures come from, and most of the words in the documentation were produced with an AI coding agent, Claude Code, working under my direction: I chose what to build from the notes, what counted as passing, and what to send back. Every figure on this page was rendered from a run I watched and can rerun. The journal was worked the same way: the agent indexed the 1,114 pages against my findings and produced the cross-reference; I read the entries it surfaced, checked the quotes against the PDF, and decided what they meant for the design. Thirty years of notes answered in a day is the point of the tool.
Later the same day: the newer vocabulary arrived. What a generated dictionary has to know about the grammar, with the scoreboard.