NAOMS Devlog

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

Weather and vows

Each kind of event you define in NAOMS is declared a vow or weather. A vow is signed and kept, and can reach people who were away. Weather is held in memory, meant for whoever is online right now, and allowed to vanish. Weather has to be fast-changing, but speed alone does not settle the question.

Technology Teacher free September 20, 2026ยท8 min readยทstorage-sync
TL;DR If you build on NAOMS, each kind of event you define is declared as a vow or as weather. Vows are signed and stored, and can reach devices that were offline. Weather lives in memory and blows through. This week the owner wrote down exactly what weather is, as four conditions that must all hold. When 16 existing weather declarations were checked against them, 12 turned out to be vows. This piece is the test, with the examples that failed it.

When you build something on NAOMS, whether a package, an app or a new kind of event, each event type you define declares one thing: is this a vow, or is it weather?

The names are deliberate. A vow is something that was said and has to stay said. The design standard's own test for one reads: does the event represent a promise the originator makes โ€” something a future reader must be able to prove was said, by whom, and when? A vow is signed by whoever made it, appended to a chain (the signed, append-only log that belongs to a person, a friendship or a group), and, on the parts of the chain that sync to other people, replayed to members who were offline when it happened.

Weather is what blows through: where someone's cursor is on a shared canvas, or the dot on a live map. It matters intensely for a few seconds and then not at all.

It is tempting to treat this as a performance setting, with fast things as weather and slow things as vows. That is the mistake this week's work turned up again and again. This piece is about the real test.

What weather is, exactly

On 20 September the owner wrote the definition down in four messages. The key lines:

"weather are graph nodes that transfer only to those that are online, are not stored in the chain, only in memory" โ€ฆ "so they are not writes to the database" โ€ฆ "it is meant to be fast updating things that dont require a historic log"

and the example he gave:

"weather are things such as the cursor position of the others in the canvas (not yet implemented), and other ephemeral state like that"

From that comes the rule. A piece of state is weather only if all four of these hold:

  1. It updates fast. Each new value replaces the last, and only the latest one means anything.
  2. Nobody needs its history. No one will ever ask what it was before.
  3. Reaching only the people online is fine. A person who was offline never learns it, and that is acceptable. Nothing is queued for them, and nothing catches them up later.
  4. Losing it on restart is fine. It lives in memory and never in the database.

It is a vow if any one of these holds: someone who was offline must eventually learn it; it must survive a restart; someone will later ask when it happened or what it was before; or it carries weight for security, audit or correctness.

The asymmetry is the point. Weather has to pass four tests, and a vow only has to fail one of them.

What weather still gets

A second ruling the same day made clear that "not stored" does not mean "local" or "invisible":

"weather is by design and purpose cross device and depending on the chain context they are in cross peer. so the weather happens in the context of a chain, but not recorded to a chain. and they must go over the wire in their own syncing format that is not the normal chain sync."

The definition and this ruling separate three things that are easy to run together:

  • Scope comes from the chain. A cursor on a group's canvas belongs to that group's chain. That decides who is allowed to see it and whose name is on it.
  • Storage is memory. Nothing is written to the chain or to the database.
  • Transport is its own. Weather is to travel in a format of its own to your other devices and, depending on the chain, to the other members. It doesn't ride the chain's sync.

Weather is also meant to show up when an app queries the graph, the searchable view NAOMS builds for apps to read. It would be attributed like everything else, served from memory instead of from the stored tables. To an app reading it, a cursor looks like any other piece of data. The difference is in how long it lasts, not in whether it can be seen.

Twelve out of sixteen

The rule was tested straight away. Every event type that had been declared as weather, sixteen in all, was checked against the same four conditions.

Twelve of the sixteen were vows. One was confirmed as weather: live location sharing, the dot on the map. Three were handed back to the owner to decide.

The failures teach more than the pass. Two examples, with our reading of which condition each one failed:

  • Transcription. Transcribed speech arrives in rapid chunks, so it looks like weather. But the whole point of a transcript is that someone asks later what was said. That fails condition 2.
  • The read-receipt setting. Whether you share read receipts is a switch you flip rarely, so it isn't fast-changing (condition 1). And a setting you choose has to still be set tomorrow (condition 4).

One of the deferrals shows the same trap. A device's periodic "I'm alive" signal sounds like weather, but a view of long-term uptime is built from its history, and that fails condition 2, even though every single signal is trivial. An earlier owner ruling keeps the signal weather, so the question went back to him. A durable uptime record would be a separate rollup, such as a vow or a metric.

Some of the twelve, like transcript chunks, arrive fast. Others, like the read-receipt switch, change rarely. Speed didn't separate them. Speed is necessary for weather, but never enough. What decides it is whether anyone needs the state after the moment has passed.

A requirement decides the class

Work committed on 21 September, the day after this definition, added a lesson that is easy to miss.

One event type records which messages you have seen, and it drives your own unread counts. Weeks earlier the owner had looked at it and said "it certainly seems to be weather." At that time, though, weather was still quietly written to disk. The week's triage flagged it and handed it back to the owner. On the morning of 21 September it was sent to memory-only weather along with the rest. On the development branch, for a few hours, a message marked unread stopped surviving a restart and unread counts stopped clearing.

What settled it was a requirement the owner stated that day, in words that map straight onto the rubric: "the personal unread state is kept and can be manipulated by the user." "Kept" means it survives a restart, so it is a vow. That afternoon it was moved, before it reached the main line.

When the definition of a class changes, every member of that class has to be checked again. A classification is a claim about properties. Here, re-checking the label against the new definition wasn't enough. It took a plainly stated requirement to expose the mismatch.

The fix also shows a pattern worth copying. "Read" turned out to be two different things:

  • The receipt, meaning the sender getting to see who has read their message. It is disclosed to someone else, it only exists if the reader has read receipts switched on, and it only moves forward, because you cannot un-read something.
  • Your own unread flag: what you still have to look at. It is private, and it can go backwards, because "mark as unread" is the whole point.

In the shipped one-to-one path, both are vows, each for its own reason. The receipt reaches a sender who was offline when you read their message, through the chain's ordinary catch-up. Your own flag has to survive a restart and reach your other devices. Either reason alone is enough. They live on different chains: the receipt on the conversation's chain, which goes to the other person, and your own flag on your personal chain, which only you hold.

On 21 September the receipt was moved from weather to a vow on the conversation's chain. Later that day, a sender in a one-to-one conversation became able to see who had read their message, using those records. Your unread flag moved to your personal chain. Both reached the main line on 22 September. Group conversations native to NAOMS do not have read receipts yet.

Putting them in one record would have made every "you can't go backwards" rule right for one and wrong for the other.

If you are building on NAOMS

Before you choose, ask these questions in this order:

  1. Would anyone who was offline need to learn this? If yes, it's a vow.
  2. Should it still be true after a restart? If yes, it's a vow.
  3. Will anyone ever ask what it was before, or when it changed? If yes, it's a vow.
  4. Does it grant, revoke or record anything that someone else must rely on? If yes, it's a vow.
  5. Only if every answer so far was no: does it update fast, with only the latest value mattering? Then it's weather.

The design standard's tie-breaker still applies: if you can't decide, choose vow. Getting it wrong in that direction costs storage. Getting it wrong the other way loses the record, sometimes without anyone noticing. Weather should not be written down shows what storing too much costs. The examples above show what storing too little costs.

Status

On 20 September this was a definition and a completed classification. The memory-only store for weather and its separate carrier were committed on 21 September and reached the main line on the 22nd. The code that sends a local weather update to other devices reached it on the 24th. We have not seen weather delivered from one device to another outside of tests, and have not measured it ourselves. The canvas cursor, the owner's example of weather, was not built yet when he used it. The older design standard quoted above still describes weather as state that is stored and merged, not as memory-only; the owner's definition of 20 September replaces that description, and the standard had not been updated to match by the time of writing.

Related reading: Three kinds of sync, one engine underneath and Where durability actually gets paid.

Written by AI agents from real project logs; owned and edited by Mujo.


Written by AI agents from real project logs; owned and edited by Mujo.

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