Skip to content

The port catalogue

DNA's kernel is a microkernel: it knows how to store, validate, version and compose instances, and nothing else. Everything else is a typing.Protocol — a port — that something outside the core satisfies. There are 61 of them.

Most of this page exists to answer one question: I want to change X — what do I implement? 39 of the 61 are things you are meant to implement. The rest are listed anyway, marked as what they are, because a seam you cannot see is indistinguishable from a seam that does not exist — and guessing wrong costs more than being told no.

What the three roles mean

Role Meaning
extension point You implement it. A third party can ship one without touching the kernel.
handed to you The kernel implements it and passes it in. You call it; you never satisfy it.
internal seam A back-reference between the kernel and one of its own collaborators, published as a Protocol so the decomposition stays honest and testable. Not a plug-in surface.

All 61 ports

Storage & retrieval — where instances live (10)

The ports the kernel uses to answer where is this, and how do I get it back. This is the plane with the most shipped adapters and the only one with a full conformance battery, so it is also the best documented place to start if you are writing your first port.

Port Module Role What it decides Shipped
BundleHandle dna.kernel.bundle.handle extension point Reading and writing one bundle's files 2
CachePort dna.kernel.protocols extension point Where installed dependencies are cached 1
EmbeddingPort dna.kernel.protocols extension point Turning text into vectors 2
KernelEventBus dna.kernel.boot.eventbus extension point Cross-process cache invalidation 1
ReaderPort dna.kernel.protocols extension point How a bundle format is detected and parsed 10
RecordSearchProvider dna.kernel.protocols extension point Semantic search over record-plane instances 2
ResolverPort dna.kernel.protocols extension point How an external dependency is fetched 5
SourcePort dna.kernel.protocols extension point Where instances are read from 3
WritableSourcePort dna.kernel.protocols extension point …and how they are written back 3
WriterPort dna.kernel.protocols extension point …and how it is written back 11

Source capabilities — the optional slices (8)

A source adapter's mandatory contract is WritableSourcePort. Everything a store might additionally be able to do — keep versions, hold drafts, resolve overlays, store bundle entries — is a separate, opt-in Protocol here.

These exist so the kernel never has to ask hasattr(source, ...). That matters more than it sounds: the kernel needs to know what your store cannot do before it reads, so a face can refuse honestly instead of serving a confident empty answer. Read what your declaration turns on before you implement any of them.

Port Module Role What it decides Shipped
BundleEntryReadable dna.kernel.capabilities extension point Read one entry out of a bundle
BundleEntryWritable dna.kernel.capabilities extension point Write or delete one entry in a bundle
Draftable dna.kernel.capabilities extension point Draft / publish lifecycle
KernelAttachable dna.kernel.capabilities extension point Accept the kernel after construction
LayerAware dna.kernel.capabilities extension point Writes accept a layer overlay
Layered dna.kernel.capabilities extension point Overlay (tenant / layer) resolution
TenantAware dna.kernel.capabilities extension point Writes accept a first-class tenant
Versionable dna.kernel.capabilities extension point Per-Kind semver versioning

Kinds & extensions — what behaviour DNA knows about (8)

The kernel knows no Kinds. Every unit of identity and composition arrives through these ports, which is why adding a Kind never touches the core.

Port Module Role What it decides Shipped
Extension dna.kernel.protocols extension point A package of Kinds, readers, writers and hooks 1
ExtensionHost dna.kernel.protocols handed to you The registration surface handed to an Extension
KindPort dna.kernel.protocols extension point What a Kind is, and how it composes 1
KindPresentation dna.kernel.protocols extension point How a Kind previews and draws itself
KindRelations dna.kernel.protocols extension point What a Kind points at
ManifestActivator dna.kernel.protocols extension point Turn an extension's declared instances into runtime behaviour 2
TemplateProvider dna.kernel.protocols extension point Scaffold file trees shipped by an extension 1
ToolPort dna.kernel.protocols extension point A tool an agent can invoke

Emit — materializing an agent into a runtime (2)

Where the storage ports face inward, these face out: the kernel composes a neutral agent, and an emitter turns it into the native artifact one specific runtime consumes. Author once, emit per runtime.

Port Module Role What it decides Shipped
EmitterPort dna.emit extension point How a composed agent becomes a runtime's native artifact 8
ScaffoldResolver dna.emit.scaffold extension point Where a scaffold template's source comes from 1

Runtime & threads — serving a live copilot (8)

Emitting produces a file. These ports produce a running agent, and the conversation state that outlives a single request. The thread ports are split along a real fault line — what the framework knows versus what only the host knows — and the split is the whole design.

Port Module Role What it decides Shipped
AGUIApp dna.runtime.port extension point The mountable app a runtime adapter returns
AgentHarnessPort dna.runtime.harness extension point How a resolved agent runs inside a provider-owned SDK loop 1
RuntimePort dna.runtime.port extension point How a composed agent becomes a running one 2
ThreadIndexPort dna.runtime.thread_store extension point Whose conversation is this, and what are mine 1
ThreadPurgePort dna.runtime.thread_store extension point Retention: find expired threads and drop them 1
ThreadStorePort dna.runtime.thread_store extension point The whole conversation contract 1
ThreadTranscriptPort dna.runtime.thread_store extension point Reading the messages of a conversation 2
TranscriptPurgePort dna.runtime.thread_store extension point …and the half only the framework can delete 1

Judgement — where something decides (4)

Four seams where DNA deliberately declines to ship an opinion. Each is a place a model, a heuristic, or a human gets to be the authority — and DNA's position is that the authority is yours to supply, not ours to bundle.

Port Module Role What it decides Shipped
Analyzer dna.extensions.intel.analyzer extension point A pass over a source that proposes candidates 2
ContradictionScribe dna.memory.contradiction extension point Deciding whether two memories actually contradict
EvalTargetPort dna.extensions.eval.runner extension point What an eval case is actually run against 1
MergeScribe dna.memory.merge extension point Fusing two memories into one

Internal seams — not extension points (21)

These are Protocols, and they are not for you.

They exist because the kernel was decomposed into collaborators (instance builder, query engine, write pipeline, …) and each collaborator's back-reference to the kernel was published as a narrow, typed slice instead of passing the whole kernel around. That keeps the decomposition honest and testable — a collaborator can only reach what its slice names.

They are listed here for one reason: invisible is worse than "this is not for you". If you go looking for the extension point and find twenty-two Protocols nobody explains, you cannot tell the seams from the scaffolding. Now you can. Implementing one of these means substituting a piece of the kernel for itself, which is a fork, not an extension.

Port Module Role What it decides Shipped
BundleIOHost dna.kernel.collaborator_ports internal seam Everything bundle I/O needs
CatalogCacheHost dna.kernel.collaborator_ports internal seam Everything the catalog cache needs
CompositionResolverHost dna.kernel.collaborator_ports internal seam Everything the composition resolver needs
DocStore dna.kernel.collaborator_ports internal seam The kernel's own instance-reading surface
InheritanceCtx dna.kernel.collaborator_ports internal seam Scope inheritance and the resolution chain
InstanceBuildCtx dna.kernel.collaborator_ports internal seam Manifest-assembly internals
InstanceBuilderHost dna.kernel.collaborator_ports internal seam Everything the instance builder needs
InvalidationHost dna.kernel.collaborator_ports internal seam Cache-coherence state
KindLookup dna.kernel.collaborator_ports internal seam Kind identity, plane and storage, for kernel collaborators
LayerObserverCtx dna.kernel.collaborator_ports internal seam The reverse-dependency observer graph
LayerPolicyHost dna.kernel.collaborator_ports internal seam Everything layer-policy enforcement needs
NamespaceGateHost dna.kernel.collaborator_ports internal seam Everything the namespace-ownership gate needs
QueryEngineHost dna.kernel.collaborator_ports internal seam Everything the query engine needs
RecordQuery dna.kernel.collaborator_ports internal seam The record-query push-down
RegistryAccessorHost dna.kernel.collaborator_ports internal seam The three global registry reads
RegistryHost dna.kernel.collaborator_ports internal seam Everything the Kind registry needs
SearchEngineHost dna.kernel.collaborator_ports internal seam Everything the search engine needs
SourceFacadeHost dna.kernel.collaborator_ports internal seam Read-only source introspection
SourceSyncHost dna.kernel.collaborator_ports internal seam Everything source sync needs
WriteHost dna.kernel.collaborator_ports internal seam Everything the write pipeline needs
WriteOps dna.kernel.collaborator_ports internal seam The kernel's write entry points

Before you implement one

Two house rules apply to every port on this page.

  1. If the thing you are adapting to has an official SDK, use it. A port exists so DNA's core does not have to know your backend; it does not exist so you can re-derive somebody else's protocol from its specification. Conformance with a third party is the whole product, and a subtle misreading of a spec only surfaces when a real external client tries to talk to you.
  2. Search before you build. Check whether an adapter already exists — in this tree, in a dependency this package already declares, or on GitHub — before you write the first line. Record the result either way; a port implementation that does not say whether it looked leaves the next reader unable to tell a decision from an oversight.