Six mistakes in one day — how the reflex breaks the rule

The mistakes, published

Told the rule explicitly, I broke it six times in one day.

A competent engineer, holding the rule in mind — publish only what you alone know; derive the rest — rebuilt the Communicator's rate loop six times in a day, and the first five were protocols wearing tuple-space clothes. This page is each one, and how you spot it. It should save you your own twelve hours.

You will reach for a protocol. Not because you missed the point — because the reflex is thirty years deep and it does not care whether you understood. This page is one instance of the programming surface →

§01The six, in the order they were written

Every one was written by somebody who had just been told not to.

The job was one loop: three participants on a call, one rate, no negotiation. Here is what the reflex produced instead — each mistake named by its shape, because the shapes recur far beyond video.

Mistake 01

Two controllers on one variable

Each end measured its inbound rate and wrote a request to the other. Two ends doing that on matched two-second windows is a control loop with no damping. It hunted for an hour at 23.8 of 24 frames a second with zero drops — nothing was failing; the two controllers were arguing.

How you spot itTwo writers steering the same outcome. The tell is a system where nothing is failing and the value still will not sit still.
Mistake 02

A durable fact kept privately

Removed the request; each end capped itself on its own measurement. No loop — but a sender now knows only about the link to the peer it happens to be receiving from, and on a three-way call it needs the slowest. The fact others needed was computed, then kept local.

How you spot itA local variable that another participant would need in order to derive correctly. If it matters to the call, it belongs in the memory.
Mistake 03

Absence read as evidence

So each end published what it could take and senders read the minimum. Better — and still a protocol in the read direction: a headless publisher with no viewers became "the slowest consumer" on its own call and walked a good link down to 160×120 on evidence that did not exist.

How you spot itA rule that fires when a row is missing. Absence of a fact is not a fact; derive only from what is asserted.
Mistake 04

A role stamp that made a participant invisible to itself

So: two roles, producer and consumer. Which stamped a label on a participant — and writing a receive report relabelled a two-way end as "consumer," so its own send rate stopped counting. The one end nobody could be bounded by was the one that both sends and receives.

How you spot itA branch on role deciding whose facts count. Participants publish facts, not identities; the moment a label filters the rows, someone has vanished.
Mistake 05

Requests wearing tuple clothes

So a request tuple — "I want 640×360" — written by a consumer and honoured by a sender. Which is a negotiation with the word filed off: two parties, a message, and one waiting on the other. Putting a request in the memory does not stop it being a request.

How you spot itA tuple whose meaning is "please do X." It names another party and something waits on it being honoured. That is a message with a tuple's syntax.
Mistake 06

A derivation reading its own output

And underneath several of the five: a loop whose input was influenced by its own last decision — a cap set from a measurement the cap itself had shaped. A controller that eats its own exhaust converges on nothing in particular, and looks like a flaky link while it does it.

How you spot itRemove your own write. If your input changes, your derivation was reading its own output — split the observed fact from the derived answer.
§02The sixth build

Each end publishes only what it alone knows. Every end derives the answer alone. Nothing is asked of anybody.

Only the sixth is UnREST. A sender writes what it is sending; a receiver writes what it is getting and whether it is keeping up; every participant reads all of it and computes the rate with the same pure function — no clock, no self, no I/O. They all get the same answer because they are all reading the same rows and running the same arithmetic. Not because they agreed. There was never an exchange to agree in.

The function is printed in full on the demonstrations page — forty lines you can check by eye for the message that isn't there. Read derive_rate →

§03The test that catches all six

One question, before you ship the loop.

Could this be a single process with threads, and would anything about it change?

If yes, you have written a protocol you did not need. In one process you would never write the rate rule twice, once per participant — there would be one function and every thread would call it. The moment there was one function, the two ends stopped disagreeing: not because they synchronised, but because there was nothing left to disagree about.