Documentation — Directive reference
Reference · Configuration

Directive reference

This page is the lookup for the instruction-document syntax agentd reads: the block forms and fence rules, every machinery kind with its grant and what agentd does with it, the prose and structural kinds, what the model reads for each construct, which configuration a document may write, and every agent.instruction setting. agentd implements the Instruction Specification version 1, registry revision 1.1; the specification holds the full grammar.

For the ideas behind these rules, see Instruction documents. For a worked example, see Write and ship instruction documents.

Forms

Every block is written in one of these forms. A kind accepts only the forms listed for it in the tables below; any other is refused, naming the forms it takes.

FormSyntaxUsed for
Container:::kind{attrs} … :::A block with a body.
Leaf::kind{attrs}A block with no body, on one line.
Set:::kind[]{attrs} … :::, holding a Markdown table or a definition listSeveral blocks of one kind. Each row or term is one member.
Section## !kind name {attrs}A Markdown section. It ends at the next heading of the same or a higher level, or at the next sigiled heading, fence or leaf. For a kind with a YAML or code body, the body is the one fenced code block in the section and the prose is its description; for a Markdown body, such as !skill, the section's text is the body.
KeywordKEYWORD: text at the start of a lineA rule or note in one paragraph.
Alert> [!KEYWORD] followed by quoted linesA note in GitHub alert style.

Machinery kinds are written with the ! sigil (:::!workflow, ::!human{…}, ## !workflow nightly). Prose and structural kinds are written without it.

Fences and attributes

  • A fence opens at column 0: three or more colons, a kind, and optional {attributes}. A ::: in the middle of a line, or indented, is text.
  • A fence closes at a line of at least as many colons and nothing else. A block left open is refused: :::!stream is never closed.
  • A longer fence contains a shorter one: a :::must inside a ::::context is a nested block. A fence of the same length is not nesting; its opener is text in the outer body, and the first bare closer ends the outer block.
  • Machinery folds into configuration from the document's top level only. A machinery block nested in any body is refused.
  • verbatim on a block delivers its body unparsed: a ::::context{verbatim} around a :::!workflow delivers those lines as text, and loads no workflow.
  • Attributes are key=value, key="a quoted value" (with \" escapes), or a bare flag, which means "true". Keys are read in lower case. A key written twice is refused. A value written as a YAML flow mapping or sequence ({max_events: 100}, [a, b]) is parsed as one.
  • On a machinery block the attributes are folded over the YAML body, so an attribute wins over a body key of the same name.
  • A machinery body is YAML, a table, code, Markdown or text, as the kind defines. A YAML body that does not parse refuses the document, naming the block's line.

Front matter and end matter

Front matter is a --- YAML block on the document's first line. It is never delivered. agentd reads these keys:

KeyMeaning
specThe specification version the document pins. "1" is the only version agentd implements; any other is refused. Optional.
delivery.labelsThe label style: bold (default), plain or tags.
idThe document's id. A signature's doc claim names it.
signatureThe author signature, a JWS compact serialization. It is excluded from the digest it signs.

End matter is a closing --- YAML block after a blank line at the end of the document: its record, such as owners, approvals and a changelog. It is never delivered, the author signature covers it, and malformed end matter refuses the document.

An author note runs from <!-- at column 0 to the first line holding -->. It is never parsed and never delivered, so a commented-out block does not load.

Machinery kinds

Every machinery kind except !config and !tools requires a name attribute. A name is unique per kind within a document.

Core kinds

These need no grant.

KindFormsBodyWhat agentd doesThe model reads
!workflowcontainer, sectionYAMLAdds the body to workflows: exactly as an inline entry: same variable folding, validation, content hash and run pinning. armed=false loads it disarmed. In the section form, the prose becomes the workflow's description. A name in the body does not name the block; the fence's does.[workflow "<name>" is loaded and runs autonomously]
!skillcontainer, set, sectionMarkdownAdds an inline skill to the skill catalogue, with description and trigger (when is an alias; trigger wins when both are set). The catalogue holds the body as delivered. An inline skill wins a name collision with a discovered one.[skill "<name>" is available — reference it as @skill/<name>], or with a trigger [skill "<name>" is available — use it when <trigger>; reference it as @skill/<name>]
!configcontainerYAMLA configuration fragment, held to the document boundary. Several !config blocks fold in order; a later block's top-level section replaces an earlier block's section whole.[runtime configuration is applied]
!mcpcontainer, leafYAMLOne mcp.servers[] entry. allow and deny (stored as exclude) filter the server's advertised tool names; an excluded tool does not exist. Takes override sub-blocks.[mcp server "<name>" is connected; its tools are available]
!streamcontainer, leaf, setYAMLOne streams.<name> entry. An empty body means the defaults.[event stream "<name>" is declared]
!toolscontainerYAMLMerges into tools:. A document may set disabled and narrow only.[tool policy is applied]
!evalcontainer, sectionYAMLNothing: test cases for an evaluation harness. The body must parse as YAML, and a target, when written, must resolve. A bare :::eval is prose.nothing
!datacontainerTableRecorded as a declaration. The rows are not delivered to the model.[data "<name>" is available]

The skill acknowledgement says @skill/<name>, the specification's spelling. agentd preloads a skill when a message holds skills.reference_prefix followed by its name, @skill:<name> by default, and the model can always load one with the skills.load tool.

Extended kinds

Each extended kind needs its family in agent.document_capabilities. agentd acts on the kinds whose entry starts with "Acts". The others are declarations: parsed, grant-checked, refused when unsafe, and counted under document in agentd --capabilities, with no runtime effect.

KindFamilyFormsBodyWhat agentd doesThe model reads
!filematerialcontainerTextDeclaration. Requires path.[file "<name>" is present at <path>]
!mediamaterialcontainer, leafMarkdownDeclaration. A remote src requires sha256.[media "<name>" is available]
!assetmaterialleafnoneDeclaration. A remote src requires sha256.[asset "<name>" is available]
!knowledgeknowledgecontainer, leafYAMLDeclaration.[knowledge base "<name>" is available]
!retrievalknowledgecontainerYAMLDeclaration.nothing
!sourceknowledgecontainer, leaf, setYAMLDeclaration.nothing
!endpointinterfacecontainerYAMLActs: becomes a workflow endpoint-<name> with one webhook start, from path, methods, auth, into, rate and respond. It loads only with into: {stream, subject}; served on the operator's webhooks.listen.[endpoint "<name>" listens at <path>]
!uiinterfacecontainerMarkdownActs: a step's schema: "@ui/<name>" takes the block's schema sub-block.nothing
!humaninterfacecontainer, leaf, setYAMLActs: a human step with to: "@human/<name>", at any depth, goes to the human's principal (the operators when none) and is announced on its channel. A reference to an undeclared human is refused.[human role "<name>" may be asked], with (may: …) when may is set
!channelinterfacecontainer, leaf, setYAMLDeclaration.[channel "<name>" is available for <target>]
!peeridentitycontainer, leaf, setYAMLActs: one a2a.peers[] entry.nothing
!policyidentitycontainerYAMLDeclaration.nothing
!secret-refidentityleaf, setnoneActs: a string "@secret-ref/<name>" anywhere in the folded configuration becomes {{secret:<name>}}, or {{secret-file:<path>}} when the block has kind=file.nothing
!runtimecomputecontainerYAMLDeclaration. network: any is refused.nothing
!functioncomputecontainer, sectionCodeDeclaration. Requires runtime. No tool is registered for it.[tool "<name>" is available]
!testcomputecontainer, sectionMarkdownDeclaration. Requires target.nothing
!fixturecomputecontainerTableDeclaration.nothing
!gitinfracontainer, leafYAMLDeclaration.nothing
!volumeinfraleafnoneDeclaration.nothing
!imageinfraleafnoneDeclaration. Requires digest=sha256:…; a mutable tag is refused.nothing
!agentcomposecontainer, leaf, setYAMLActs: a step's template: "@agent/<name>" takes the block's template. It references a subagent template; it cannot define one.[subagent "<name>" is available]

A set of machinery delivers one line naming its members, such as [2 event streams are declared: orders, refunds]. A set of a kind with no acknowledgement delivers nothing.

In any machinery body, a line holding a recognisable literal credential (an API key, an AWS access key, a GitHub or Slack token) is refused: a literal credential is never allowed (API key) — use a secret-ref.

Sub-blocks

A sub-block lives inside its parent's body, is written without the sigil, and has no identity of its own in the document. The parent's fence must be longer than the sub-block's:

::::!mcp{name=crm}
endpoint: "https://crm.example.com/mcp"

:::override{target=delete_contact}
disabled: true
:::

:::override{target=send_email}
tags: [egress]
description: "Sends email to a customer. Confirm the address first."
:::
::::
Sub-blockParentWhat it does
override{target=<tool>}!mcpNarrows one of the server's tools: disabled: true adds it to tools.disabled; tags and description add trifecta tags and an operator annotation under tools.narrow. It can only make a tool more careful: disabled: false is refused. Needs no grant. Delivers nothing.
case!testOne test case.
signature!functionThe function's signature.
schema!uiThe schema a schema: "@ui/<name>" step reference takes.
preview!uiA preview of the interface.

Prose kinds

Prose kinds need no grant and carry no sigil. A rule may be named in brackets (MUST[escalate]: …) or with name=, so that other blocks can refer to it; the name is never delivered.

KindKeywordFormsDelivered as (bold style)
mustMUSTcontainer, keyword, alert**MUST:** …
neverNEVER, MUST NOTcontainer, keyword, alert**NEVER:** …
shouldSHOULD; SHOULD NOT or {not}container, keyword, alert**SHOULD:** …, or **SHOULD NOT:** …
mayMAYcontainer, keyword, alert**MAY:** …
alwaysALWAYScontainer, keyword, alert**MUST:** …
avoidAVOIDcontainer, keyword, alert**SHOULD NOT:** …
guardrailGUARDRAILcontainer, keyword, alert**GUARDRAIL:** …
note, infoNOTE, INFOcontainer, keyword, alert**NOTE:** …
tip, important, warning, cautionthe same in capitalscontainer, keyword, alert**TIP:** … and so on
exampleEXAMPLEcontainer, keyword, alert**EXAMPLE:** on its own line, then the body as written; **EXAMPLE (avoid):** with {avoid}
context—containerThe body inside <reference> tags, with the title attribute when given
output—container**OUTPUT (<format>) — <title>:** on its own line, then the body. Its schema attribute is never delivered.
glossary—container (definition list)One **term** — definition line per entry
form—container**Inputs to collect — <title>**, then the parameters its body references, with their descriptions
tool—container, leafIts label, capability and allow/deny policy, then the body. Requires cap.

A rule's strength orders overrides: guardrail is strongest, then never, must and always, then should and avoid, then may.

Structural kinds

KindFormsWhat it does
whencontainerDelivers its body when every fact it names matches. A fact agentd does not supply keeps the body. A value lists admissible values: agent="claude, gpt" matches either.
unlesscontainerDelivers its body unless every fact it names is known and matches.
otherwisecontainerAfter a run of when/unless blocks, delivers its body when nothing in the run was kept.
paramleaf, setDeclares a typed parameter: ::param{name=limit type=number default=5}. Requires name.
includeleafTranscludes another document by id or uri. agentd resolves none when it delivers a document itself, so the model reads > _(included instruction not available)_.

What the model reads

agentd delivers a document only when it holds something delivery renders, removes or refuses: a block, a keyword or alert line, a BECAUSE: line, an inline reference, an author note, front matter or end matter. Otherwise the model reads it byte for byte. This table shows what each revision 1.1 construct becomes, in the default bold label style.

ConstructWrittenThe model reads
Named ruleMUST[escalate]: page the on-call.**MUST:** page the on-call.
ConditionMUST (if the customer is on a paid plan): reply within an hour.**MUST (if the customer is on a paid plan):** reply within an hour.
Reasona BECAUSE: paragraph after a rule, or because= on a container**BECAUSE:** … on the line after the rule
Negated ruleSHOULD NOT: … or :::should{not}**SHOULD NOT:** …
AliasesALWAYS: …, AVOID: …**MUST:** …, **SHOULD NOT:** …
Variants:::unless{model="gpt-5.1"}, then :::otherwisethe unless body unless the model is gpt-5.1; else the otherwise body
Output:::output{format=json title="Reply"}**OUTPUT (json) — Reply:**, then the body
Example to avoid:::example{avoid}**EXAMPLE (avoid):**, then the body as written
Typed parameter::param{name=limit type=number default=5} and ${limit}5. A value that does not fit the type leaves the placeholder.
Override:::must{name=b overrides="must/a"}rule b; rule a and its reason are not delivered. A guardrail, or a rule stronger than its overrider, cannot be overridden.
Label stylefront matter delivery: {labels: plain} or {labels: tags}MUST: x, or <must>x</must>
Inline reference[[must/escalate]], [[human/lead|the lead]], [the lead](#human/lead)escalate, the lead, the lead
Author note<!-- … --> at column 0nothing
End mattera closing --- YAML blocknothing
Machinery:::!workflow{name=digest} …its acknowledgement line

Examples and verbatim bodies keep their keywords and references as written. A ${…} inside fenced code is not substituted. Inline references degrade in prose, never inside a code span or fenced code.

Facts for when and unless

agentd supplies three of the specification's context keys:

KeyValue
hostAlways agentd.
modelThe model the agent's turns use, as the provider receives it: intelligence.roles.turn, else intelligence.model, with a declared model resolved to its model.
agentThat model's family, when its id names one: claude, gpt (gpt-*, and o1, o3, o4-…), gemini, llama or mistral.

environment and locale are not supplied, and neither is agent for a model id agentd does not recognise. A condition on a key that is not supplied keeps its content. The facts come from the operator's intelligence section, read before the document's :::!config merges under it. A re-pulled OCI document and a registry read are decided by the same facts. A subagent template is decided by the model its child runs: the template's own model:, else subagents.defaults.model, else the agent's.

Grants

agent.document_capabilities lists the extended families a document may use. It is operator-only and restart-only.

FamilyKinds
(none needed)!workflow, !skill, !config, !mcp, !stream, !tools, !eval, !data, and the override sub-block
material!file, !media, !asset
knowledge!knowledge, !retrieval, !source
interface!endpoint, !ui, !human, !channel
identity!peer, !policy, !secret-ref
compute!runtime, !function, !test, !fixture
infra!git, !volume, !image
compose!agent

A block from an ungranted family refuses the document:

line 1: `:::!file` needs the `material` capability — add it to `agent.document_capabilities`

The families a document may use are the grant, intersected with the source's max_capabilities, with what the author signature attests when a publisher is pinned, and with what the delivery signature attests on a registry read with a reader. A signed folder is capped by its narrowest file.

A document that arrived over the wire (a url:, oci: or mcp: source, or a subagent template's url: or oci: source) never uses compose or identity, whatever the grant or the signature says: the specification's floor. Each such block is refused:

line 3: `:::!agent` is in the `compose` family, which a document that arrived over the wire never uses (§7.8) — declare it in the operator's configuration

Nor does such a document reach them through the blocks every document may use: a url: or oci: document whose :::!config writes a2a.peers, or that names a secret ({{secret:…}}, {{secret-file:…}}, @secret-ref/…) in a header, a step or a declaration, is refused at load, since the secret would go wherever the document points it.

Note. A name outside this table grants nothing and is not refused at load. Spell the family exactly: compose, not composition.

Configuration a document may write

A :::!config fragment, and every machinery block that folds into configuration, may write only these paths. A path is checked with everything under it.

A document may writeWhy
workflows, streams, mcp, varsWhat the agent does.
a2a.peersAnother agent this one dials: an outbound connection, like an MCP server.
context, goal, knowledge, search, memory, limitsHow it thinks, remembers and bounds itself.
intelligence.model, .models, .roles.turn, .roles.think, .roles.decide, .roles.preflight, .roles.compaction, .roles.goal, .dialect, .budget, .timeout, .structured_output, .swap_policyWhich model, and how much of it.
agent.name, .approval, .ask_human_fallback, .ask_human_unowned, .conversation_budget, .max_parallel_turns, .on_workflow_finished, .preflight, .wake_onThe agent loop's own shape.
tools.narrow, tools.disablednarrow only adds trifecta tags and annotations; disabled only takes tools away.
skills.max_bytes, .max_loaded, .reference_prefixCaps on the skill loader.
store.kind, .durability, .checkpoint, .on_error, .timeout, .max_value_bytes, .prefixThe durability class and the caps around it, never the place.
lifecycle.run_until, .idle_grace, .until_signalWhen the agent is finished.
observability.log_level, .runtime_eventsHow loud the log is, and routing runtime events into a stream the document declared.

Everything else is the operator's. A path on neither list is refused too.

Operator onlyWhy
agent.document_capabilitiesThe grants that decide which blocks this document may use.
agent.instruction, agent.promptThe source, trust pins and decryption keys. A document that rewrote them would point the next read at itself.
agent.descriptionWhat the public Agent Card tells strangers this agent is.
agent.gate_channelsWhere gates the document did not declare are announced. A document announces its own by declaring the ::!human.
agent.tools, tools.overridesThe tool grant, and re-routing a built-in onto a server. Lists concatenate when merged, so a document could only widen the grant.
securityThe gates: trifecta, egress, exec, policies, TLS trust, AAuth.
servicesThe catalogue security.egress: closed is checked against.
identityWho work is done on behalf of.
a2a.listen, .url, .tls, .bearer, .principals, .device_grant, .cors, .push, .events, .introspectionWho may talk to this agent, as what, over which socket, and what the listener shows its clients.
webhooksInbound sockets and the auth on them.
intelligence.endpoints, .token, .token_file, .headers, .auth, .providersWhere model calls go, and the credential they go with.
intelligence.roles.approveThe model that answers asks on the operator's behalf.
intelligence.routesThe models preflight may move a turn onto.
subagentsA whole child agent. A document references a template; it does not define one.
store.file, .http, .mcp, .retentionWhere state lives, and how long finished work is kept.
lifecycle.drain_timeout, .exit_code_map, .run_id, .watch_configThe orchestration contract.
observability.log_content, .audit, .otel, .metrics_addr, .health_file, .events_ring, .traceparent, .status_valuesConversation text in the log, telemetry sinks, sockets and files on the host, and which memory status readers see.
skills.dir, skills.sourcesWhere skills are read from.

A refusal names every path the document wrote that it may not:

the instruction's :::!config writes intelligence.endpoints — operator configuration is not a document's to set (§6 rule 4). …

Further rules for documents

RuleRefusal or effect
A model a document declares names no provider.writes intelligence.models.<name>.provider is refused.
A document cannot bind or grant MCP Events.the instruction declares mcp.servers[<name>].events — MCP Events bindings and grants are the operator's to declare
A workflow with a webhook start or a wait {on: webhook} needs the interface grant, however the document writes it, including workflows it references by file:, url:, uri: or dir:.… opens an inbound route on the operator's webhook listener — a served document may open one only under the interface grant
The fragment merges under the operator's configuration.At every key, a config file, environment variable or flag wins.
A turn model the operator names wins, in either spelling (intelligence.model, intelligence.roles.turn).The document's is dropped. A warning names a spelling the operator did not write.
MCP servers a document declares are added to the operator's list.A name the operator already uses is refused: duplicate server name.
Two definitions of one workflow name, from any two sources, are refused.The message names the workflow and both sources.
A subagent template's machinery faces the same boundary.It also may not write a2a, intelligence, store or lifecycle, which the parent composes for the child.

Instruction source settings

agent.instruction is the agent's standing instruction. It takes the short form, a single value, or the long form, an object naming one source plus its settings. It is reloadable, except trust, which is restart-only.

Sources

The long form names exactly one source. Naming two is refused; naming none, when the object has settings, is refused too. To run without an instruction, omit agent.instruction.

KeyFlagValueRead
text--instruction.textThe instruction itself, never read as a path or URI.—
file--instruction.fileA path. ~/ expands to $HOME.At load and on each reload.
dir--instruction.dirA folder path, or {path, glob, order}.At load and on each reload.
dir.glob--instruction.globComma-separated globs relative to path. ** recurses. Default *.md,*.markdown,*.txt,*.instruction.—
dir.order--instruction.ordername (default, path order) or date (modification time, oldest first).—
url--instruction.urlAn https:// URL (plain http:// to a loopback host only), fetched with a plain GET and no credential. Up to 3 redirects are followed, each held to the same rule and to security.egress; a redirect from https:// to http:// is refused, and so is a body over 8 MiB.At load and on each reload.
oci--instruction.ocighcr.io/acme/agent:v3 or …@sha256:… (oci:// implied), or {ref, cosign_key}.At load; a tag is polled.
mcp--instruction.mcpA resource URI any connected server serves, or {server, resource, events}. events lists MCP Events types, as a name or {name, arguments}, whose occurrences re-read the instruction.At runtime; followed by notification, poll and events.

Short form

A short-form value is classified, first match wins:

The valueRead as
contains a newlinetext
file://…a file
a single-token oci://…an OCI artifact
any other single-token scheme://…, https:// includeda resource an MCP server serves
no whitespace, ending in .md, .markdown, .txt or .instructiona file
no whitespace, starting /, ./, ../ or ~/, and ending in / or naming an existing foldera folder
no whitespace, starting /, ./, ../ or ~/a file
anything elsetext

A value read as a file that does not exist is refused, naming both readings.

agent.prompt and a subagent template's instruction take the same classification and the load-time sources text, file, dir, url and oci. For them, a short-form https:// value is fetched as url, and an mcp source is refused. agent.prompt drops end matter from every source, with a warning; nothing else in a prompt is processed.

Behaviour

KeyFlagValuesDefault
refresh--instruction.refreshauto, off, or a duration.auto
unavailable--instruction.unavailableauto, keep, freeze, drain, exit.auto
unenforceable--agent-instruction-unenforceablewarn, refuse, ignore.warn
decrypt.keys--agent-instruction-decrypt-keysKey files, each an AGE-SECRET-KEY-1… identity, 64 hex characters, or base64.—
decrypt.passphrase--agent-instruction-decrypt-passphraseA {{secret:NAME}} reference, for age scrypt envelopes.—
trust--agent-instruction-trustA list of trust pins. Restart-only.—

refresh: auto does this per source:

Sourceauto
textNothing to re-read.
file, dirNo poll. Watched when lifecycle.watch_config is on; a change reloads.
urlNo poll. Fetched again on each reload.
oci with a tagPolls every 5 minutes.
oci with a digestNever re-read.
mcpnotifications/resources/updated, any events, and a poll every 5 minutes.

A duration or off changes the poll for oci and mcp sources. A trust pin's freshness still re-checks the source when refresh is off. A re-read updates the delivered text; machinery applies on a reload or restart.

unavailable applies after startup, once the source has gone unconfirmed past its deadline:

ValueBehaviour
keepCarry on with the last good instruction.
freezeFinish live work, refuse new work until a re-read succeeds.
drainFinish live work, then exit 0.
exitExit 6 at once.
autofreeze when a trust pin names a publisher for this source, keep otherwise.

At startup an unreadable source stops the start: exit 2 for a load-time source, exit 6 for an mcp source. See CLI, environment and exit codes for every exit code.

unenforceable says what a trust pin means when it names no key file this load can use: its author keys are registry instruction://…keys.json URIs, or none at all. warn logs one warning and loads the document unverified; refuse exits 2; ignore says nothing. A key file that cannot be read is not this case: the document is refused, exit 2, whatever unenforceable says.

Trust pins

Each entry of agent.instruction.trust:

FieldMeaning
uriThe document the pin applies to, such as instruction://acme/support. A signature's doc claim must name it.
publisherThe publisher the author signature must claim. A pin without one enforces nothing.
author_keysAuthor verification keys: files holding a raw 32-byte, hex or base64url Ed25519 public key, or instruction://…keys.json URIs a registry serves. Empty on a registry source: discovered from the read's publisherKeys pointer.
delivery_keysDelivery verification keys, in the same forms.
readerThis agent's reader id, such as agent://support-desk. Setting it turns on the delivery check on registry reads.
max_capabilitiesThis source's ceiling on the grant.
freshnessThe revocation deadline, a duration. When refresh is shorter, the shorter wins.

Signatures are JWS compact serializations, Ed25519 (alg: EdDSA), over digests written sha256:<hex>. The author digest is the document's bytes with only the front-matter signature: line left out, so end matter is signed with the text. The manifest a delivery signature embeds must be the specification's S7 signed form; a delivery that embeds any other shape is refused wherever a pin sets reader. Under a pin, a registry read of a version the registry marks revoked is refused, and the running instruction is kept.

A refused verification carries the specification's Appendix B code in the agentd-instruction crate: signature-typ-mismatch, audience-mismatch, digest-mismatch, manifest-dropped-missing, unpinned-publisher, delivery-ceiling-exceeded, wire-floor or ungranted-family, and attestation for a condition without a row, such as a signature that does not parse or has expired. agentd logs the refusal's message.

A binary built without the sign feature refuses any pin with a publisher. The release binaries include it.

Log events

These log lines follow an instruction through its life. See Events and metrics reference for the full catalogue.

EventWhenFields
instruction.loadedAn OCI, folder or MCP instruction is read.uri and manifest_digest (OCI); dir, files, glob, order (folder); server, uri, version_id, resolution (MCP); bytes, version
instruction.verifiedA registry read's signatures verify.uri, publisher, kid, capabilities, delivery_checked
instruction.appliedA registry read moves to a new version.uri, old_version_id, new_version_id, delivered_digest
instruction.updatedA re-read of an MCP instruction changed its text.version
instruction.eventAn MCP Events occurrence triggers a re-read.server, event_type
instruction.reread.failA re-read failed.server, uri, reason, err
instruction.subscribe.unsupportedThe serving MCP server offers no subscriptions.server, uri
instruction.unavailableThe source went unconfirmed past its deadline.uri, server, err, policy, trust_pinned
freshness.armedThe re-read timer is set.every_ms
freshness.recoveredA re-read succeeded after a freeze.uri
skills.discoveredInline skills joined the catalogue.server: "instruction", skills

With agent.wake_on including instruction_updated, a changed instruction also leaves a note for the root conversation.

Next steps