A compute model in which state changes only by decision — with its language, compiler, virtual machine, protocol binding, and interface.
open · extend · enrol · signal · tally · decide
S(t+1) = g⁺·A(S,I) + g⁰·S(t) + g⁻·R(S,I) g⁺ + g⁰ + g⁻ = 1
Computers have run input → process → output for eighty years. That is not a criticism — it is a question. Von Neumann answered under what conditions may a machine change state? in 1945, with one arithmetic unit and delay-line memory. It was a good answer.
What is uncomfortable is that it survived eighty years not because it was re-validated but because binary compatibility is a stronger force than good design. Much of what we treat as inherent to computing descends from that one answer: ambient authority, undefined behaviour, out-of-band error handling, audit trails bolted on afterwards and therefore incomplete.
This is a second answer.
**Input → process → output is three stages.
Cooren is five:**
signal → evaluation → authority → consequence → evidence
The two extra are who permitted this and what proves it happened. And "output" splits in two, because the effect and the record are different things — conflating them is how audit trails end up optional.
The same eleven words kept working across systems that had no business sharing a vocabulary. A door lock and a hypervisor VM exit turn out to be the same question — who may commit this state change, among what alternatives, on whose support, and what proves it. One of those is a building. The other is silicon.
The equation came after the implementations, not before. It describes what had already been built, which is why it has not needed amending: it was a description, not a construction.
git clone <this repo> && cd cooren-code
make test # 109 tests, about two seconds
make examples # four programs compile, run, report conformance
make refusals # six programs that must not compile, and do not
make console # the interface, at http://127.0.0.1:8787$ ./tools/cn run examples/door.cn
+ signal badge open=yea keep_shut=nay open_and_alarm=abstain
+ signal interlock open=yea keep_shut=abstain open_and_alarm=nay
+ signal rota open=abstain keep_shut=abstain open_and_alarm=abstain
0 decide open_and_alarm option carries a nay
+ decide open carried
+ commit door door := 'open'
CONFORMANCE: COMPLETE - all axioms held and all were exercised.
A door: a badge reader, a fire interlock, a rota. The interlock dissented on one option. It was refused at full authority with no override available, and the refusal came back as an ordinary value in the same struct as the commit.
Note what replaced the exit code. The machine checked itself against its own nine properties, because "did it behave like a normal program" is the wrong question to ask of a machine whose purpose is refusing.
| No ambient authority | Running is not permission. Holding the token is. |
| No fiat | A one-option session is not representable — it does not parse. |
| No traps | A refusal returns the same struct as an acceptance. |
| Silence is not consent | An option with only abstentions cannot be committed. |
| A veto disqualifies | One dissent outranks any amount of support. |
| No unlimited privilege | Maximum authority still cannot commit what nobody chose. |
| No optional audit | The record is emitted by construction; a gap in it is proof of an unrecorded transition. |
The sixth is the one people miss, and it has a test:
tests/test_axioms.py::Axiom6::test_maximum_privilege_is_not_unlimited_action.
C could enforce none of this. Token class is not a type in C, sessions are not linear, and undefined behaviour is the exact inverse of "refusal is data". Each of these is a build failure, not a runtime check:
examples/refused/fiat.cn:3 session declares 1 option(s) … fiat
examples/refused/impostor.cn:13 'qa' holds a participant token and may never decide
examples/refused/authority_signals.cn:11 'board' holds authority and may never signal
examples/refused/invented.cn:12 'approve_quietly' was never enumerated
examples/refused/partial.cn:3 gate 'half' is not total — missing arm: abstain
examples/refused/left_open.cn:9 session 'r' is left open
The backend then verifies mechanically that no conditional jump was emitted,
that every gate lowered to exactly one selection, and that every state write
carries a decision. cnvm/isa.py defines JMP and JZ precisely so that
check has something to find — a verifier that can only assert about
instructions the machine does not have is asserting nothing.
MANUAL.md |
how to use all of it — commands, every file, writing a program, every refusal explained |
cooren/ |
the substrate: trits, the gate equation, the six primitives, capabilities, the ledger, conformance, admission |
cnc/ |
the compiler — lexer, parser, desugar, checker, codegen, backend verifier |
cnvm/ |
the instruction set, the pointer interpreter, and dynamics.py — the same semantics with no instruction pointer, no call stack, and halting as a fixed point |
csp/ |
a local binding of the Signal Protocol. No cryptography. See SECURITY.md |
cnui/ |
the interface host, for interfaces declared in cn itself |
examples/ |
working programs, and examples/refused/ — programs that must not compile |
docs/ |
LEARN.md first, then AUDIT.md, SELF-HOSTING.md, LANGUAGE.md, PROTOCOL.md, EXTENDING.md |
If you read three files, read cooren/gate.py, cooren/session.py, and
cnc/check.py. Together they are the semantics; the rest is plumbing.
view console "Door" {
panel entry {
title "Open the door?"
writes door
show tally
control signal for badge
control decide by lock
show evidence
}
}
Offer a commit control to someone holding a participant token and it does not compile. Capabilities stay on the host; the browser holds a handle. A capability in a browser is a capability in a screenshot.
Because action requires a capability the display does not hold, presentation carries no security weight — so it can be replaced, restyled, or rendered for a screen reader with identical authority. Accessibility stops being a retrofit and becomes a rendering choice.
Working and tested: the substrate; six axioms plus three completeness properties; branch sessions; elision with record-identity; admission as a session; the compiler front to back; two execution engines producing byte-identical ledgers, one of which has no instruction pointer; the protocol binding; the interface.
Early: ~8,700 lines. cn has each — iteration over an enumerated set,
unrolled at compile time — but no unbounded iteration, no recursion, no
module system. Nothing here targets hardware.
Open, with reasons: docs/AUDIT.md is the standing
audit of inherited assumptions — fourteen items, ten closed, three open, one
that looks like debt and is not.
The caveat that travels with everything else:
Cooren makes decisions accountable. It does not make them correct.
Axiom 1 guarantees the machine never enters a state it did not enumerate. It guarantees nothing about whether the enumeration was right. If the correct answer was not in the option set, the machine commits the best available wrong thing — with a perfect tally, a valid authority, and a flawless audit trail. A system producing immaculate evidence is easy to mistake for one that decides well.
Tell me the domain where this vocabulary breaks.
That is the useful contribution and it needs no credentials. The claim is that one invariant spans identity, scheduling, admission, allocation, firewalls, hypervisor exits and interfaces. Claims like that are worth attacking rather than agreeing with.
There is an issue template for exactly this. Also welcome: a port to another language, a domain example, or a case where the compiler refuses something it should accept.
- Cooren Compute Model — the specification. Published separately, also Apache-2.0.
- Cooren Signal Protocol — the normative wire protocol, a separate work.
The
csp/package here is a local binding and does not interoperate with it.
Apache License 2.0. See LICENSE and NOTICE.
Copyright 2026 McLeod Interactive Group LLC.