Cognets
A cognet is a cognition engine: the program that runs a mind.
A game engine runs a game. It holds the game's world, runs its logic many times a second, and draws the result. A cognet does the same for something that senses, believes and acts — a chat agent, a thermostat, a robot mapping a room.
The body is whatever the mind is attached to: a chat window, a simulator, a robot. It sends what it senses and does what it is told. The cognet never touches it directly — which is why the same mind runs in all three.
Why it exists
Most minds start as one loop: read the sensors, call a model, decide, act. That works until the mind grows. Perception, memory, maps and planning all run at different speeds, all depend on each other, and the loop becomes a tangle nobody can trace.
Games hit the same wall decades ago, and solved it with an entity component system. A cognet brings that design to minds:
- Everything the mind believes lives in one world, as plain data.
- Every piece of logic is a small system that says what it reads and what it writes.
- The engine runs the systems on a clock, in the right order, and records everything.
You write the parts. The engine handles the loop, the order, the threads and the record.
How it works
The engine runs in ticks — on a clock, say 60 times a second, or only when something arrives for a chat agent that sleeps between messages. Every tick:
- Senses arrive. Whatever the body felt since the last tick lands in the world.
- Systems run. Each reads what it declared and writes what it declared. The engine
orders them from those declarations: a system that reads
temperatureruns after the one that writes it. Nobody writes that order down. - Actions leave. Whatever the systems told the body to do.
Systems never call each other. They only meet in the world.
What you write
Components are what the mind can believe. Plain types, in any of the three languages:
// types/room/room.components.ts
export interface Temperature {
celsius: f64
sensed: f64
}
export interface Heating {
on: boolean
}
Systems read some components and write others:
// src/room/warmth.system.ts
const TARGET = 21
export default defineSystem({
reads: ["temperature"],
writes: ["heating"],
run() {
for (const room of ecs.query({ components: ["temperature"] })) {
ecs.set({ id: room.id, components: { heating: { on: room.temperature.celsius < TARGET } } })
}
},
})
Put three of these together and you have a thermostat. The engine wires them by what they read and write:
Pick a language per system, not per project. A cognet can be all TypeScript, all Python, or whatever each part is best written in — the world doesn't know the difference.
What you get for free
Because every system declares what it reads and writes, the engine knows the whole mind's structure before it runs a single tick. That buys:
| Order | Systems run in the order their data implies. No main function, no call graph. |
| One owner per belief | Two systems writing heating is refused before the first tick, by name. |
| Parallelism | Systems that share nothing run on other cores, untouched. |
| A full record | Every value read and written, by whom, on which tick. |
That record is what the debugger reads. Ask who writes a belief, and who depends on it:
$ axonl debug graph --component heating
{"ok":true,"data":{"name":"room/heating","writtenBy":["room/warmth"],"readBy":["room/heat"], …}}
Where to go next
- Three languages — one mind that follows a person, in whichever language you pick.
- Systems — how systems declare, schedule, and run.
- Cognet structure — where every file lives.