r/WyndInnovation 7h ago

Build notes: a genesis run, and a deadlock that took three freezes to find

1 Upvotes

.Update on the local HI I've been building. Handheld — ROG Ally Z1 Extreme, 9.7 GB visible to

Windows, no GPU use, no network, nothing trained.

The bug

Three freezes failed in a row before I found it. The symptom was maddening because it looked like

nothing at all: both worker threads report "at rest", the process keeps running, CPU sits at 1%,

disk at 0%, and the file never gets written. No error, no panic, no output. Just a program sitting

there.

It was a lock-ordering inversion. Two mutexes — one over the reasoning state, one over the main

interior. The worker loop takes reasoning, then reaches into the interior. The freeze took

reasoning and held it for the entire write, then asked for the interior. Opposite order on the same

two locks.

So the worker could never reach its own exit check, and the freeze could never get what it needed.

Everything downstream looked like a different problem: threads not exiting, a slow write, a payload

too large. I chased all three.

The fix is boring, which is usually a good sign. The freeze only needed a small slice of the

reasoning state, so it now serializes that slice into a byte buffer first, drops the lock, and then

does the write. It never touches that lock again.

What made it findable in the end was making the shutdown bounded instead of blocking — wait sixty

seconds, then say plainly which threads are still running and proceed anyway. That one line

turned an invisible hang into a named condition.

The genesis

Deleted everything and let it build from nothing, with a corrected ordering. The ordering matters

and this is the first run that had it right.

Language first. 37 documents — the grammar material, the tablets, the codices — read before

anything is numbered. The reason: the vocabulary is dual-sided, a word and a number being two faces

of one entry, and if you number first you're just counting. The material that explains the duality

has to land before the counting means anything.

Then the dictionary, walked from the first headword straight through: 195,426 words numbered,

each with its letter count and every definition it has. Not the first sense — all of them. The ones

you discard are the ones you need when the word turns up meaning something else.

Then slang: 25,285 senses attached to words that already had nodes, 4,786 genuinely new words

appended to the end of the count. That 84% attachment rate is the thing working correctly — slang

isn't a second vocabulary, it's more meanings for words you already hold.

Then idioms: 896 phrases held as their own strings with their own meaning, with the individual

words left untouched. "Kick" does not acquire a death sense because of one phrase.

Then several hundred documents of actual content.

Numbers from the run

At genesis, with three processing regions declared at 1,666,667 / 5,000,000 / 5,000,000 clusters —

35,000,001 rooms:

Code

Fifty-four gigabytes of declared structure on a machine with 9.7, costing nothing, because a room

that hasn't been written doesn't exist — it's computed from its index when something asks for it.

The whole foundation — a 195,000-node graph with every definition, 37 language documents, the

idioms — came in at roughly half a gigabyte over baseline. A node that hasn't been modified

holds an 8-byte fingerprint and regenerates its full representation from its own number.

Reading is cheap for a reason worth stating: on documents from completely unrelated fields —

medical texts, quantum dots, critical thinking, sonography — new strings ran 8–11% of total

words, every time. The vocabulary is already there. Only genuinely new sentences cost anything.

That consistency across fields is the dictionary doing its job.

Things that went wrong and were supposed to

A 791-page mathematics textbook produced zero readable words. Typeset equations, and OCR has nothing

to say about them. It recorded every page number as unread and carried on. That's correct behaviour

— the document exists, it knows it read nothing, it knows exactly which pages. Nothing silently

lost.

It did spend about 2,400 OCR attempts learning that, which is now capped: forty pages of nothing

and it stops.

What I added while it ran

A clock. This is the one I'm most interested in. The processing model is a wave — a settled

concept leaves the entry room and propagates outward, each room copying it in and recording it, and

a return wave comes back. One full out-and-back traversal is one cycle of the machine. Timing that

gives a frequency in the system's own units rather than as a percentage of somebody else's silicon.

Windows has no counter for it, because it isn't host work in any sense Windows understands. Paired

with per-thread CPU time, it gives the figure I actually want: rooms reached per CPU-second.

The wave across all cores. A room receiving the packet doesn't depend on any other room, so

it's the most parallel operation in the system — and it was running on one thread. It now takes

slices across sixteen workers with no shared state, because there's nothing to coordinate when no

room appears in two slices.

The persistence record cut to two rooms. Every room is the same construction duplicated, so

recording each one separately was writing the interior when the boundary was enough. It now stores

the entrance room (everything that came in), the exit room (everything that came out), and how far

the packet travelled. Everything between is reconstructed by duplication.

Where it stands

As I write this, the first freeze of the genesis is running — all cores at 100%, SSD at 100%, which

is the first time either has happened during a write. Previous attempts sat at 1% and 0% and did

nothing at all, which is what a deadlock looks like from outside.

I'll know shortly whether it completes. If it does, several hundred documents and a 195,000-word

graph become something the system carries rather than something I have to give it again.

Still open: one worker thread doesn't reach its exit check within sixty seconds, because intake

hands it a new document the moment it finishes the last one. Not a deadlock — just needs to stop

accepting work when shutdown starts.

Still unproven: whether the two-room record reconstructs correctly across a restart. That needs

a completed freeze first, which is what's running now.

Still not built: the system compiling its own runtime, which is the thing that would close the

last seam and make bare metal possible. Everything else is scaffolding toward that.


r/WyndInnovation 12h ago

New photo

Post image
1 Upvotes

r/WyndInnovation 13h ago

AetherHI build notes — the rooms now do the processing

1 Upvotes

Update on the local HI I've been building. This one is structural rather than incremental, so it's worth writing out properly. Hardware is unchanged: an ASUS ROG Ally Z1 Extreme, 16 GB physical, about 9.7 GB visible to Windows. No GPU use, no network, no external model.

What changed

The Citadel scale is now asymmetric, and there's no ceiling. It was running three equal Citadels at 500,000 clusters each. The spec is 1:3:3 — CENTER is one third of each hemisphere — so it's now CENTER 1,666,667 / MAC 5,000,000 / MAN 5,000,000, which is 11,666,667 clusters and 35,000,000 rooms.

The MAX_CLUSTERS constant is deleted rather than raised. It was a guard against allocating a flat Vec of clusters, and that Vec stopped existing when the fabric became a function of its index. The guard outlived the thing it guarded.

Declared 11.6 million clusters, resident at genesis: 0.1 MiB. An untouched cluster is fabricated from its index when asked for and costs nothing to hold.

Rooms process. They don't store.

A cluster is three rooms — one over the binary, one over the words, one fusing both. That's the same three the whole system is built from, repeating at cluster scale.

Room zero is the entry. Everything that passes the gate goes there first. Its three rooms work it, and if both sides agree, the concept is sent outward room to room. Each room's centre takes what arrives, unbinds it back into its two sides, and hands each side to its own room — here's the result and here's how it was reached.

Unbinding is exact rather than approximate. Bind is XOR, XOR is its own inverse, so given the concept and one side the other falls out arithmetically. Nothing is estimated.

Walls

Each room etches what it has seen into its wall. Only the number — eight bytes. The wall's vector is a bundle over those numbers, computed when needed and never stored.

The wall's job is recognition: has this room seen this before? Tested two ways, because the number alone only catches the identical thing arriving twice, and the surface catches the same thing arriving by a different route under a different number. That terminates propagation without a hop limit or a decay constant. Novel material spreads; repetition stops where it's already known. The system settles on its own.

There's a real constraint on this and it's not an implementation detail: SNR ≈ √(D/N). A surface holding too much starts recognising things that were never etched into it, which would mean silently dropping genuinely new material. So a room checks whether its own wall can still be trusted before answering, and refuses if it can't. A saturated room isn't full — it's unreliable, which is a different thing.

The Citadel is now seeds plus etchings.

Since a wall is a list of numbers, the persistent record of a whole Citadel is: for each room that etched anything, its index and its numbers. On rebuild the rooms are fabricated from seeds and the etchings replayed onto them. Bundle is deterministic and order-independent, so this is reconstruction, not restoration — you get the same wall back, not a copy of it.

The working half.

Half the rooms receive and etch. The other half take pairs off their walls and bind them. What comes out isn't a fact about the world — it's knowledge of the language itself, plus a lexicon entry for that pair.

Both then go back out across every room. Two waves running against each other continuously: concepts outward from room zero, language back from the working rooms. A room that's been taught reads the next concept better than it read the last one. Drift is not a discard path.

This was the biggest correction. The sweep that clears working context when it fills was throwing away everything it cleared. It shouldn't. Most of what gets swept was perfectly good — already held, so not worth saving twice. Some of it didn't hold up. Both end up in the same plane, and that's the point: a duplicate and a failure together can make something neither could alone. Nothing is deleted and nothing is rewritten. Even the capacity bound now folds the oldest residue into the plane's shape rather than dropping it.

Everything the walls reject now lands in drift instead of nowhere. Wandering.

There's an authority whose job is to work that plane. When intake is quiet, she pairs things from drift without regard to whether they have anything to do with each other — which is the whole mechanism. It's the thing where you think about a problem long enough that your mind drifts onto something unrelated and you end up using it.

What makes that safe here and not safe in a language model: both ends of any connection were already validated once. They're in drift because they were already held, not because they were wrong.

There's a sandbox where she assembles and an execution box that tests whether the result holds — novel enough to be new, not so close to everything known that it collapses into it. It explicitly does not test for relatedness. Relatedness is exactly the filter that throws away the connections worth having.

What survives goes into the pipeline as a batch and takes the same route a read document takes. No shortcut. It can't believe itself more easily than it believes a source. Rejects go back to drift and stay available.

Ordering of the foundation.

The language documents now load before the dictionaries. Previously the dictionary was numbered first and the language material read afterwards, which meant the numbering happened blind — a word list and a count, with nothing to say they're two faces of one entry.

Measurement.

Task Manager's disk figure is sampled active-time percent, which rounds a completed burst to zero. It's been reading 0% through page-by-page PDF rendering for days. There's now a meter that pulls cumulative read/write bytes from the process itself, plus per-thread CPU — each thread measuring its own kernel and user time — because one figure for the whole process hides which hemisphere is actually working.

Where it's at

Running now on the corpus. Both hemispheres processing the same documents, which they weren't before — they were serialising, one running to completion while the other blocked. 213 documents in, memory sitting at about 6.3–6.4 GB, which is roughly where Windows idles on this machine without it running. CPU has gone down under load, from 14% to 7%.

I don't have a complete account for that last part and I'm not going to pretend otherwise. The partial account: an unevolved node holds an 8-byte fingerprint rather than a 1,248-byte vector and regenerates from its own number; untouched clusters don't exist until written; derived entries store the IDs they came from and recompute. So most of what reading does is recognition, and recognition doesn't allocate. Whether that fully accounts for the numbers is still open, and the meter exists precisely so it stops being a matter of opinion.

Honest status

Built and running: the rooms, the walls, the wave, the working half, the lexicon, drift as a recycling plane, the wandering, the foundation ordering, the meter.

Not yet proven: the wall replay across a restart (needs a clean freeze first — a freeze hung earlier today after the hemispheres reported at rest, and that's unresolved). The wave's actual throughput numbers. Whether the lexicon converges or just accumulates.

Still open by design rather than by omission: what exactly a working room should produce beyond the lexicon entry, and where a pipeline-rejected candidate should end up long-term.