FrogNet Memory · the contract, first draft
Written from the source, not from intent. Every clause is marked verified, implied, or undetermined — and the undetermined ones are the interesting part. They are not filled in with something plausible, because a contract needs a commitment, and code only has a behaviour. The two are the same only when somebody decides they are. That is a spec-editor's job →
Vocabulary rule: values, names, services, scopes, authority, observations, invariants — never hosts, senders, or receivers. The consequences of distance are in the contract; the mechanism of distance is not.
No part of that identity names a machine. The writer's address is envelope data on the row: not part of the identity, not supplied by the caller, not required to read. The write is an upsert by name — a write under a description that already exists replaces the value there. Two executions writing under one description are not two messages to reconcile; they are writes to the same location, and the second replaces the first.
Freshness is judged on the row's update time, never on a timestamp inside the value. This is load-bearing and was learned expensively: when freshness compared a reader's clock against a writer's stamp, a machine two minutes slow vanished from every roster while publishing correctly, and the only symptom was an empty result. fresh_s=0 means no filter: observe the value whatever its age.
Never written; written and aged past fresh_s; not observable from here at this moment. A caller can separate the second from the others with fresh_s=0, and has no supported means to separate the first from the third. Whether that distinction should exist is the first thing the contract has to decide — a program that behaves differently depending on why a value is absent has reintroduced the topology; an application with a safety invariant must be able to tell "no reading" from "no contact". Both arguments are real.
A value ceases to be observable when nothing re-asserts it inside the freshness window the reader asks for. No delete must arrive; no reaper must run. Crashing is the same thing, slower — there is no cleanup path a failure can skip. A process may register its own writes for removal on exit (the courtesy, not the mechanism); own=False exists for writes that must outlive their writer and age out instead.
These cannot be resolved by reading the code more carefully. They are decisions, not documentation — authorship, not extraction.
The write is an upsert; the last write under a description is what is observed. But what ordering exists among concurrent writes under one description, and on whose clock it is judged, is not stated anywhere and must be. And whether "last write wins" is the contract or merely the current behaviour matters: if it is the contract, an application with an invariant across two values has no supported way to maintain it, and the contract should say so plainly.
The word is used throughout the project — PERM is the authority, the transient is the always-there current value — but there is no stated rule for which value survives when two exist under one description and neither is stale. Is authority per-scope or per-value? Can an application declare itself the authority for a scope, and what does that entitle it to? What happens to a write made without authority?
Within a region that can still exchange state, values written there are observable there under the ordinary rules. Values last written elsewhere remain observable until they age past the reader's freshness window — at which point they cease to be observable rather than becoming wrong. On reunion, when two fresh values exist under one description, which is observed? Authority decides this one, and until authority is specified it is unspecified. How the regions find each other again is the fabric's business, not the contract's.
No transaction across two or more values. No lease or authority-handoff primitive. No single-writer region enforced by the substrate. No ordering guarantee between values under different descriptions. No consensus.
An application needing any of these builds it, on top, using the memory. That is a supported thing to do, and the contract should stop pretending the question does not arise.
Three of these clauses — absence, ordering, authority — are the strongest argument for the spec-editor seat: everything else in the four planned documents is extraction, and these three are authorship. If you want to argue with a clause, bring an oracle — a demonstration that fails on the current code is how a decision gets made here.