Skip to content

Document & ManifestInstance

Document is the universal wrapper for every manifest document — doc.kind, doc.name, doc.spec, doc.metadata, doc.typed, doc.origin. ManifestInstance is the blessed query surface: the one documented read API (all, one, root, default_agent, find_agent, build_prompt, resolve) that the guides and examples teach.

Document

dna.kernel.document.Document

Document(
    api_version: str,
    kind: str,
    name: str,
    metadata: dict[str, Any] | None = None,
    spec: dict[str, Any] | None = None,
    raw: dict[str, Any] | None = None,
    typed: Any | None = None,
    origin: str = "local",
)

Bases: Generic[SpecT]

Universal wrapper. Works for parsed BaseKind AND raw dict.

doc.spec and doc.metadata always return SpecDict at runtime — a dict subclass with attribute access. When typed via Document[MySpec], the type checker treats doc.spec as MySpec, enabling autocomplete + typo detection at edit time without a runtime cast.

The typed model is still available via doc.typed.

metadata cached property

metadata: SpecDict

Always returns SpecDict — typed metadata when available, raw dict otherwise.

spec cached property

spec: SpecDict

Always returns SpecDict — typed spec when available, raw dict otherwise.

from_raw classmethod

from_raw(
    raw: dict[str, Any], typed: Any | None = None
) -> Document[Any]

Create a Document from a raw dict.

Returns Document[Any] because the spec type is determined at the call site by the consumer's annotation; the factory itself cannot infer it. Consumers using typed access: doc: Document[PageIndexSpec] = Document.from_raw(raw) get the right type via the annotation.

ManifestInstance

dna.kernel.instance.ManifestInstance

ManifestInstance(
    scope: str,
    documents: list[Document],
    kinds: dict[tuple[str, str], KindPort],
    source: SourcePort | None = None,
    resolve_errors: list[str] | None = None,
    kernel: Any = None,
    profiles: list | None = None,
    lazy: bool = False,
)

Facade over a loaded manifest scope.

Marco B (s-lazy-manifest-instance-class, 2026-05-14): supports a LAZY mode where the constructor only receives bootstrap docs (Genome + KindDefinition + LayerPolicy + UA index ~30 docs) instead of the full scope (often 1500+). In lazy mode:

  • one(kind, name) → delegates to kernel.get_document (L2 cached, ~5ms).
  • all(kind) → delegates to kernel.query (~10ms indexed).
  • documents → triggers _ensure_loaded() which materializes the full scope. Emits a DeprecationWarning when called in lazy mode — callers should use one/all or kernel.query directly.

Bootstrap kinds (always eager) keep mi.root, mi.kind_for, namespace getters (mi.composition, mi.nav) functional cheaply. Heavy operations like mi.summary() / mi.composition.validate() that iterate the full scope still force the materialization, but that's the explicit ask.

To enable lazy mode: pass lazy=True to the constructor (the Kernel does this when DNA_LAZY_MI=1). When lazy=False (default), ManifestInstance behaves exactly as before — full back-compat for tests, agent paths, and external callers.

documents property writable

documents: list[Document]

Materialized list of all docs. In lazy mode, accessing this triggers a full load (the only way to honor list semantics). Prefer one(kind, name) or all(kind) which stay lazy.

Emits a DeprecationWarning in lazy mode the first time the full set is materialized.

prompt property

prompt: PromptBuilder

Namespace: mi.prompt.build().

composition property

composition: CompositionEngine

Namespace: mi.composition.validate().

nav property

nav: Navigator

Namespace: mi.nav.describe() / summary() / inventory().

lock property

lock: LockManager

Namespace: mi.lock.generate().

reports property

reports: ReportBuilder

Namespace: mi.reports.eval_summary() / findings_summary().

root cached property

root: Document | None

The manifest's root document (the Genome), or None when the scope has no doc whose KindPort is marked is_root.

composition_result cached property

composition_result: CompositionResult

Validate cross-kind references. Returns resolved + missing + warnings.

profile_for

profile_for(doc: Any)

Find the CompositionProfile for a doc's kind (via alias).

all

all(kind: str) -> list[Document]

Return all docs of kind — DEPRECATED, will be removed in 1.0.

s-blessed-query-surface: the blessed query surface is mi.documents (in-memory, filter by d.kind) plus kernel.query(scope, kind) for indexed / record-plane reads. This method survives as a warning shim until 1.0.

all_async async

all_async(
    kind: str, *, tenant: str | None = None
) -> list[Document]

Async-native variant of all() — bridge for callers migrating to await kernel.query(scope, kind).

f-mi-class-extinction (Story s-mi-async-bridge, 2026-05-14): new API that callers should target during the MI sweep. Returns the same list[Document] shape as sync all() but uses await kernel.query end-to-end — no thread, no asyncio.run, no loop-mismatch with asyncpg pools.

Bootstrap kinds (Genome, KindDefinition, LayerPolicy) are served from the in-memory self._documents (no query). Lazy-cached kinds (already materialized by a previous call) are served from self._lazy_kind_cache.

Tenant note: does not auto-apply tenant overlay from this MI's resolved layer context. Callers that need tenant filtering should pass tenant via kernel.query(..., tenant=...) directly. The MI overlay-merge is applied at doc content level and is observable via this method only when the underlying layer storage already filters by tenant (Postgres adapter does).

all_where

all_where(predicate) -> list[Document]

Return all documents whose registered KindPort satisfies a predicate. Forces full materialization in lazy mode (cross-kind walk requires the whole scope).

one_async async

one_async(
    kind: str, name: str, *, tenant: str | None = None
) -> Document | None

Async-native variant of one() — bridge for callers migrating to await kernel.get_document(scope, kind, name).

f-mi-class-extinction (Story s-mi-async-bridge, 2026-05-14): new API that callers should target during the MI sweep. Same return shape as sync one(). Bootstrap kinds + lazy-cached kinds short-circuit; otherwise delegates to await kernel.get_document (L2 cached).

one

one(kind: str, name: str) -> Document | None

Lookup single doc by (kind, name) — DEPRECATED, will be removed in 1.0.

s-blessed-query-surface: the blessed query surface is mi.documents (in-memory, search by d.kind/d.name) plus kernel.get_document(scope, kind, name) for indexed / record-plane reads. This method survives as a warning shim until 1.0.

read_spec

read_spec(
    kind: str, name: str, field: str, *, default: Any = None
) -> Any

Read a single field from document.spec.

read_metadata

read_metadata(
    kind: str, name: str, field: str, *, default: Any = None
) -> Any

Same contract as read_spec but reads from document.metadata.

read_spec_list

read_spec_list(kind: str, name: str, field: str) -> list

Read a list-typed spec field, returning [] when missing or None.

default_agent

default_agent() -> Document | None

The agent Document the root Genome names as its default (spec.default_agent via the root KindPort), or None when there is no root or no such agent.

list_kinds

list_kinds() -> list[str]

Sorted list of the distinct Kind names present in this manifest's loaded documents.

render_doc

render_doc(kind: str, name: str) -> list[PreviewBlock]

Polymorphic per-kind preview.

consumers_of

consumers_of(kind: str, name: str) -> list[dict[str, str]]

Walk the manifest and return every doc that references this one.

is_root_doc

is_root_doc(doc: Any) -> bool

Public alias for _is_root_doc — used by viz functions.

kind_for

kind_for(kind: str) -> Any | None

Return the KindPort registered for kind (by kind name), or None.

kind_for_alias

kind_for_alias(alias: str) -> Any | None

Return the KindPort whose alias matches, or None.

iter_doc_deps

iter_doc_deps(doc: Any) -> list[dict[str, Any]]

Iterate a document's declared dep_filters dynamically.

get

get(kind: str | None = None) -> list[dict[str, Any]]

List documents as light {kind, name, apiVersion} dicts — all of them, or only those of kind. For full Documents use documents / all() instead.

describe

describe(kind: str, name: str) -> str

Human-readable description of one document (metadata, spec highlights, relationships) — delegates to the Navigator.

summary

summary() -> str

Plain-text overview of the manifest (scope + the documents loaded, grouped by kind) — delegates to the Navigator.

inventory

inventory() -> dict[str, Any]

Structured inventory of everything loaded in this manifest.

dependency_tree

dependency_tree() -> dict[str, Any]

Build a dependency tree for every document that has dep_filters.

dependency_tree_mermaid

dependency_tree_mermaid() -> str

Mermaid flowchart of the dependency tree (docs → their dep_filter targets), as diagram source text.

er_diagram_mermaid

er_diagram_mermaid() -> str

Mermaid ER diagram of the document instances and their relationships, as diagram source text.

mindmap_mermaid

mindmap_mermaid() -> str

Mermaid mindmap centered on the root document, fanning out to the manifest's kinds and docs.

pie_chart_mermaid

pie_chart_mermaid() -> str

Mermaid pie chart of document distribution by Kind.

quadrant_mermaid

quadrant_mermaid() -> str

Mermaid quadrant chart of the docs — axes come from the CompositionProfile hints, not hardcoded kind names.

timeline_mermaid

timeline_mermaid() -> str

Mermaid timeline of the build_prompt composition phases.

sankey_mermaid

sankey_mermaid() -> str

Mermaid sankey diagram of document flow into agents.

kind_catalog_mermaid

kind_catalog_mermaid() -> str

Mermaid classDiagram of every registered Kind (the catalog, not just the kinds instantiated in this scope).

export_diagrams_md

export_diagrams_md(
    path: str | None = None,
) -> dict[str, str]

Render every diagram to Markdown with embedded Mermaid blocks. Returns {diagram_name: markdown}; when path is given the files are also written to that directory.

matrix

matrix() -> dict[str, Any]

Agent × dependency matrix — which agent uses which docs — as a structured dict (agents, dependencies, matrix).

matrix_markdown

matrix_markdown() -> str

The matrix() data rendered as a Markdown table.

impact

impact(kind: str, name: str) -> dict[str, Any]

Blast-radius analysis for changing/removing one document: which agents depend on it and through which dep_filters.

health

health() -> dict[str, Any]

Manifest health report — coverage gaps, orphan documents, missing refs — driven generically by CompositionProfile slots (no kind names hardcoded).

ascii_tree

ascii_tree() -> str

Terminal-friendly ASCII rendering of the dependency tree — no diagram renderer needed.

ref

ref(value: str) -> str

Resolve a file reference via source, or return value as-is.

Sync entry-point. Use this from CLI / tests / sync workers whose top-level entry is asyncio.run. Async callers MUST use 🇵🇾meth:ref_async — running this from inside an event loop with a postgres source orphans the asyncpg pool.

ref_async async

ref_async(value: str) -> str

Async variant of 🇵🇾meth:ref.

Use from inside the harness event loop (lifespan, request handlers, async middleware). Awaits source.resolve_ref directly on the caller's loop, which is the same loop that owns the asyncpg pool — no cross-loop dispatch needed.

build_prompt

build_prompt(
    agent: str | None = None,
    context: dict[str, Any] | None = None,
    enabled_skills: list[str] | None = None,
    enabled_guardrails: list[str] | None = None,
    enabled_slots: dict[str, list[str]] | None = None,
) -> str

Build system prompt via template cascade.

Sync — uses _run_sync_helper to await source ref() coroutines. Callers inside an async event loop must use build_prompt_async to avoid the "called from inside a running loop" guard.

build_prompt_async async

build_prompt_async(
    agent: str | None = None,
    context: dict[str, Any] | None = None,
    enabled_skills: list[str] | None = None,
    enabled_guardrails: list[str] | None = None,
    enabled_slots: dict[str, list[str]] | None = None,
) -> str

Async variant of 🇵🇾meth:build_prompt. Use from inside an async caller (test, middleware, etc.) so the ref_async path keeps the source pool's loop binding intact.

find_agent

find_agent(name: str) -> Document | None

Find the best prompt-target document matching name.

Considers prompt_target_priority when multiple kinds match. Public API — use this instead of _find_agent().

resolve

resolve(
    layers: dict[str, str] | None = None,
) -> ManifestInstance

Apply layer overlays (sync). Delegates to Kernel.resolve_layers().

Memoizes per-layers so repeated mi.resolve({"tenant": X}) calls from request handlers reuse the same merged instance instead of re-reading every doc from disk. Cache lives on the base mi; MIHolder.reload() swaps the base instance, which discards this cache transparently.

From inside an event loop, prefer await mi.resolve_async(layers) — the sync path falls back to a ThreadPool/asyncio.run dance that orphans pool-based source adapters.

resolve_async async

resolve_async(
    layers: dict[str, str] | None = None,
) -> ManifestInstance

Async variant of resolve. Use from inside an event loop (request handlers, lifespan, EventBus consumer) so the source pool stays tied to the caller's loop.

apply_hooks

apply_hooks() -> None

Auto-register Hook documents on the kernel's HookRegistry.

generate_lock

generate_lock() -> 'Lockfile'

Generate lockfile with SHA256 per document.