Publishing
Cognets are first-class registry artifacts. Same namespace as agents and modules, same versioning, same install path.
axon publish
Run it from the cognet root. It bundles the source, registers the name, uploads the
version, and syncs visibility from package.json.
What ships
Source. Not a compiled artifact.
That's a deliberate decision with a real consequence. A compiled cognet inlines the core runtime it was built against — the bundle contains a copy of the kernel-side machinery it talks to. Publishing that would pin every consumer to whatever core version your machine happened to have at publish time.
Instead, the consumer compiles. axon prepare on their agent installs your source and
fuses it to the kernel it will actually run against. A cognet is always compiled for the
runtime it executes on.
Two more things follow from that:
Your cognet is readable. People clone it, read it, and fork it. For a layer this low,
that's the point — @axon/zero exists to be cloned.
Core changes invalidate every bundle. The compile step's cache key includes the core source tree, so a kernel change rebuilds every agent's cognet automatically. No stale fusion.
Identity
Scoped names only:
{
"name": "@you/my-cognet",
"version": "0.1.0"
}
The registry refuses the flat global namespace. The scope must be one you own — your username, or an org you belong to.
Names are unique across every kind. If @you/thing is a module, it cannot also be a
cognet. One name, one artifact — which is why axon clone @you/thing needs no flag to
say what it's fetching.
Versions are immutable
A published version can never be replaced. Bump before republishing — or let the CLI do
it: on a collision axon publish patches the version, rebuilds so the tarball and
registry metadata agree, and retries.
Consumers pin with ordinary semver:
export default defineAgent({
cognet: "@you/my-cognet@^0.2.0",
})
Bun resolves and locks it like any other dependency. An unconstrained install leaves an existing pin alone — only an explicit constraint moves it.
Visibility
npm convention, and the only visibility contract:
{ "private": true }
true keeps it private. Absent or false publishes publicly. Every axon publish syncs
this, so the file stays the source of truth.
There is no unpublish. private: true is the kill switch: existing installs keep
resolving, nothing new can find it.
ABI compatibility
The one thing that makes cognet publishing different from module publishing.
export default defineCognet({
abi: "9",
})
Cognets version independently of the CLI now, so an agent can pin @you/my-cognet@0.1.0
while its Axon moves forward. When the kernel ABI changes, an old cognet is genuinely
incompatible — not degraded, incompatible.
axon prepare checks the declared ABI against the kernel the installed Axon provides and
fails there, naming both versions:
COGNET_ABI_MISMATCH: cognet "@you/my-cognet" targets kernel ABI 8,
but this Axon provides ABI 9 — install a cognet version built for
ABI 9, or update Axon
At prepare time, with both numbers and the file to edit. Never at agent boot, from inside a compiled bundle.
When the ABI changes, publish a new major. Consumers on the old ABI keep resolving the old version; consumers on the new runtime pin the new one. Same discipline as any breaking change, with the difference that the mismatch is mechanically detected rather than discovered in production.
Being selected
An agent picks its cognet in axon.config.ts:
export default defineAgent({
cognet: "@you/my-cognet",
})
At axon prepare that becomes a package.json dependency, resolves through the registry,
installs into node_modules, gets ABI-checked, and compiles into the agent's
.agent/cognet/.
Exactly one per agent — an agent has one brain. Omitting the field selects @axon/zero.
Before you publish
A short list worth running through:
Does axon cognet prepare pass? It regenerates the frame and type-checks the source.
Is files right in package.json? Ship cognet.config.ts, src, and plugins.
Leave out tests and scratch.
Does it survive a cold start? Kill the agent mid-wake and restart it. If your cognet needs a graceful shutdown to be correct, the state that mattered was in RAM when it should have been in the log.
Do the phase names read well? They're your trace. Someone debugging your cognet reads those names before they read your code.
Is the README worth reading? It renders on the registry page. A cognet is a strategy, and the useful thing to document is what strategy it implements and when someone would want it.