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.