NAOMS Devlog

Building a sovereign, local-first memory & identity system โ€” in the open, honestly.

NAOMS engineering update

Week 1

The first week of the project, and the one everything later stands on. Roughly 1,014 commits, most of them writing down foundations rather than shipping surfaces. Everything the week touched is below, the largest threads first and every area with its own account at the end.

Commits
1,014
(1,006 authored, 8 merges)
Busiest day
2026-03-19
301 commits
Lines added
~494,000
Lines deleted
~31,000
Net line movement
โ‰ˆ+463,000
writing and design, not code
Process Dispatch free March 22, 2026ยท22 min readยทmeta

Commits per day โ€” Week 1

Four things changed this week

One per major area, none touching the same code. This is the first window in the series, so each of them is a beginning rather than an improvement on something described before, and each has a longer account published the same week.

1

You can speak a question and hear the answer

Speech goes in at the microphone and comes back out of the speakers. Listening, answering and speaking all run on the machine sitting in front of you.

2

A process you describe once now runs itself

NAOMS can carry a defined process forward on its own. It pauses, resumes, and picks the work back up where it stopped, including on a different machine.

3

Memory recall caught up with the published best

Recall was measured against a standard long-conversation benchmark and landed level with the best published result, across five runs rather than one lucky one.

4

Every change became a signed, linked record

Identity, permissions and memories enter the system as signed events, each carrying the hash of the one before it, so a rewritten past cannot stay hidden.

Speaking to a memory that never leaves the machine

An illustration, not a screenshot โ€” week 1 shipped no user interface, and the first browser client does not exist at that commit, so there is nothing from the week to photograph. It draws what the week actually built: an event is written down and signed, each entry carries the fingerprint of the one before it, altering an old entry breaks every entry after it, and memory, identity, consent and governance all read from that single record.

The feature: asking your own memory a question out loud, and hearing the answer spoken back.

Before: nothing was spoken. Every question was typed and every answer read. Now: you talk, and it talks back. The audio never leaves the computer at any point in the exchange.

A voice interface that sends audio away is a different product from one that does not. The two look identical in a demo. They differ in what a person is willing to say in front of the machine, which is the only property of a voice interface that finally matters. Someone weighing where their sentence is going has already stopped talking naturally.

What was built. The path has five hops and each one runs locally: the microphone captures, a speech-recognition model turns the sound into words, NAOMS answers the question from your own memory store, a synthesis stage turns that answer back into sound, and the speakers play it.

The recognition hop is the one that usually goes to a server, because good transcription used to be something only a large machine could do well. Running it on your own computer is the choice this week made, and it is the choice the rest of the path depends on โ€” the other four hops are cheap by comparison.

The exchange also holds its place across turns rather than resetting after each question, so a follow-up can lean on what was just said. A session could be switched into voice and back, and the voice work was folded into the memory layer directly instead of bolted alongside it, which is the whole chain, hop by hop.

Each hop is also replaceable on its own. Recognition, answering and synthesis are separate components rather than one bundled service, which is what makes a local swap possible at all โ€” a hosted equivalent arrives as a single thing you either use or do not.

"No cloud in the middle" means the audio and the text of your question are handled by processes on your own machine. It does not mean the machine is offline, and it makes no claim about what other, unrelated software on that computer is doing.

Nothing in that chain reaches out. That is the whole claim of the week, and the value of it is that it can be stated in one sentence and checked against the behaviour of one machine.

A narrow claim stated narrowly is the only kind worth publishing, and it is worth repeating exactly as narrowly as it is true: the path runs locally, on a machine that already has the models installed.

Why the boundary is the feature, not the voice

Speaking to a computer is old. Speaking to a computer that holds your own memories is not, and the difference is entirely about where the recording of your voice ends up.

A question asked out loud carries more than its words. It carries who else is in the room, what you sound like, and often the thing you would not have bothered to type. That is precisely the material a memory system accumulates, and precisely the material people are right to be careful with.

There is a second reason, less about privacy than about structure. The project holds that a system must be complete in itself โ€” able to do its core work on one machine with the network gone โ€” and a voice feature that dies when the wireless drops would quietly break that promise for a core function, which is the argument set out in why the values cannot be taken one at a time.

Keeping recognition local means the sentence exists as sound in one place and as text in one place, both of them yours. There is no third copy on someone else's disk to reason about later, because there is no third copy.

That also changes what an outage means. A local path degrades when your machine is busy; a hosted one disappears when a company changes its terms, its prices, or its mind. Only one of those two failures is yours to fix.

The cost is real and worth naming. Models have to be present on the machine, which means disk, a download, and a setup step that a hosted service would have absorbed. This week bought privacy and independence by spending installation.

When the answer is "I don't know yet"

Asking out loud raises a question that typing hides: what should the machine say when it cannot answer? The same week gave that a shape. An answer now arrives with a list of what could not be reached and a note of where the rest came from.

The list is drawn from a fixed vocabulary rather than written freehand, so a thin answer has to say which kind of thin it is โ€” refused, capped, still arriving, or genuinely nowhere to be found. An open list would let every new failure quietly file itself under "unknown".

The search that produces an answer is bounded at every step โ€” how wide it may reach, how long it will wait, how many requests may be in flight. A search that runs forever can never tell you it is finished, and one that cannot finish cannot tell you what it missed.

If your own records are not enough, the question can travel to trusted peers, but only when your privacy setting allows it. With that setting closed you get your local results and a plain statement that nobody was asked, rather than an emptiness you might read as an answer.

What survives, and what did not

The capability survives to today. You can still speak to your memory and hear it answer, and the local-only stance born this week held rather than being quietly traded away later.

The command surface from March did not survive. The specific commands typed to reach the voice path have since changed, so this week's instructions describe a shape that has moved on. That is ordinary for a first week, and better said than left to imply the March interface is the current one.

One honest gap sits around all of it. No screenshots exist for this window, because the only surface was a terminal dashboard nobody captured. Every claim here rests on the record of the work rather than on a picture of it โ€” which is the trade the project took on deliberately when it decided to work in public from the first week.

A process you describe once, and a machine that keeps its place

The feature: defining a process โ€” a sequence of steps with rules about what may follow what โ€” and having NAOMS carry it out for you.

Before: a process was something a person drove, step by step, holding the place in their own head. Now: it is described once and executed by the system, which pauses when it must and resumes where it stopped.

Resuming is the hard half, and it is the half that gets skipped. Running a sequence of steps is easy while nothing interrupts it. The interesting question is what happens when the machine is closed halfway, and the answer is what separates a script from a runtime.

What was built. Five pieces landed, each doing one job: a compiler that turns a written agreement into eight process definitions, a runtime that moves between states or refuses, persistence so a run's position outlives the process that made it, enforcement that understands where in a process a request arrives, and federation so a run is not confined to one machine.

The compiler is the least obvious of the five and does the most for a reader. It means the rules a process obeys are written in the same document a person would read to understand the process, rather than translated by hand into code that then drifts away from it.

Eight definitions came out of that first compilation. Because they are data rather than code, the rules of a process can be stored, inspected and reasoned about without reading the program that runs them.

Hand translation is where process systems usually rot. The document says one thing, the implementation says another, and the gap is discovered by someone who followed the document and got refused. Compiling the rules from the text removes the gap by removing the second copy.

Why the position has to live outside the runner

A defined process here means something narrower than a to-do list and wider than a script: a set of steps, plus rules about which step may follow which, plus the conditions under which the whole thing may proceed. Written down that way, it can be checked as well as run.

The runtime is deliberately narrow. It is always in exactly one nameable state, and an arriving event either makes a legal move or is refused โ€” no partial progress, no being in two places at once. That narrowness is what collapses a half-finished process down to a single value, and a single value is something you can write to disk.

A process holding its own place is fine right up to the moment it stops existing. Then the place goes with it, and the only recovery is to start over and hope the earlier steps were safe to repeat.

Writing the position into storage instead makes resumption a read rather than a reconstruction. It also makes a paused run inspectable, which is the difference between a process you can trust and one you have to watch, and it is where the river-remembers account gets its name.

Federation extends that across machines. If the position is a record rather than a memory, the machine continuing a run need not be the machine that began it โ€” the run is a thing in storage, not a thing inside a process.

Enforcement is the fifth piece and the one that keeps the other four honest. Rules that do not know where they are get applied uniformly, which means they get applied wrongly: a step in the middle of an approved sequence is not the same request as that step arriving cold.

The shape underneath it

Making the position a record rather than a memory is one instance of a pattern the same week wrote down for everything else the system stores. Changes are appended as signed events; the screens and the graph you actually read are rebuilt from those events and can be thrown away, which is the argument in why your data can always be rebuilt from scratch.

The rebuild only holds because the logic that builds the readable surface is forbidden from looking at its own previous output. Let it peek and replaying the same history twice can land in two different places, and the guarantee that the surface is a faithful function of the record is gone.

The event underneath all of it carries its own proof โ€” a signature naming its author, the hash of the event before it, and enough context to be checked on its own, which is the one idea the rest of the system stands on.

Three properties fall out of that one shape. Tampering is visible, because altering an old record breaks every link after it. Authorship is provable, because each record is signed. And two devices replaying the same records land in the same state, with nobody adjudicating.

The rule the week drew from that is blunt: anything that can be recorded as an event must be. State kept in a side table beside the record starts to drift, and a thing that drifts is a thing that can eventually disagree with the record while both still look correct.

There is a small consequence worth naming, because it shows the standard being applied to the system's own convenience. When a requested value has to be clamped to a legal limit, both numbers are recorded โ€” what was asked for and what was enforced โ€” rather than the enforced one silently replacing it.

Where a rule meets whoever is asking

Enforcement that knows the position also has to know who is standing at it, and the same week set out how that works. People, collectives and AI agents walk one identity path rather than a human path and a separate, lesser one for software.

The practical consequence is the shape of a mistake. When an ordinary automated system does something wrong the failure is a smear with no edges; here it has an actor, a delegation that was granted, a scope on that delegation, and an outcome that either fell inside the scope or was stopped at it.

The two halves are left in tension rather than resolved. Dropping the standing would make the limits unremarkable, and dropping the limits would make the standing dangerous, so the week kept both and said so.

Standing comes with limits that run in a specific direction โ€” from whoever delegated, not down from a platform above. An agent cannot widen its own authority, extend its own budget, or refuse its own termination, an argument the week made at length in person, not user.

The line drawn against consensus

The cryptography arriving this week comes from the same family of ideas as the ledger systems, and the week wrote down exactly how far it was willing to follow them. Signatures, hash-linked records and custody trails were taken. A globally agreed ledger was not.

The reason is the completeness commitment. A system whose core function waits on strangers agreeing is not complete on one machine, and a personal memory does not have the problem consensus exists to solve โ€” the authority over your own record is you.

What was left behind, and what is unproven

One choice from this week is named in the retrospective as the thing to leave. The engine's durability was tied to one external graph database, which was reasonable for a bootstrap and wrong for a system that has to be whole on a single offline device. The principle outlived the implementation; the dependency did not.

What the engine does not yet do is the interesting half of its future. Nothing this week demonstrates a run recovering from an unplanned failure rather than a clean pause, and nothing demonstrates two machines disagreeing about where a federated run had reached. Both are ordinary conditions and both are unproven.

What this means, in plain terms

Most of what lands in a week belongs to the thing it landed in. A few things generalise past it. These five are the ones this week actually paid for, each learned by building the thing rather than by reasoning about it.

A capability that needs someone else's server is a capability you rent

The voice path runs entirely on the machine: microphone, recognition, answer, speech. The same feature built against a hosted recognition service would demo identically and behave differently the first time the network is gone or the terms change. Where a capability runs is part of what the capability is.

The position of a running process belongs in storage, not in the process

The workflow engine writes each run's place into durable storage rather than holding it in memory. That single choice is why a run survives a restart, why a paused run can be inspected, and why another machine can continue it. Anything that must outlive a crash has to be written down before the crash.

An empty answer that cannot say why is asking you to guess

Every answer now arrives with an account of what could not be reached, drawn from a fixed vocabulary of ten named gaps โ€” four meaning something refused or capped, six meaning something is still on its way. "Nobody has it" and "we did not ask" stop looking identical, as the receipt sets out. A closed list of failures forces new ones into the open.

Claim the smallest thing your measurement supports

Recall matched the published best on a long-conversation benchmark โ€” low-forties against low-forties, five runs, one percent spread, reached by fixing three real bugs rather than tuning until the number looked good. The note said "matches", not "beats", and said only that. An overstatement costs you the next honest number too.

A pattern without a policy is a belief without enforcement

A safety check everyone agreed with carried a standing exception, and that exception had already been widened once to work around its own side effects. Removing it, rather than tidying it, is what made the rule real: a check that meets a situation it does not recognise now refuses instead of waving it through. Understanding a rule and enforcing it are two separate pieces of work.

How much healthier is it than a week ago?

Metric Value What it counts
Commits 1,014 Every commit in the window: 1,006 authored plus 8 merges
Busiest day 301 Commits dated 2026-03-19, the highest of the seven days
Lines added ~494,000 Added lines across the window's diff, dominated by documents and seed data
Lines deleted ~31,000 Deleted lines across the same diff
Net line movement โ‰ˆ +463,000 Added minus deleted, under the same rule

This is the first window in the series, so every figure stands alone. There is no previous value to set beside it, and publishing the value by itself is the honest way to say so rather than inventing a baseline.

Every later dispatch compares against the window before it under one stated rule. That rule starts here: a figure is quoted with what it counts, and a figure that cannot be reproduced from the record is not quoted at all.

The line figures are approximate and are published as approximate. They are dominated by writing rather than by code, so they measure how much material moved, not how much product was built.

A commit count is a weak measure of a week and is published here because it is the one figure that can be reproduced exactly. It says how often work was recorded, not how much of it mattered, and this window's own line totals are the clearest demonstration of the gap between the two.

The per-day shape: 85 on 03-16, 152 on 03-17, 227 on 03-18, 301 on 03-19, 173 on 03-20, 25 on 03-21, 43 on 03-22. It climbs through the working week and falls away across the weekend.

Week-1 commits per day, drawn from the per-day counts above. This is a chart made from the numbers, not a captured screenshot of any product surface โ€” no screenshots exist for this week, because the only surface was a terminal dashboard with no saved images. The 03-19 peak of 301 is highlighted.

In one line

a spoken path to your own memory now runs end to end on your own machine, a defined process can be handed to the system and resumed after an interruption, recall was measured level with the published best, and most of this week's half-million lines are writing rather than code.

Four honest notes.

The line count is not a code count. Documents, research and seed data dominate the diff, so reading +463,000 as product code would overstate the week by a wide margin.

Nothing here was verified by looking at it. No images exist for this window's surfaces, so every claim rests on the record of the work rather than on a capture of the running product.

The benchmark result is quoted as parity rather than as a single digit. Two notes written the same day give the headline number slightly differently, and neither was re-run for this report, so the honest form of the claim is level with the published best.

The busiest-day figure counts every commit dated that day, merges included. It describes the shape of the week โ€” a mid-week climb and a weekend fall โ€” and should not be read as a measure of how much was finished on any of them.

What changed, area by area

Everything that moved this week, in plain terms and in rough order of how much of it moved. Per-area file counts are not available for this window, so each area is named without one rather than with a figure that cannot be reproduced.

Several entries here are pieces of writing rather than running code. They are listed because they are what the week produced and what later weeks are built against, not because a document is a feature.

The four threads

Voice.

Speaking a question and hearing the answer now works end to end on one machine.

The path runs microphone, speech recognition, NAOMS, speech synthesis, speakers, and it holds context across turns rather than answering one question at a time. Recognition is the hop that would normally be hosted, and keeping it local is what the week's claim rests on.

Workflows.

A process described once is now executed, paused and resumed by the system.

Five parts landed together: a compiler that turns a written agreement into eight process definitions, a runtime that makes a legal move or refuses, persistence and resume, enforcement that knows where in a process a request arrives, and federation so a run is not tied to the machine that started it.

Memory recall.

Recall was measured against a standard long-conversation benchmark and came out level with the best published result, in the low forties on the benchmark's own score, across five runs with a one percent spread.

Three concrete bugs were fixed to get there. Two same-day notes quote the headline digit slightly differently, so the claim is stated as parity rather than as an exact figure.

The signed record underneath everything.

Identity, permissions, memories and votes became one shape: an event signed by its author, carrying the hash of the event before it and enough context to be verified alone.

Tampering with an old record breaks every link after it, so history can be added to but not quietly rewritten.

The rest of the running system

Storage.

Reading and writing were split into opposite directions.

Writes append to the signed record; the graph you query is rebuilt from it and can be discarded entirely, and the logic doing the rebuilding is barred from reading its own previous output so that a replay always lands in the same place.

Honest answers.

Answers gained a receipt: a list of what could not be reached, drawn from a closed vocabulary of ten named gaps, and a record of where the rest came from.

Four of the ten mean a refusal or a limit, six mean something still on its way, and the system rather than the app reading it decides which is which.

Asking beyond your own device.

A question that your own records cannot answer can now travel to trusted peers, but only if your privacy setting permits it โ€” otherwise you get your local results plus an explicit note that no peer was asked.

Every step is bounded by how wide it may fan out, how long it waits, and how many requests may run at once, described in how a question travels .

Classification.

Sorting your own notes moved to a local model, and that model became the default rather than the fallback.

A from-scratch local runner landed with it, so the path needs no outside AI service at any point โ€” this is the week the local-only stance began, and it began by being made the default rather than offered as a setting.

Local model runner.

A runner built from scratch executes models on the machine without an outside AI service, which is what both the voice path and the classification default stand on.

It is not a feature anyone opens; it is the reason two features on this list can make the claim they make.

Scheduling.

Work can now be scheduled and orchestrated without a person triggering it.

The job scheduler and task orchestrator were renamed Kronos this week, and both are still in the product today.

Identity and setup.

Creating an identity became a single one-time ceremony: start the background service, run founder setup, and write down a recovery phrase shown exactly once.

The setup refuses to guess which ceremony you meant and refuses a secret typed on the command line, as the zero-to-first-identity walk-through shows.

Research, rules and writing

Protocol and ledger study.

The heavy ledger and identity ecosystems were read and a deliberate line drawn: keep the signatures, hash-linked chains and custody trails, reject the globally-agreed ledger.

Hyperledger and GNU Taler are both named, the second as proof that strong cryptographic guarantees do not require consensus at all, in why we adopt protocols and skip blockchains .

Sync research.

An encrypted graph-sync engine was read end to end and the conclusion recorded in four words โ€” sync, don't replace.

What came home was the commit-graph model for data, the idea that a key is the permission, and permission to carry several conflict-resolution strategies at once; what stayed behind was the runtime itself, per the reading of NextGraph .

Rules the project applies to itself.

The hole drilled in a safety check turned out to be the most honest signal about the check, because every use of it marks a case the rule did not fit.

The exception was removed rather than tidied, after being widened once to work around its own side effects, and a check meeting a situation it does not recognise now refuses rather than waving it through, told in the bypass is the signal .

Personhood and agents.

The week argued in writing that people, collectives and AIs walk one identity path rather than a human path and a lesser bot path, and that an agent's mistakes have edges โ€” an actor, a delegation, a scope โ€” where an ordinary automated failure is a smear.

The same piece keeps the agent stoppable, in person, not user .

Design writing, and where it started.

Thousands of lines of philosophy, projections and ontology landed, which is most of what the line count measures; none of it is a feature and all of it is what later weeks are built against.

The project's own first commit was an archive file imported from an earlier attempt, recounted in chapter zero .

โ† more in Process   home โœฆ   all โ†’