Kinds reference¶
A Kind is DNA's unit of identity + composition — the equivalent of a Kubernetes CRD, but for agent behaviour. Every Kind is declared by a *.kind.yaml KindDefinition descriptor; the descriptor format is pinned by kind-definition.schema.json and summarised below. The catalogue on this page is generated from the live registered Kinds (Kernel.auto()), so it cannot drift from the code.
The KindDefinition descriptor¶
Declarative Kind descriptor — the format of builtin kinds/*.kind.yaml package descriptors AND per-scope kinds/<name>/KIND.yaml instances (one format, one funnel). Canonical copy: docs/schemas/kind-definition.schema.json; a byte-identical runtime copy ships as sdk-py package data (dna/kernel/schemas/) and backs the validation in TypedKindDefinition.from_raw. Parity-critical: the Python hand-rolled validator (models.py KindDefinitionSpec.from_raw) must accept exactly what this schema accepts (guarded by packages/sdk-py/tests/test_kind_definition_schema.py). There is NO TypeScript twin — packages/ holds cli, client-py, client-ts and sdk-py, and neither a models.ts KindDefinitionSpecSchema nor a kind-definition-schema.test.ts exists anywhere in the tree. The claim that one guarded this file was stale; a false 'guarded by' sitting next to newly-added fields invites the next author to trust it. Editor autocomplete: put # yaml-language-server: $schema=<path-to-this-file> on the first line of a .kind.yaml.
spec fields of a KindDefinition:
| Field | Required | Description |
|---|---|---|
alias |
yes | Globally unique alias, convention <owner>-<kebab(kind)> (e.g. sdlc-kaizen). Used in dep_filters and templates. It is NOT how a relation names its target: spec.relations[*].to carries the bare Kind NAME, which is unambiguous by the enforced i-195 invariant and is what the instance read takes. This line used to say aliases were for "cross-kind refs — never bare Kind names", which no implementation ever matched (i-110 item 2). |
approved_at |
When the approval recorded in approved_by was given (ISO-8601). Audit metadata only — the gate reads the STATE, of which approved_by is one input. | |
approved_by |
Who approved this Kind. A KindDefinition loaded from a STORE registers only once this names someone: registration is what confers schema enforcement and storage routing, so an unapproved Kind is parsed, logged and left inert — an instance that is auditable, listable and diffable, and does nothing. Omit (null) while the Kind is authored but not yet approved. | |
ascii_icon |
Single emoji or character for ASCII tree / compact views. | |
created_at |
When the instance was created (ISO-8601). VOLATILE means excluded from canonical_digest, NOT supplied by the runtime — nothing in the write path stamps it, so an instance written without it comes back with no created_at at all. The Kind-authoring door therefore stamps it deliberately, and the audit view projects it. It means the BIRTH of the instance and is PRESERVED across edits — the authoring door rebuilds the spec from scratch and persists it, so it carries the existing value forward and stamps now only when the instance does not yet exist; 'when the instance was created' has to stay true after the first edit. For when the pending shape was proposed, read proposed_at. A write-time stamp, if one ever lands, wins. |
|
default_agent |
Fixed Agent name returned by get_default_agent_name for every doc of this Kind. | |
default_agent_field |
Spec field whose value is returned VERBATIM by get_default_agent_name (descriptor-expressiveness D6). | |
dep_filters |
Cross-Kind references: spec field → target Kind ALIAS (never a bare Kind name). | |
describe |
Per-doc one-liner: a template string ("{name} ({status})") or a projection mapping ({"path": "description"}) (descriptor-expressiveness D3). | |
description_fallback_field |
Spec field acting as the Studio card description fallback when metadata.description is absent (D7). | |
display_label |
Human-friendly plural label (e.g. "Kaizens"). | |
docs |
Prose explanation of what this Kind IS at the concept level (surfaced by describe_kind). | |
embed |
Spec fields composing the doc's embedding text (semantic search source, F3 D4). | |
flatten_in_context |
True flattens the spec dict into the prompt context. | |
graph_style |
Colors for mermaid/graph visualizations, e.g. {fill, stroke, text_color}. | |
identifiers |
Fields that point NOWHERE, and say so — the other half of spec.relations, and the half that makes the gap list finite. A field whose NAME looks like a reference (sprint_id, stripe_customer_id) but which points at no instance is reported by the schema graph as an undeclared gap; this block is how a Kind ANSWERS that — on itself, beside its schema, with a machine-readable reason. NOT the retired inference denylist: nothing is being suppressed (the gap row asserts no target, so there is no false claim to silence), and the declaration lives on the Kind rather than in a central table that can go stale against a Kind it no longer describes. Declaring the same field as BOTH a relation and an identifier is refused at load — one says it points somewhere, the other says it points nowhere. Normalized + enforced by dna.kernel.kinds.identifiers; exposed on the port as identifiers. |
|
is_catalog_identity |
A write of this Kind changes the Catalog tier's scope/mandatory set, so the kernel drops its catalog cache after it. | |
is_overlayable |
A tenant overlay may fork this Kind (false only for structural bootstrap Kinds). | |
is_root |
True only for the scope-root identity Kind (one per scope). | |
is_runtime_artifact |
True for Kinds whose docs are PRODUCED by runtime workflows (eval runs, findings, ...) rather than authored — replication/seed/export tools skip them. | |
is_schema_affecting |
A write of this Kind invalidates the kernel's schema cache (Kernel._SCHEMA_INVALIDATING_KINDS). Refused on the record plane, exactly as for a class Kind. | |
layout_names |
The prompt layouts instances of this Kind may name; UnknownLayout lists them back to the author. | |
marker_shared_allowed |
This bundle Kind consents to sharing its (container, marker) pair with another Kind that also consents. Both sides must declare it. | |
origin |
yes | Registry namespace label of the owning extension/package, e.g. github.com/ruinosus/dna/sdlc. |
overlayable_fields |
Per-FIELD refinement of is_overlayable: the top-level spec keys a layer (a tenant overlay, a branch) may CHANGE. Enforced on the WRITE path — a layer write that changes any other key raises LayerPolicyViolationError — and intersected with the operator's LayerPolicy docs, so neither widens the other. Not applied when merging overlays already stored (that would retroactively rewrite existing deployments); it gates what a layer may AUTHOR. Writing a non-listed key back at its base value is not a change and stays allowed. Omit for no per-field restriction (the default: every spec key is overlayable); an explicit [] forbids every field change. Exposed on the port as OVERLAYABLE_FIELDS. | |
plane |
composition = participates in agent composition (writes invalidate scope caches) · record = pure typed instance (cacheless writes, never composes into prompts; cannot carry composition signals — the plane lint rejects contradictions). | |
post_save_event |
The post_save event_type instances of this Kind emit. A string = that name for BOTH create and update (a run is 'completed' either way); a two-element array = [create, update]. Absent = the generic document_created / document_modified pair. EvidencePolicy selects which writes to capture BY event_type, so a Kind that cannot name its event cannot be captured by any policy — which is why this is declarable here rather than a table in kernel/boot/events.py (i-107). | |
presentation |
How this Kind's DATA reads, declared ONCE for every surface (an MCP Apps card, a portal screen, a CLI table). Deliberately NOT a layout language: there is no column, width, section, colour, variant or widget anywhere in the vocabulary, and unknown keys are refused — the Kind says what a field MEANS, and each surface decides what that becomes on it. Sibling of ui_schema, not its twin: that one hints how a human EDITS a field, this one says what the value means when a human READS it. The bare-list shorthand presentation: [name, title, status] is equivalent to {fields: [...]}, exactly as summary accepts a list. Normalized + enforced by dna.kernel.kinds.presentation (the role enum below is the SAME closed set that validator holds); exposed on the port as presentation and on the wire, composed with display_label/ascii_icon, by presentation_wire. |
|
prompt_target |
True if instances of this Kind compose into LLM prompts. | |
prompt_target_priority |
Ordering priority among prompt targets (lower first). | |
proposed_at |
When the proposal recorded in proposed_by was made (ISO-8601). Equal to created_at on a FIRST author and later than it on every edit — created_at is the instance's birth and is carried forward, while this pair moves with the current proposal. Audit metadata only. | |
proposed_by |
Who PROPOSED this Kind — the verified identity at the authoring door, stamped THERE because a proposer cannot be back-filled onto an instance that never recorded one. Tracks the CURRENT proposal: an edit (a second author call for an existing name) RE-STAMPS it to the editor, because the question this field answers is who proposed the shape that is pending or approved right now. The original proposer stays recoverable through the kernel's version history. Audit metadata only: the registration gate reads approved_by. It is legal for this to name the same identity as approved_by (a solo author who approves their own proposal is two credentials, and refusing on identity equality would block the commonest user for no security gain) — a coincidence the audit REPORTS, not an error. What must never happen is one act wearing the other's name: each field is stamped from the verified identity of ITS OWN act, never from the request body. | |
relations |
What this Kind POINTS AT — first-class, so a relation is listable without walking properties, its cardinality is declared rather than inferred, and a reciprocal pair can say that it IS one. The relation's NAME is the spec field holding its value, which is what keeps the declaration and the data together and lets the read that VALIDATES a relation be the read that produces its edge. Normalized + enforced by dna.kernel.kinds.relations; exposed on the port as relations. Replaces the four mechanisms that answered this question before (x-dna-ref, x-dna-ref-composite, name-shape inference, and the denylist that existed to silence it). dep_filters is NOT one of them and stays separate — it drives prompt composition. |
|
revoked_at |
When the revocation recorded in revoked_by was made (ISO-8601). Audit metadata only — and NOT a tie-break against approved_at: which state is current is decided by the two acts (approving clears the revocation, revoking stamps it), never by comparing caller-supplied timestamps from possibly-skewed clocks in possibly-different formats. | |
revoked_by |
Who REVOKED this Kind — the THIRD state, and deliberately not the absence of the second. Clearing approved_by is indistinguishable from never having approved, and never-approved means UNREGISTERED, which means instances are accepted with no validation at all — so a revocation implemented as a plain un-approval loosens instead of tightening. The revoked fact is therefore persisted here; the Kind stays REGISTERED (being known is what stops revocation meaning 'accepts anything'); new instances of it are REFUSED; and existing ones read back MARKED invalid — never deleted, never an error, because the data did nothing wrong and the audit needs to see what existed. Reversible: approving again clears this pair and validity returns, because validity follows the Kind's CURRENT state and is never a stamp on the instance. approved_by is deliberately left standing beside it — the audit must keep who conferred effect in the first place. | |
schema |
JSON Schema of the Kind's DATA — the shape of the spec dict. Drives Studio form generation + validate_on_parse. New Kinds should ship additionalProperties: false (s-strict-schema-lint ratchet). It carries no reference vocabulary: what a field POINTS AT is declared in spec.relations, which is a model statement rather than a data one. The x-dna-ref / x-dna-ref-composite annotations that used to live on a property are GONE — see spec.relations. |
|
schema_fragments |
Namespaced schema fragment IDs merged into schema in order (e.g. ["sdlc/workitem-common"]). Python reference implementation only — the TS Zod schema does not consume it yet. |
|
scope_inheritable |
Instances of this Kind inherit across scopes (false for per-scope ledgers + structural Kinds). | |
spec_defaults |
Shallow-merge defaults applied as {spec_defaults, spec} BEFORE schema validation in parse() (D5). | |
storage |
yes | Where instances of this Kind live on disk (mirrors StorageDescriptor / storage_dict_to_descriptor). |
summary |
List-endpoint projection. Dict form {field: default} passes through; list form ["a", "b"] is normalized with per-schema-type defaults (array→[], boolean→false, number/integer→null, else ""). | |
target_api_version |
yes | apiVersion namespace of the Kind being DEFINED (globally unique), e.g. github.com/ruinosus/dna/sdlc/v1. |
target_kind |
yes | CamelCase name of the Kind being defined, e.g. Kaizen. Must be unique across api_versions (i-195). |
tenant_scope |
Tenant enforcement for this Kind. Undeclared = permissive (base + per-tenant override). Máxima: an inheritable default-of-_lib Kind must NEVER be tenanted. |
|
traits |
What this Kind PARTICIPATES in, e.g. ["sdlc.work-item"] / ["memory.recallable"]. Consumers ask kernel.kinds_with_trait(name) instead of carrying a literal Kind-name list, so adding a Kind to a family is a declaration rather than an edit in every module that has an opinion. OPEN vocabulary: an unregistered trait is legal; <owner>.<name> by convention (see dna.kernel.kinds.traits). |
|
ui |
StudioUIMetadata mapping — generates Studio routes/sidebar/sitemap. Keys are validated strictly (⊆ StudioUIMetadata dataclass fields) by the hand-rolled check AND here (D1). | |
ui_schema |
Per-field widget-hint bag (field → {widget, label, help, language, height, order, ...}). Deliberately permissive — an explicitly UI-owned bag (D4). See docs/KIND-UI-HINTS.md. | |
updated_at |
Runtime-stamped volatile field (never authored) — allowed so write-stamped instances keep validating. | |
validate_on_parse |
parse() validates spec against schema() and raises on a malformed instance (the loader turns that into a parse_error event). A descriptor Kind with a declared schema already validates; declaring this keeps a class → descriptor migration lossless and makes the intent readable. | |
version |
Runtime-stamped volatile field (never authored). | |
version_retention |
How many version snapshots to keep for a machine-churn Kind. Omit for the kernel's curated default. | |
visible_in_backend |
Explicit override of the storage-pattern default for backend visibility. Omit (null) to derive it (bundle/standalone → true, yaml/root → false). | |
volatile_spec_fields |
Extra write-/runtime-stamped spec fields excluded from the canonical digest, unioned with the base set {updated_at, version, created_at}. | |
workitem_common |
DEPRECATED back-compat shorthand for schema_fragments: ["sdlc/workitem-common"]. Python-only. |
Registered Kinds (89)¶
Composition plane¶
Composition-plane Kinds are behaviour that composes into an agent's prompt (skills, souls, guardrails, …) — resolved through the layer/tenant overlay engine.
| Kind | Alias | apiVersion |
|---|---|---|
| Actor | helix-actor |
github.com/ruinosus/dna/v1 |
| Agent | helix-agent |
github.com/ruinosus/dna/v1 |
| AgentDefinition | agentsmd-agent |
agents.md/v1 |
| Canvas | helix-canvas |
github.com/ruinosus/dna/v1 |
| Comment | collab-comment |
github.com/ruinosus/dna/collab/v1 |
| EvidencePolicy | evidence-policy |
github.com/ruinosus/dna/evidence/v1 |
| Genome | helix-genome |
github.com/ruinosus/dna/v1 |
| Guardrail | guardrails-guardrail |
github.com/ruinosus/dna/v1 |
| Hook | helix-hook |
github.com/ruinosus/dna/v1 |
| KindDefinition | kinddef-kinddefinition |
github.com/ruinosus/dna/core/v1 |
| LayerPolicy | policy-layer-policy |
github.com/ruinosus/dna/policy/v1 |
| Lesson | lesson-lesson |
github.com/ruinosus/dna/lesson/v1 |
| MCPFederation | federation-mcp |
github.com/ruinosus/dna/federation/v1 |
| Recognizer | presidio-recognizer |
presidio/v1 |
| Research | research-research |
github.com/ruinosus/dna/research/v1 |
| SafetyPolicy | helix-safety-policy |
github.com/ruinosus/dna/v1 |
| Setting | helix-setting |
github.com/ruinosus/dna/v1 |
| Skill | agentskills-skill |
agentskills.io/v1 |
| Soul | soulspec-soul |
soulspec.org/v1 |
| Tenant | tenant-tenant |
github.com/ruinosus/dna/tenant/v1 |
| TenantMembership | tenant-membership |
github.com/ruinosus/dna/tenant/v1 |
| TestGuide | testkit-test-guide |
github.com/ruinosus/dna/testkit/v1 |
| TestRun | testkit-test-run |
github.com/ruinosus/dna/testkit/v1 |
| Theme | helix-theme |
github.com/ruinosus/dna/v1 |
| UseCase | helix-usecase |
github.com/ruinosus/dna/v1 |
| UserProfile | helix-user-profile |
github.com/ruinosus/dna/v1 |
| UserRoleAssignment | audit-userroleassignment |
github.com/ruinosus/dna/audit/v1 |
Record plane¶
Record-plane Kinds are queryable data rows (SDLC work items, research, evidence, audit log, …) — first-class instances you query/count rather than fold into a prompt.
| Kind | Alias | apiVersion |
|---|---|---|
| ADR | sdlc-adr |
github.com/ruinosus/dna/sdlc/v1 |
| AgentCatalogEntry | a2a-agent-catalog-entry |
github.com/ruinosus/dna/a2a/v1 |
| AgentGrant | a2a-agent-grant |
github.com/ruinosus/dna/a2a/v1 |
| AgentSession | sdlc-agent-session |
github.com/ruinosus/dna/sdlc/v1 |
| App | helix-app |
github.com/ruinosus/dna/v1 |
| AuditLog | audit-auditlog |
github.com/ruinosus/dna/audit/v1 |
| Automation | dna-automation |
github.com/ruinosus/dna/automation/v1 |
| Bug | sdlc-bug |
github.com/ruinosus/dna/sdlc/v1 |
| Changelog | sdlc-changelog |
github.com/ruinosus/dna/sdlc/v1 |
| CognitivePolicy | sdlc-cognitive-policy |
github.com/ruinosus/dna/sdlc/v1 |
| Copilot | helix-copilot |
github.com/ruinosus/dna/v1 |
| Doc | dna-doc |
github.com/ruinosus/dna/doc/v1 |
| Engram | helix-engram |
github.com/ruinosus/dna/v1 |
| Epic | sdlc-epic |
github.com/ruinosus/dna/sdlc/v1 |
| EvalBaseline | eval-eval-baseline |
github.com/ruinosus/dna/eval/v1 |
| EvalCase | eval-eval-case |
github.com/ruinosus/dna/eval/v1 |
| EvalRun | eval-eval-run |
github.com/ruinosus/dna/eval/v1 |
| EvalSuite | eval-eval-suite |
github.com/ruinosus/dna/eval/v1 |
| Evidence | evidence-evidence |
github.com/ruinosus/dna/evidence/v1 |
| Feature | sdlc-feature |
github.com/ruinosus/dna/sdlc/v1 |
| GenUIBinding | runtime-gen-ui-binding |
github.com/ruinosus/dna/runtime/v1alpha1 |
| GenUIComponent | runtime-gen-ui-component |
github.com/ruinosus/dna/runtime/v1alpha1 |
| HtmlArtifact | sdlc-html-artifact |
github.com/ruinosus/dna/sdlc/v1 |
| Initiative | sdlc-initiative |
github.com/ruinosus/dna/sdlc/v1 |
| IntelInsight | intel-insight |
github.com/ruinosus/dna/intel/v1 |
| IntelSource | intel-source |
github.com/ruinosus/dna/intel/v1 |
| Issue | sdlc-issue |
github.com/ruinosus/dna/sdlc/v1 |
| Kaizen | sdlc-kaizen |
github.com/ruinosus/dna/sdlc/v1 |
| KindNamespace | tenant-kind-namespace |
github.com/ruinosus/dna/tenant/v1 |
| KnowledgeChunk | artifact-knowledge-chunk |
github.com/ruinosus/dna/artifact/v1 |
| Membership | portfolio-membership |
github.com/ruinosus/dna/portfolio/v1 |
| Memory | mif-memory |
mif-spec.dev/v1 |
| ModelProfile | modelreg-model-profile |
github.com/ruinosus/dna/modelreg/v1 |
| Narrative | sdlc-narrative |
github.com/ruinosus/dna/sdlc/v1 |
| Organization | portfolio-org |
github.com/ruinosus/dna/portfolio/v1 |
| Plan | sdlc-plan |
github.com/ruinosus/dna/sdlc/v1 |
| PlanBinding | cloud-plan-binding |
github.com/ruinosus/dna/cloud/v1 |
| Postmortem | sdlc-postmortem |
github.com/ruinosus/dna/sdlc/v1 |
| PricingPlan | cloud-pricing-plan |
github.com/ruinosus/dna/cloud/v1 |
| Project | portfolio-project |
github.com/ruinosus/dna/portfolio/v1 |
| PromptTemplate | sdlc-prompt-template |
github.com/ruinosus/dna/sdlc/v1 |
| Reference | sdlc-reference |
github.com/ruinosus/dna/sdlc/v1 |
| RemoteAgent | a2a-remote-agent |
github.com/ruinosus/dna/a2a/v1 |
| Repo | portfolio-repo |
github.com/ruinosus/dna/portfolio/v1 |
| Retrospective | sdlc-retrospective |
github.com/ruinosus/dna/sdlc/v1 |
| RiskRegister | sdlc-risk-register |
github.com/ruinosus/dna/sdlc/v1 |
| Roadmap | sdlc-roadmap |
github.com/ruinosus/dna/sdlc/v1 |
| Role | portfolio-role |
github.com/ruinosus/dna/portfolio/v1 |
| RuntimeBinding | runtime-binding |
github.com/ruinosus/dna/runtime/v1alpha1 |
| Solution | helix-solution |
github.com/ruinosus/dna/v1 |
| SourceArtifact | artifact-source |
github.com/ruinosus/dna/artifact/v1 |
| Spec | sdlc-spec |
github.com/ruinosus/dna/sdlc/v1 |
| Spike | sdlc-spike |
github.com/ruinosus/dna/sdlc/v1 |
| Sprint | sdlc-sprint |
github.com/ruinosus/dna/sdlc/v1 |
| StatusReport | sdlc-status-report |
github.com/ruinosus/dna/sdlc/v1 |
| Story | sdlc-story |
github.com/ruinosus/dna/sdlc/v1 |
| Task | sdlc-task |
github.com/ruinosus/dna/sdlc/v1 |
| Tool | helix-tool |
github.com/ruinosus/dna/v1 |
| WorkflowEvent | sdlc-workflow-event |
github.com/ruinosus/dna/sdlc/v1 |
| Workspace | tenant-workspace |
github.com/ruinosus/dna/tenant/v1 |
| WorkspaceMembership | tenant-workspace-membership |
github.com/ruinosus/dna/tenant/v1 |
| WorkspaceScopeGrant | tenant-workspace-scope-grant |
github.com/ruinosus/dna/tenant/v1 |