Skip to main content

Resource reference

Five resource kinds exist today: Colony, Agent, AgentVersion, Run and Tool, plus the append-only Event. All are defined in proto/hived/v1alpha1, which is the source of truth.

Field names. The proto uses snake_case; the JSON and YAML wire form uses lowerCamelCase. Write displayName, agentRef, maxConcurrentRuns in a manifest, not display_name. Unknown fields are rejected.

Enums are written as their full proto name, for example type: TOOL_TYPE_MCP. Durations use the protobuf JSON form, for example timeout: 300s. Money fields are decimal strings such as "12.50", never floats, to avoid drift in budget accounting.

ObjectMeta

Every kind except Event embeds metadata. Event does not: it is not a reconciled resource, it is a fact that happened.

FieldTypeMeaning
namestringUnique within (kind, colony). Immutable after creation.
colonystringThe owning Colony. Required for colony-scoped kinds; empty for Colony itself, which is hive-scoped.
uidstringServer-assigned, stable across renames. Renames are not supported today; the field exists for forward compatibility.
generationint64Increments only when the spec changes. A status-only write leaves it alone, which is what makes status.observedGeneration meaningful.
resourceVersionint64Increments on every write, spec or status. This is the watch cursor and the optimistic-concurrency token.
labelsmapFree-form key/value. List filters on them; Watch currently does not.
annotationsmapFree-form key/value, not used for selection.
createdAttimestampServer-assigned.
updatedAttimestampServer-assigned.
deletedAttimestampSet on soft delete. A Watch stream emits DELETED when this transitions from unset to set. No API sets it today: there is no delete operation on any service.

uid, generation, resourceVersion and the timestamps are server-owned. Setting them in a manifest does not do anything useful.

Condition

A shared status building block used by most kinds.

FieldType
typestring
statusstring
reasonstring
messagestring
lastTransitionTimetimestamp
observedGenerationint64

Nothing writes conditions in v0.1.0. There are no controllers yet.

Colony

Hive-scoped. The tenant and isolation boundary. It owns agents, policies, quotas, tool registrations and a memory scope root.

spec:

FieldTypeMeaning
displayNamestringHuman-readable name.
quotasQuotasSee below. Stored, not enforced.
policies[]stringNames of Policy resources evaluated for Runs in this Colony. Policy is not implemented; accepted and stored, never evaluated.
memoryRootstringThe mindD path root this Colony's Runs are scoped under. See ADR-0004 for the interim mapping onto mindD's flat tenant claim.
executorAllowlist[]stringExecutors Runs here may use. Stored, not enforced.
modelAllowlist[]stringModels Runs here may use. Stored, not enforced.

spec.quotas:

FieldTypeMeaning
maxConcurrentRunsint64
maxRunsPerHourint64
tokenBudgetint64
costBudgetstringDecimal string, for example "12.50".

status: conditions, observedGeneration.

apiVersion: hived/v1alpha1
kind: Colony
metadata:
name: acme
spec:
displayName: Acme Corp
memoryRoot: colony/acme
quotas:
maxConcurrentRuns: 4
costBudget: "25.00"

Agent

Colony-scoped. The mutable envelope around a versioned definition. The real spec lives on AgentVersion.

spec:

FieldTypeMeaning
descriptionstringThat is the whole spec. Everything else is on the version.

status:

FieldTypeMeaning
currentstringName of the active AgentVersion. There is no controller to set this, so it has to be written explicitly.
versions[]stringKnown version names.
conditions[]Condition

AgentVersion

Colony-scoped, and the immutable one. Apply is create-or-identical-noop: re-applying an identical spec succeeds and changes nothing, applying a different spec to an existing (colony, name) is rejected as immutable. To change an agent, create a new version.

spec:

FieldTypeMeaning
agentstringName of the owning Agent.
versionstringVersion label, for example v1.
instructionsstringThe system prompt.
modelModelSpec
tools[]ToolRefReferences to Tool resources.
memoryMemorySpec
policies[]stringPolicy names. Stored, never evaluated.
runtimeRuntimeSpec
limitsLimitsSpec
ioIOSpec

spec.model (ModelSpec):

FieldType
providerstring
namestring
paramsmap

spec.tools[] (ToolRef):

FieldTypeMeaning
namestringThe Tool resource's name.
versionstring
configmapPer-tool options.

spec.memory (MemorySpec):

FieldTypeMeaning
rootstringMemory path root.
blocks[]stringmindD blocks this version uses: kv, episodic, semantic, artifact, lease.

spec.runtime (RuntimeSpec):

FieldTypeMeaning
executorstringA hint, not a binding assignment. See ADR-0003.
imagestring
envmap

spec.limits (LimitsSpec):

FieldTypeMeaning
maxStepsint64
maxTokensint64
maxCoststringDecimal string.
timeoutdurationRun wall clock, for example 300s.

spec.io (IOSpec):

FieldTypeMeaning
inputSchemastringJSON Schema, stored as a string.
outputSchemastringJSON Schema, stored as a string.

status: conditions.

None of model, tools, memory, runtime, limits or io is acted on in v0.1.0. They are stored faithfully so that the Scheduler, Drone and Tool Broker can read them without a schema change.

Run

Colony-scoped. One running instance of an Agent, a "Worker" in prose.

RunService.Apply always persists a Run in RUN_PHASE_PENDING at attempt 0. The Scheduler owns every later transition and is the only writer of status. Since there is no Scheduler, a Run stays PENDING.

spec:

FieldTypeMeaning
agentRefstringAgent to run.
versionstringAgentVersion to pin.
inputstructArbitrary JSON object passed to the Run.
sessionRefstringSession grouping. Session is not a resource yet.
parentRunRefstringSet when a Run was spawned by another Run.
executorHintstringMaps to an Executor lane per ADR-0003. Consumed by nothing today.
cancelboolDesired state, Kubernetes style: setting it asks the Scheduler to stop the Run and move it to RUN_PHASE_CANCELLED. Clearing it has no effect once the Run is terminal.

status:

FieldTypeMeaning
phaseRunPhaseSee below.
cellRefstringThe Cell this attempt runs in.
executorstringWhich Executor provisioned it.
identitystringOpaque reference to the Run's issued token. Never populated today; internal/identity is a stub. See ADR-0002.
startedAt / finishedAttimestamp
stepsint64
tokensTokenUsageinput, output, total.
coststringDecimal string.
checkpointstringLast checkpoint reference.
resultstructTerminal result.
messagestringHuman-readable status detail.
conditions[]Condition
attemptint32Counts Cell incarnations. 0 until the first Cell is provisioned, incremented each time the Scheduler re-provisions after a lost Cell. Drone reports carry the attempt they belong to, so a stale Cell cannot overwrite its successor's status.
observedGenerationint64
lastHeartbeatAttimestamp

RunPhase:

ValueMeaning
RUN_PHASE_UNSPECIFIEDZero value.
RUN_PHASE_PENDINGCreated, not yet picked up. Every Run in v0.1.0.
RUN_PHASE_SCHEDULINGThe provisioning window: Cell requested, Drone not yet bootstrapped.
RUN_PHASE_RUNNING
RUN_PHASE_PAUSED
RUN_PHASE_SUCCEEDEDTerminal.
RUN_PHASE_FAILEDTerminal.
RUN_PHASE_CANCELLEDTerminal.
RUN_PHASE_TIMED_OUTTerminal. The Keeper stopped the Run because AgentVersion.spec.limits.timeout elapsed.

Tool

Colony-scoped registration of something an Agent may call. An AgentVersion references Tools by name in spec.tools.

The design point: the Tool Broker resolves those references and is the only component that ever contacts spec.endpoint. The Drone never sees a Tool's endpoint or credentials. The Broker is not implemented, so today a Tool is a record and nothing more.

spec:

FieldTypeMeaning
typeToolTypeSee below.
descriptionstring
endpointstringMCP server URL, for TOOL_TYPE_MCP.
builtinstringNames the broker-internal implementation, for TOOL_TYPE_BUILTIN.
agentRefstringAgent to spawn, for TOOL_TYPE_AGENT.
riskClassstringread, write, destructive or external-money. Feeds policy. Stored, not enforced: policy evaluation is a later milestone.

ToolType:

ValueMeaning
TOOL_TYPE_UNSPECIFIEDZero value.
TOOL_TYPE_MCPA Model Context Protocol server reached at spec.endpoint.
TOOL_TYPE_BUILTINImplemented inside the Tool Broker, for example spawn_run or wait_run. spec.endpoint is empty.
TOOL_TYPE_AGENTCalling the tool spawns a child Run of spec.agentRef.

status: conditions, observedGeneration.

apiVersion: hived/v1alpha1
kind: Tool
metadata:
name: docs-search
colony: acme
spec:
type: TOOL_TYPE_MCP
description: search the internal docs corpus
endpoint: https://mcp.internal.example/docs
riskClass: read

Event

Append-only and per Run. No metadata, no spec/status split, no update, no delete.

FieldTypeMeaning
colonystring
runstring
seqint64Monotonic per (colony, run), assigned by the store on Append. This ordering is authoritative.
typestringSee the vocabulary below.
tstimestampInformational, and may be skewed between Keeper and Drone clocks. A caller-supplied value is preserved.
payloadstructA summary, never a transcript.
resourceVersionint64Shares the same sequence space as resources' watch cursor, so a single cursor orders both.

Event type vocabulary

ADR-0005 fixes a closed vocabulary of UpperCamelCase names and splits it by emitter. Nothing emits any of these in v0.1.0, because neither emitter exists. The vocabulary is fixed in advance so that hived events, a future run inspector and any SIEM export can key off type without churn.

Keeper-emitted, where the Scheduler is the only writer:

TypeWhen
RunScheduledPENDING to SCHEDULING; AgentVersion resolved, policy passed
CellProvisionedExecutor returned a Cell handle
CellLostCell exited or vanished without Finish, or heartbeats stopped
RunTimedOutlimits.timeout elapsed
RunCancelledspec.cancel honoured

Drone-emitted, authenticated with the Run token:

TypeWhen
RunStartedFirst step of attempt 1
RunResumedFirst step of attempt > 1, after loading the checkpoint
ModelCalledA Model Gateway call returned
ToolCalledA Tool Broker call returned
RunCheckpointedCheckpoint written
RunFinishedFinish accepted

Payloads carry identifiers and counts, never prompt text, tool arguments or tool results. Those belong in mindD's episodic block, which keeps the Postgres event log small and free of user data by default. Approval and policy events (ApprovalRequested, ApprovalDecided, PolicyDenied) are deliberately absent; they arrive with the Policy engine.

List and Watch

ListOptions, accepted by both List and Watch:

FieldTypeMeaning
colonystringScopes the list. Ignored for Colony, which is hive-scoped.
labelSelectormapExact-match label filter. Honoured by List, ignored by Watch.
pageSizeint32Clamped to a maximum of 1000.
pageTokenstringOpaque keyset cursor. A malformed token is reported as InvalidArgument.

ListMeta, returned by every List:

FieldTypeMeaning
nextPageTokenstringEmpty when the page is the last one.
resourceVersionint64The highest resourceVersion observed in this response.

The List then Watch handoff

This is the contract that lets a client build a complete, gap-free view.

  1. List the kind you care about. Page through until nextPageToken is empty. Keep listMeta.resourceVersion.
  2. Watch(sinceResourceVersion = listMeta.resourceVersion).
  3. Every change after the List arrives on the stream exactly once. Nothing is missed and nothing is double-processed.
  4. While idle, the stream emits BOOKMARK events every 30 seconds. They carry no object, only a newer resourceVersion, so a watcher can advance its saved cursor without a real change.

WatchEventType is ADDED, MODIFIED, DELETED or BOOKMARK, mirroring Kubernetes' watch semantics.

The handoff depends on resourceVersion order matching commit order, which is why the store allocates it from a transactional counter rather than a sequence. See Architecture.

Kinds that do not exist yet

docs/PROJECT.md describes several more resources. None of them is implemented, and none has a proto message:

Session, Policy, ModelBinding, Executor, Credential, Approval.

Run.spec.sessionRef and the policies fields on Colony and AgentVersion reference kinds that have no resource behind them yet. They are stored as strings.