Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

CVN

CVN is the shape an application takes when its kernel cannot touch the world and its host cannot decide anything.

  • The kernel holds a Model and an update that is total and synchronous: every action returns a new model and a list of Cmds — data describing effects, never the effects themselves.
  • A host (node, web, native) performs Cmds through ports it declared, and hands the kernel the capabilities it cannot own: a clock, timers, storage, the network, randomness.
  • A declaration on the runtime says what the kernel owns, what it still borrows, and what the host must provide. The port is done when the borrowed list is empty — and the gates make sure "done" was not written by hand.
   action ──▶ kernel.update(model, msg) ──▶ [model', Cmd[]]

                                       dispatcher records, then drains

                                    host.performNow(cmd) ─▶ ports

CVN was extracted from impl-super-mvp, where the whole application runtime was moved into this shape one borrowed method at a time, with every claim tied to code by a gate. What is in this package is what survived that: the dispatcher, the state cell, the runtime, one host contract with node and web behind it, a conformance suite every host runs, the gates, and cvn/enc — the ENC rules the port surfaced, each pinned by a Lean model whose cases the real code replays.

import { createRuntime, router, performed } from '@enc-protocol/cvn'
import { createNodeHost } from '@enc-protocol/cvn/node'
 
const host = createNodeHost()
const rt = createRuntime({
  initial: { count: 0 },
  runAction: (cell, perform, path) => {
    if (path === '/inc') cell.commit({ count: cell.value.count + 1 })
    if (path === '/save') perform({ kind: 'persist', key: 'count', value: cell.value.count })
  },
  performNow: router({
    persist: (cmd) => (host.store.setJSON(cmd.key, cmd.value), performed()),
  }),
})
rt.action('/inc')
rt.action('/save')

Start with Concepts, then The rules. If you are implementing a host, go straight to Hosts and Native.