One engine. Your corpus. Your name on it.
A lab is one subdomain under lab.ado.earth running the same engine on a different list. Off this namespace anyone may do that without asking. On it, a listing is a claim about what the visitor is running — so it goes through the , and it declares what it is running before it is listed.
A lab is one subdomain under lab.ado.earth. It runs the same engine on a different list. Anywhere else, anyone may do that without asking. Here, a listing is a claim about what the visitor is running. So it goes through the , and it says what it is running before it is listed.
An adaptation with an address
A copy of the same thing, at its own address
Ω.js, τ.js and index.html are byte-identical across every adaptation. Content addressed, they are one cache entry serving all of them. A new lab costs its — a few hundred bytes — plus its corpora, around 8 KB brotli each at the size of the first entry.
Ω.js, τ.js and index.html are byte for byte the same in every adaptation. Named by their content, they are one cached copy serving all of them. A new lab costs its , a few hundred bytes, plus its corpora. At the size of the first entry that is around 8 KB brotli each.
So the constraint is not cost. The marginal lab is essentially free.
So cost is not what limits this. One more lab is close to free.
A different system wearing the same badge
A visitor on <name>.lab.ado.earth reasonably reads the namespace as a claim about the engine. That claim needs someone accountable behind it, which is the entire reason listings are reviewed rather than self-serve.
A visitor on <name>.lab.ado.earth fairly reads the name as a claim about the engine. That claim needs somebody answerable behind it. That is the whole reason listings are reviewed instead of self-serve.
A may be listed. A fork disguised as the reviewed engine may not. That is the one line here that does not bend.
A may be listed. A fork dressed up as the reviewed engine may not. That is the one line here that does not bend.
Anywhere else, no permission. Here, by proposal.
| Where | Permission needed | What governs |
|---|---|---|
| your own domain | None. Fork it, host it, change the engine, change the corpora. | The software licence, and the rights in whatever material you feed it. Nothing on this page restricts it. |
| *.lab.ado.earth | A listing proposal through the doorway. | The declarations below, the standing obligations, and two of three reviewers on rights, provenance and fit. |
The reason is narrow and worth stating rather than assuming: the namespace is read as an endorsement of the engine, and an endorsement with nobody behind it is worth less than no endorsement at all. Listing is not an assessment of whether the lab's research is any good.
The reason is narrow, and worth saying out loud rather than assuming. The namespace is read as backing for the engine, and backing with nobody behind it is worth less than no backing at all. Listing does not say whether the lab's research is any good.
The same rule applies to an internal lab. Alpha Data Omega LLC and its principals may submit a listing proposal; they may not sit on the panel that hears it, and they are conflicted on every proposal touching the canonical engine pin, the ado.earth namespace, or the first corpus.
The same rule applies to a lab run in-house. Alpha Data Omega LLC and its principals may submit a listing proposal. They may not sit on the panel that hears it. They are conflicted on every proposal that touches the canonical engine pin, the ado.earth namespace, or the first corpus.
Five things, declared and displayed.
A lab declares the same things any adaptation declares. Declared in the proposal, and shown in the served interface — not only in the recipe, because a recipe is not what the visitor is looking at.
A lab declares the same things any adaptation declares. They go in the proposal, and they are shown in the interface it serves. Not only in the recipe, because the recipe is not what the visitor is looking at.
The engine hash, visible in the interface.
The engine hash, shown on the page.
The hash of the exact Ω.js, τ.js and index.html served. The main site publishes the canonical one; a visitor must be able to tell in one glance whether they are on the reviewed engine or somebody's variant.
The hash of the exact Ω.js, τ.js and index.html it serves. The main site publishes the canonical one. A visitor must be able to tell at a glance whether they are on the reviewed engine or somebody's own variant.
A lab can ship a modified engine. Then every measured number — needle recall, false-claim rate, never claims foreign material — stops being about the thing in front of the visitor, and stops silently. The hash is what makes that visible instead.
A lab can ship a modified engine. Then every measured number stops being about the thing in front of the visitor: needle recall, the false-claim rate, never claims foreign material. And it stops quietly. The hash is what makes that visible instead.
The corpus list, in full.
The complete recipe: schema, engine pin, ordered parts by , joiner. Ordered, because merging is order-dependent.
The whole recipe: schema, engine pin, the parts in order by , and the joiner. In order, because merging depends on the order.
Every part must be either an admitted registry entry or material the operator has declared rights to. A part that grants nothing cannot be redistributed by the namespace, and silence grants nothing.
Every part must be one of two things. Either a registry entry that has been admitted, or material the operator has declared rights to. A part that grants nothing cannot be passed on by the namespace, and silence grants nothing.
Every API it calls, exhaustively.
Every server it talks to. All of them.
Every origin, pinned in the page's CSP connect-src and shown in the interface. A lab that wants to talk somewhere undeclared then simply cannot — the browser enforces it, not a promise.
Every origin, pinned in the page's CSP connect-src and shown in the interface. A lab that wants to talk to an undeclared place then simply cannot. The browser enforces it. It is not a promise.
This is a privacy boundary before it is an audit trail. A lab that can POST a visitor's prompt to its own API is a thing the visitor needs to know before typing, not in a policy afterwards.
This is a privacy boundary first and a record second. A lab that can send a visitor's prompt to its own API is a thing the visitor needs to know before typing, not in a policy afterwards.
A frame declaration for any live feed.
A rule saying where one thing ends, for any live feed.
Same contract as any corpus. The endpoint declares where one thing ends and the next begins; the appends; the encoder re-derives on a cadence rather than per tick, because appending churns every and deriving is not free.
Same contract as any corpus. The endpoint declares where one thing ends and the next begins. The only appends. The encoder re-derives on a set cadence rather than on every tick, because appending churns every and deriving is not free.
A fresh feed has nothing to claim from until it has been fed, so its first minutes are honest silence. The interface must say waiting — not an error, and not an empty field that reads as a bug.
A fresh feed has nothing to claim from until it has been fed. So its first minutes are honest silence. The interface must say waiting. Not an error, and not an empty field that reads as a bug.
An accountable operator.
Somebody who answers for it.
A contactable person or entity. Not a handle with no route to it.
A person or an entity you can contact. Not a handle with no route to it.
Becoming uncontactable — no response to a governance contact within 30 days — is itself grounds for delisting, because every other obligation on this page depends on somebody being reachable when it is not met.
Becoming uncontactable is itself grounds for delisting. That means no response to a governance contact within 30 days. Every other obligation on this page depends on somebody being reachable when it is not met.
{
"type": "D", listing on the namespace
"subdomain": "<name>.lab.ado.earth",
"operator": { "entity": "", "contact": "" },
"engine": { "Ω.js": "sha256:…", "τ.js": "sha256:…", "index.html": "sha256:…",
"fork": false }, true is allowed; undeclared is not
"recipe": { "schema": "ΑΔΩ/recipe/1", "engine": "Ω.js@<pin>",
"parts": [ "<cid>", "…" ], "joiner": " " },
"origins": [ ], every one. empty means zero requests.
"csp": "connect-src 'self'", must match origins exactly
"feeds": [ { "origin": "", "frame": { "rule": "", "delims": [] },
"rederive_every": "" } ]
}
An empty origins list is the strongest declaration available and it is worth naming. The package as shipped makes no external request at all, which is why it can be served from anywhere and audited by reading it. The moment a lab talks to an API that property is gone for that lab. It is a fair trade for live data, and it should be a stated one.
An empty origins list is the strongest declaration available, and it is worth naming. The package as shipped makes no external request at all. That is why it can be served from anywhere and audited by reading it. The moment a lab talks to an API, that property is gone for that lab. It is a fair trade for live data, and it should be a stated one.
Two of three. Always.
ΘΘ = 3 × ½ = 1.5 1.5 sits between 1 and 2, so it can never be met — only exceeded. Passage is strictly more than 1.5 of 3. That is 2 of 3. Always.
There is one and every proposal passes through it or does not. No side path, no fast track, no delegated authority, and no exception for the author of the rule.
There is one . Every proposal passes through it or does not. No side path. No fast track. Nobody may hand the decision to somebody else. And no exception for the author of the rule.
This is not a governance preference borrowed from voting theory. is the constant the code already runs on — the threshold the field applies when deciding whether to speak or refuse. One constant, two uses. If Θ ever changes in the code, the governance document is already wrong and must be amended before the next proposal is heard.
This is not a governance rule borrowed from voting theory. is the constant the code already runs on. It is the threshold the field applies when it decides whether to speak or refuse. One constant, two uses. If Θ ever changes in the code, the governance document is already wrong and must be amended before the next proposal is heard.
Counted in reviewers, never in percentages
- Exactly three reviewers are seated. Not two. Not four. Not "at least three".
- Exactly three reviewers are seated. Not two. Not four. Not "three or more".
- Two approvals carry it. One does not, however strongly argued.
- Two approvals carry it. One does not, however well argued.
- If three reviewers cannot be seated, the proposal cannot pass. It waits.
- Never carried by a majority of those who happened to respond. A non-response is not a pass, not a refusal, and not a vote of any kind.
- It is never carried by most of the people who happened to respond. No response is not a pass, not a refusal, and not a vote of any kind.
Three , and refusal is first-class
| Verdict | Means | The reviewer owes |
|---|---|---|
| pass | The listing should go up. | Reasons. |
| hold | It cannot be judged as written. | The specific missing thing. |
| refuse | It should not go up. | Reasons. A well-grounded refusal carries the same weight as a passage and is not a failure of the process. |
2 or 3 pass -> passes 2 or 3 refuse -> refused anything containing a hold, or 1/1/1 -> held
Every proposal produces a ledger record whether it passed, was refused, was held or expired — the full text as submitted, the mechanical output verbatim as numbers rather than a pass/fail summary, the three seated reviewers and any recusals, each verdict with its reasons and timestamps, and the hashes of anything it changed. No decision exists without a verdict. No verdict exists without a record.
Every proposal leaves a record in the ledger. That happens whether it passed, was refused, was held or expired. The record holds the full text as submitted. It holds the mechanical output word for word, as numbers, not as a pass or fail summary. It holds the three seated reviewers and any recusals. It holds each verdict with its reasons and timestamps. And it holds the hashes of anything it changed. No decision exists without a verdict. No verdict exists without a record.
Weakness, stated. A fixed three-seat gate does not scale to hundreds of proposals a week, and it stalls completely where fewer than three unconflicted reviewers exist. The correct response to a stall is to wait, or to widen the roster — never to seat fewer than three, and never to convert the doorway to a percentage. A gate that bends under load is not a gate.
Weakness, stated. A fixed three-seat gate cannot handle hundreds of proposals a week, and it stops dead where fewer than three unconflicted reviewers exist. The right response to a stall is to wait, or to widen the roster. Never to seat fewer than three, and never to turn the doorway into a percentage. A gate that bends under load is not a gate.
The gates are code. You can run them now.
Every corpus in a lab's recipe passes four gates before any reviewer is seated. Three of the four are pure computation, they run in CI on the pull request, and they run on a contributor's own machine in seconds — because gate strength is worth nothing if nobody can get to the gate.
Every corpus in a lab's recipe passes four gates before any reviewer is seated. Three of the four are pure computation. They run in CI on the pull request, and they run on a contributor's own machine in seconds. Gate strength is worth nothing if nobody can get to the gate.
node gates.js <corpus.txt> gates 2 and 3, straight away node gates.js <entry.json> all four, using the declared ingest
| Gate | Checks | Bar | State |
|---|---|---|---|
| 0 · form | Required fields present, and an engine pin that is not null, not a range, not latest. | all present | code |
| 1 · reproduces | The declared source, through the declared ingest, lands on the declared τ hash — and the codec round-trips. | byte-identical | code |
| 2 · reads itself | Fed its own material, does it claim, and is it right when it claims? A corpus that cannot read itself is mis-framed, and this is what catches that. | claim ≥ 50% accuracy ≥ 95% | code |
| 3 · not its neighbours | Probed with the shipped three-work , it claims nothing. This is the safety property the whole library rests on. | exactly 0 claims ≥ 360 probes | code |
| human | Rights, provenance, and whether the material belongs here at all. | 2 of 3 | specified, not staffed |
Reviewers do not re-run the gates and do not vote on their results. A reviewer may not refuse on measurement, framing, reproducibility or format — those are gates, and gates have already spoken. What is left is the part that should be human: does the submitter hold the rights they claim, is the stated origin credible, and does the material belong here. The third is openly a matter of taste, and "I do not like it" is a reason that may be given — but it must be given.
Reviewers do not re-run the gates and do not vote on their results. A reviewer may not refuse on measurement, framing, reproducibility or format. Those are gates, and the gates have already spoken. What is left is the part that should be human. Does the submitter hold the rights they claim? Is the stated origin credible? Does the material belong here? The third is openly a matter of taste, and "I do not like it" is a reason that may be given — but it must be given.
What a real run looks like
The gates on the first shipped corpus, run 2026-08-18. Printed unedited, including the failure, because a page that only shows passing runs is indistinguishable from one that never ran them.
The gates on the first shipped corpus, run 2026-08-18. Printed unedited, the failure included, because a page that only shows passing runs is indistinguishable from one that never ran them.
node gates.js Δ/V·001ADMISSION GATES Δ/V·001
15,564 bytes of source
GATE 2 reads itself PASS — reads itself
2,919 states · window 8 · alphabet 66
context probes claimed right when claimed
120 119 119 (100.0%) 117 of 119 98.3%
400 119 119 (100.0%) 117 of 119 98.3%
800 119 119 (100.0%) 117 of 119 98.3%
GATE 3 does not claim neighbours FAIL — 3 false claim(s)
Frankenstein 113 probes · 0 claims
Pride and Prejudice 112 probes · 3 claims
Moby-Dick 111 probes · 0 claims
336 foreign probes · need exactly 0 claims, and at least 360 probes
NOT ADMISSIBLE YET
Gate 3's bar is exactly zero, not "low". Three claims in 336 foreign probes is 0.9%, which would be a respectable number under almost any other rule and is a failure under this one. The same run produced 336 probes where the gate wants at least 360, so it misses on sample size as well as on claims.
Gate 3's bar is exactly zero, not "low". Three claims in 336 foreign probes is 0.9%. Under almost any other rule that would be a respectable number. Under this one it is a failure. The same run produced 336 probes where the gate wants at least 360, so it misses on sample size as well as on claims.
The holdout is shipped and fixed rather than drawn from the registry. Drawing foreign probes from "three corpora already in the registry" was a closed loop — the registry holds one corpus, so corpus #2 could never satisfy it, and therefore neither could #3. The gate was arithmetically unsatisfiable rather than merely strict.
The holdout ships with the code and is fixed. It is not drawn from the registry. Taking foreign probes from "three corpora already in the registry" was a closed loop. The registry holds one corpus, so corpus #2 could never satisfy it, and therefore neither could #3. The gate could not be met at all by arithmetic. It was not merely strict.
Specified, and not yet staffed.
Everything in the section above exists as code and runs today. The review that follows it exists as a rulebook and has nobody in the seats.
Everything in the section above exists as code and runs today. The review that follows it exists as a rulebook, and it has nobody in the seats.
| Piece | Specified | Exists |
|---|---|---|
| Gates 0–3 | yes | yes — gates.js |
| The doorway rule | yes | yes — it is the engine's own constant |
| A reviewer roster of five or more | yes | no |
| Three unconflicted reviewers, any sector | yes | no |
| Deterministic draw, recorded in the ledger | yes | no |
| Continuous check that a served engine matches its declaration | yes | no |
At the time of writing there are not three independent reviewers for any sector. Until there are, nothing can pass. That is the honest state, and it is not papered over with a founder's casting vote, an interim administrator, or a temporarily lowered threshold. The gate holds or it is not a gate. The first real work here is filling one roster.
At the time of writing there are not three independent reviewers for any sector. Until there are, nothing can pass. That is the honest state. It is not papered over with a founder's casting vote, an interim administrator, or a threshold lowered for a while. The gate holds or it is not a gate. The first real work here is filling one roster.
Five is the target roster size because five is the smallest number that survives two recusals and still seats three. A reviewer serves a 12-month term, may resign at any time by saying so, and may not sit on more than three consecutive proposals in the same sector.
Five is the target roster size, because five is the smallest number that survives two recusals and still seats three. A reviewer serves a 12-month term, may resign at any time by saying so, and may not sit on more than three consecutive proposals in the same sector.
Conflicts are self-declared and recusal is mandatory — a conflicted reviewer recuses, they do not disclose and vote anyway. That is unenforceable at this size and the rulebook says so: with a roster of five in a small field everyone will know everyone, and the conflict rule removes the most knowledgeable participants from exactly the proposals they understand best. A slower and less expert review is accepted in exchange for a reviewable one.
Conflicts are self-declared, and recusal is required. A conflicted reviewer recuses. They do not disclose and vote anyway. At this size nobody can enforce that, and the rulebook says so. With a roster of five in a small field everyone will know everyone, and the conflict rule removes the most knowledgeable people from exactly the proposals they understand best. A slower and less expert review is accepted in exchange for a reviewable one.
Standing obligations, and the grounds for removal.
What a listed lab must keep doing, and when it can be removed.
A listing is a continuing statement, not a one-time check. A listed lab must, continuously:
A listing is a continuing statement, not a one-time check. A listed lab must, at all times:
- serve the engine it declared, at the declared hash;
- make no request to any origin outside its declared list and its CSP;
- make no request to any place outside its declared list and its CSP;
- cut range requests and chunk boundaries with
τ.safeCutonly — never at an arbitrary offset; - cut range requests and chunk boundaries with
τ.safeCutonly, never at just any offset; - show waiting, not an error and not an empty field, while a fresh feed has nothing to claim from.
- show waiting, not an error and not an empty field, while a fresh feed has nothing to claim from.
The cut rule has a measured reason. A τ body is .-separated and a truncated cell can be missing from the alphabet. Across 4,400 arbitrary cuts of the 122,870-byte shipped ledger most refused, and none decoded to something untrue — truncation loses the tail, it does not invent one — while 400 of 400 cuts taken through safeCut were exact prefixes of the full ledger. Zero-corrupt is not a licence to cut carelessly: behind a CDN a refusal is still an outage, and decode() throws precisely so the page can report the failure rather than swallow it.
The cut rule has a measured reason. A τ body is split by ., and a truncated cell can be missing from the alphabet. Across 4,400 cuts at any offset of the 122,870-byte shipped ledger most refused, and none decoded to something untrue. Truncation loses the tail. It does not invent one. Meanwhile 400 of 400 cuts taken through safeCut were exact opening pieces of the full ledger. Zero-corrupt is not a licence to cut carelessly. Behind a CDN a refusal is still an outage, and decode() throws precisely so the page can report the failure rather than swallow it.
Delisting
Removing a listing
Any person may file a delisting proposal. It goes through the same doorway.
Anybody may file a delisting proposal. It goes through the same doorway.
| # | Ground | Clock |
|---|---|---|
| 1 | The served engine hash does not match the declared hash. | 24 hours, suspends on passage |
| 2 | A request to an undeclared origin, or a connect-src wider than the declaration. | 24 hours, suspends on passage |
| 3 | Serving a corpus that is not admitted and not covered by a declared right, or one that has been withdrawn. | 10 days |
| 4 | Presenting a forked engine as the canonical one, or removing the engine hash from the interface. | 10 days |
| 5 | Redistributing a corpus outside the terms its author stated. | 24 hours, suspends on passage |
| 6 | Claiming performance, transfer or generalization the measurements do not support. | 10 days |
| 7 | The operator has become uncontactable — no response within 30 days. | 10 days |
A delisted operator may reapply. There is no permanent ban, because a permanent ban is a power this rulebook does not need and cannot supervise.
A delisted operator may apply again. There is no permanent ban, because a permanent ban is a power this rulebook does not need and cannot supervise.
Nothing continuously verifies a served engine hash or a served CSP. Grounds 1 and 2 depend on somebody noticing. Until something fetches each listed subdomain and compares hashes and connect-src against the declaration, these obligations are enforced by chance.
Nothing keeps checking a served engine hash or a served CSP. Grounds 1 and 2 depend on somebody noticing. Until something fetches each listed subdomain and compares hashes and connect-src against the declaration, these obligations are enforced by chance.
That is a missing cron job, not a missing rule, and it should exist before the list is long enough that nobody is watching all of it.
That is a missing scheduled job, not a missing rule. It should exist before the list is long enough that nobody is watching all of it.
Listed labs.
There are none.
No lab has passed the doorway, because no panel has been seated, because no roster yet holds three independent reviewers. The list is empty and stays empty until that changes.
No lab has passed the doorway. No panel has been seated. No roster yet holds three independent reviewers. The list is empty, and it stays empty until that changes.
It would be easy to fill this space with plausible examples marked "coming soon". An empty state that says so plainly is worth more than a list nobody can check — and a fabricated entry here would fail ground 6 on the same page that defines it.
It would be easy to fill this space with made-up examples marked "coming soon". An empty state that says so plainly is worth more than a list nobody can check. And a made-up entry here would fail ground 6 on the same page that defines it.
What it will and will not do.
A lab answers out of the material it was fed, word for word, and refuses when the arrangement you typed is not one it holds. That refusal is the property worth having, and it is why many corpora can share one namespace safely.
A lab answers out of the material it was fed, word for word. When the arrangement you typed is not one it holds, it refuses. That refusal is the property worth having, and it is why many corpora can share one namespace safely.
- About 2% on material it has never been fed. Measured at about 2% on books never fed. If your lab depends on it answering about things it was not shown, it will not work.
- No transfer between corpora. Adding a second corpus does not teach the first anything about it. The same probes scored about 2% before that material was fed and about 92% after — the change is in what was fed, not in what was generalised from it.
- Framing, not subject, decides whether it works at all. Raw EEG and raw controller telemetry have no word boundaries and nothing to probe. Framed at one frame per sample and one frame per event, they gave 100% right when they claimed, on streams of 16,200 and 9,896 bytes. An unframed corpus looks like a broken engine when it is a missing declaration.
- How the stream is cut up, not what it is about, decides whether it works at all. Raw EEG and raw controller telemetry have no word boundaries and nothing to probe. Cut at one frame per sample and one frame per event, they gave 100% right when they claimed, on streams of 16,200 and 9,896 bytes. A corpus with no framing rule looks like a broken engine when it is a missing declaration.
None of this is improved by a subdomain, a recipe, a pin, or a content address. It is the shape of the thing, and a lab that implies otherwise is delistable on ground 6 of its own listing.
None of this is improved by a subdomain, a recipe, a pin, or a content address. It is the shape of the thing, and a lab that implies otherwise is delistable on ground 6 of its own listing.
Terms
- corpus
- The body of text you feed it. That text is the only thing it can answer from.
- doorway
- A rule that only lets a thing through if it beats a number. The number is 1.5 out of 3. So you need at least 2 of 3, and a tie is impossible.
- recipe
- A short list. It names the engine and the material to feed it, in order. Run the list again and you get the same field back.
- fork
- A copy of a recipe that points back at the one it came from. It can add or drop material. The link back cannot be faked.
- CID
- A name made out of the file itself. Change one byte and the name changes. So the name proves what the file is.
- ledger
- The record of what the machine was fed, written down as addresses. It is only added to. Nothing in it is edited later.
- address
- A short string of symbols that says where a thing sits in the field. Two things are alike when their addresses start the same way.
- gate
- A check a thing must pass before it is let in. Three of the four gates here are code, and you can run them yourself.
- Θ
- A fixed number: 3 × ½ = 1.5. It sits between 1 and 2, so it can never be matched exactly, only passed.
- verdict
- The answer about the answer. There are three of them. It is mine and in the same order. Or the words are mine but the order is not. Or it is not mine at all.
- holdout
- Books the machine is never fed. They are used to test it on writing it does not have.
- τ
- The step that turns a place in the field into an address. It splits the disc in four, then splits each quarter again, and writes down one symbol each time.