---
url: 'https://adk.nht.io/glossary.md'
description: >-
  The project vocabulary of @nhtio/adk — turns, dispatch, trust tiers,
  batteries, gates, and the rest of the language the docs assume you already
  speak.
---

# Glossary

The ADK is opinionated, so its vocabulary is too. These are the words the docs use as if you already know them — the concepts and coined terms that carry the architecture. Raw API types (`MediaReader`, `SpoolReader`, every field and enum) live in the [API reference](./api/), not here; this page is the mental model, not the type signatures.

Terms are written as nouns — "turn runner", "trust tier" — because that is how you think about them. When a specific API type is the thing you'd reach for in code, it appears as a code symbol (`TurnRunner`, `Retrievable`) linked to its reference. The noun is the concept; the symbol is its implementation. That split is deliberate; do not "correct" one into the other.

Definitions take a position. If one of them annoys you, that is the design talking, and the page that owns the rationale is linked from the term.

## The execution loop

### Turn

One end-to-end agent request: input arrives, middleware shapes it, dispatch may call the model several times, state gets persisted, the runner resolves. The whole unit of work — not the model call. A turn is **not** a chat session; it is one execution unit inside whatever conversation loop your product owns. See [The Loop](./the-loop/).

### Dispatch

The model-execution cycle inside a [turn](#turn): the loop that calls the [executor](#executor-seam), chases tool calls, and exits only on a terminal [signal](#signalling) or [abort](#abort). The ADK supplies the loop; **you** supply the stopping logic, because infinite loops are still bad. The executor's contract is the [`DispatchExecutorFn`](https://adk.nht.io/api/@nhtio/adk/dispatch_runner/type-aliases/DispatchExecutorFn), and it reads a [`DispatchContext`](https://adk.nht.io/api/@nhtio/adk/types/interfaces/DispatchContext). See [LLM dispatch](./the-loop/llm-dispatch).

### Iteration

One trip through the [dispatch](#dispatch) loop: dispatch-input middleware → executor → dispatch-output middleware. Tool results become useful across the boundary — iteration N persists a tool result, iteration N+1 shows it back to the model.

### Harness

The deterministic structure around the agent — the [turn runner](#turn-runner), contexts, [pipelines](#pipeline), validation, event buses, and lifecycle signals. The harness runs the loop; it does not decide behavior. The ADK is the harness; the agent is yours.

### Turn runner

The bookkeeper for one [turn](#turn), not the agent hiding behind the curtain. [`TurnRunner`](https://adk.nht.io/api/@nhtio/adk/turn_runner/classes/TurnRunner) validates config eagerly, threads a fresh context through middleware and dispatch, emits events, and refuses to invent behavior you did not wire. It returns nothing — everything leaves through the [event buses](#functional-bus). See [Turn Runner](./the-loop/turn-runner).

### Executor seam

The hard boundary where ADK stops and your model integration begins. The runner invokes **one callback per iteration** and judges only what it streams, persists, and signals; provider plumbing is your problem — mercifully and dangerously. Your model client stays yours. See [Bring your own LLM](./assembly/byo-llm).

### Ack

`ctx.ack()` — the executor's "this dispatch succeeded, stop here" signal. One of the three terminal outcomes of [signalling](#signalling); see also the [ack/nack invariant](#ack-nack-invariant). The opposite verdict is [nack](#nack).

### Nack

`ctx.nack(error)` — the executor's "this dispatch failed" signal, carrying the error that should propagate instead of a silent stall. The failure counterpart to [ack](#ack); both are governed by [signalling](#signalling) and the [ack/nack invariant](#ack-nack-invariant). A [nack](#nack) is a reported failure, not an [abort](#abort) — abort is deliberate, nack is something going wrong.

### Signalling

The contract that terminates a [dispatch](#dispatch): [ack](#ack), [nack](#nack), or [abort](#abort). Deliberately **not** silently idempotent — two seams each claiming the final word is a bug wearing a race-condition hat. See [Signalling](./the-loop/llm-dispatch/signalling).

### Ack/nack invariant

ADK's terminal-signal law: every executor invocation must call exactly one of `ctx.ack()` or `ctx.nack(error)`, exactly once. Ignore it and you get infinite loops, double-signal explosions, or failures that vanish instead of propagating. The invariant is absolute. See [Bring your own LLM](./assembly/byo-llm).

### Abort

Intentional cancellation or refusal — **not** an error. It short-circuits the relevant path and emits nothing on the error bus. Use it when middleware means "stop, on purpose"; reaching for an exception instead is how you make a clean cancellation look like a crash. See [Abort](./the-loop/pipelines/abort).

## Pipelines and middleware

### Pipeline

An ordered sequence of [middleware](#middleware) that transforms a shared context. In ADK these sequences **are** the agent's behavior surface — the runner walks them in order, and that walking is the runtime. No hidden guardian angel runs behind them. See [Pipelines](./the-loop/pipelines).

### Middleware

A function handed a context and a `next` continuation, owning both its pre-step (before `next`) and post-step (after). Not a lifecycle hook, not a decorative callback — it is where retrieval, policy, budgets, cleanup, and most actual behavior live.

### Turn-scoped pipelines

The once-per-[turn](#turn) bookends: `turnInputPipeline` before dispatch, `turnOutputPipeline` after a successful dispatch. Retrieval, history packing, and memory updates belong here so they do not accidentally run once per model [iteration](#iteration).

### Dispatch-scoped pipelines

The per-[iteration](#iteration) sandwich around the [executor](#executor-seam): `dispatchInputPipeline` and `dispatchOutputPipeline`. Put loop bounds, retry shaping, and repetition detection here — and put retrieval here only if you enjoy paying the same bill ten times.

### Pipeline short-circuit

What happens when middleware returns without calling `next()` and without [aborting](#abort). ADK reports it as a bug (`E_PIPELINE_SHORT_CIRCUITED`), because intentional refusal already has its own channel: abort. See [Composition](./the-loop/pipelines/composition).

### Stash

The sanctioned scratchpad for cross-middleware state inside one context. Deliberately unschemed — flexible enough for strangers' middleware to cooperate, sharp enough to cut you if you do not namespace your keys. See [Stash](./the-loop/pipelines/stash).

### Context hydration

The explicit act of fetching messages, memories, retrievables, tools, and instructions into the turn context. ADK does **not** do it for you; an empty `turnInputPipeline` is a perfectly valid way to build a confident idiot. See [Assembly → pipelines](./assembly/pipelines).

### Helpers vs persistence

Two decoupled concerns inside the executor: helper methods stream the wire shape (for the UI); `ctx.store*` writes the canonical record (for durable history). They are kept apart because a UI delta and an agent's memory are not the same thing — call the helper without the store and you get a ghost message the user saw but storage never did. See [Inside one turn](./the-loop/llm-dispatch/adk-facts).

## Trust and safety

### Trust tier

A structural provenance label for content — not a vibe check on whether the prose *sounds* safe. Trust tiers exist so the renderer can keep developer authority, user data, tool output, and retrieved material from collapsing into one undifferentiated prompt soup. Declared at the source; the battery uses it to pick the [envelope](#envelope). See [Trust Tiers](./the-loop/trust-tiers).

### Envelope

The prompt-rendering discipline that wraps content in authority-specific XML boundaries, with hostile content closed by an unguessable nonce-keyed tag. It exists because asking the model to *politely ignore* injected instructions is not a security boundary — it is theater with a tokenizer. See [Envelopes](./the-loop/trust-tiers/envelopes).

### Tag escape attack

Hostile content that includes a forged closing tag (`</trusted_content>`) to break out of its envelope and run with the surrounding authority — the SQL injection of the agentic era. Nonce-keyed closing tags are the structural fix; a content-derived id is not a nonce. See [Envelopes](./the-loop/trust-tiers/envelopes).

### Prompt injection

The attack the entire trust-tier system exists to blunt: untrusted input carrying instructions the model follows as if they were yours. The defense is structural — declare provenance, render untrusted content fenced — and mis-declaring a [trust tier](#trust-tier) is an immediate vulnerability, not a style nit. See [Bring your own retrieval](./assembly/byo-retrieval).

### Memory poisoning

A delayed [prompt injection](#prompt-injection): hostile content stored now, detonating when it is recalled later. Persistence turns yesterday's attacker into today's invisible co-author — you step on the landmine months after they walked away. See [Persistence](./the-loop/trust-tiers/persistence).

### Reasoning fence

A nonce-keyed boundary around [thought](#thought) records that stops an attacker from ending a reasoning trace and inserting their own. It treats chain-of-thought as a control surface, because that is exactly what it is — own the model's reasoning and you own its decisions. See [Identity and reasoning](./the-loop/trust-tiers/identity-and-reasoning).

### Multi-identity

The two-channel rendering of participant identity: a sanitized structural channel for the provider API, and verbatim identity inside a bounded content [envelope](#envelope) for the model. It exists because an identity string is both operational metadata and attacker-controlled text — and one channel cannot safely be both. See [Identity and reasoning](./the-loop/trust-tiers/identity-and-reasoning).

### Modality hazard

The second trust axis for [media](#media): not where the bytes came from, but how instructions might be hidden in or extracted from them. Text has one read path; media has OCR, ASR, vision encoders, and embedded text — plenty of places for trouble to squat. Orthogonal to provenance, and required at construction. See [Media trust](./the-loop/trust-tiers/media).

### Trusted Courier Fallacy

The mistake of assuming output is safe because it arrived through a trusted tool. Delivery fidelity is not semantic safety — a trusted tool that fetches a stranger's web page still hands you third-party content. The courier's integrity does not launder the payload. See [Media research](./the-loop/trust-tiers/media/research).

## Retrieval, memory, and budgets

### Synthetic RAG

Giving a model retrieval behavior by **injecting** precomputed [retrievable](#retrievable) records into context through middleware — no tool-calling required. RAG as prompt architecture, not as a tool-calling talent show. It is how a tool-less small model can still answer from a corpus. The pattern and its trust rationale live in [Trust Tiers](./the-loop/trust-tiers); for the whole thing built end-to-end on a 3B model, see the [Ask ADK showcase](./showcase/ask-adk).

### Synthetic chain-of-thought

Precomputed reasoning injected into context as [thought](#thought) records, letting a fast model continue from expensive reasoning it never performed. The trick is only safe because the injected reasoning stays inside a [reasoning fence](#reasoning-fence). See [Trust Tiers](./the-loop/trust-tiers).

### RAG

Retrieval-Augmented Generation: staging external documents into the context before [dispatch](#dispatch) so the model answers from a prepared corpus rather than memorized weights. In ADK, retrieval belongs in the [turn-scoped](#turn-scoped-pipelines) input pipeline — it runs once per turn, not once per iteration — and every [retrievable](#retrievable) carries a [trust tier](#trust-tier).

### HyDE

A hypothetical-answer retrieval trick (Hypothetical Document Embeddings): generate a fake answer and embed *that* to widen semantic recall. The generated text is bait for the embedding space, not evidence — in [Ask ADK](./showcase/ask-adk) it seeds a cosine lane and gets no vote in lexical ranking.

### Sufficiency floor

A coded relevance threshold below which retrieved chunks are deemed too weak to answer from. Below it, the system refuses deterministically rather than handing the model tangential scraps and *asking it nicely* not to make things up. See [Ask ADK](./showcase/ask-adk).

### Abstain

A deliberate refusal to answer when the [sufficiency floor](#sufficiency-floor) is not cleared. In [Ask ADK](./showcase/ask-adk) the model's output is never used on the abstain path — a refusal is assembled in code, naming the closest pages as links — because the moment of lowest evidence is exactly when a generator is most tempted to invent.

### Token-Thrift

[Ask ADK](./showcase/ask-adk)'s RAG-first budgeting policy for a hard 4096-token window: measure the prompt cost once, give retrieval the largest useful allocation, and shed low-priority context instead of pretending the window is elastic. The window is a compiled ceiling, not a preference knob. It is one concrete shedding policy built on the general [context window budget](#context-window-budget) primitives; the [Ask ADK showcase](./showcase/ask-adk) builds it end-to-end, [Budgets](./the-loop/budgets) covers the primitives underneath.

### Context window budget

The model-visible content you can afford in one [dispatch](#dispatch). A budget, not a wish. ADK primitives are built so large content can be referenced, queried, or spooled instead of shoved wholesale into the next call — and [`Tokenizable`](#tokenizable) makes the cost measurable before you spend it. See [Budgets](./the-loop/budgets).

## Primitives

The eight validated data shapes the ADK threads through every turn. The entries below define the *concept*; field-level contracts live in the [API reference](./api/) and the per-primitive pages under [Primitives](./the-loop/primitives).

### Tokenizable

The text concept that makes token cost estimable instead of pretending strings are free. Every prompt-adjacent field is a [`Tokenizable`](https://adk.nht.io/api/@nhtio/adk/common/classes/Tokenizable) so budget decisions can be made locally, without a remote call. See [Tokenizable](./the-loop/primitives/tokenizable).

### Message

One unit of dialogue, attributed to a speaker — exactly two roles, `user` and `assistant`. A [`Message`](https://adk.nht.io/api/@nhtio/adk/common/classes/Message) is not a system or tool record. Tool results and RAG context are **not** messages; shoving them into a user role nukes the trust boundary and turns your data into a privilege-escalation vector. See [Message](./the-loop/primitives/message).

### Memory

Long-term context: what was learned or decided in previous conversations that should still inform this one. ADK defines the [`Memory`](https://adk.nht.io/api/@nhtio/adk/common/classes/Memory) primitive and the retrieval/storage contracts; it does not decide where memories live, how they are ranked, or when they are forgotten — the [retrieval middleware](#context-hydration) sets the scores at query time. See [Memory](./the-loop/primitives/memory).

### Retrievable

Fresh external context pulled in **for this turn**: RAG chunks, web results, KB snippets, uploaded-document passages. A [`Retrievable`](https://adk.nht.io/api/@nhtio/adk/common/classes/Retrievable) is not [memory](#memory). It must declare a [trust tier](#trust-tier) before the executor is asked to trust it — there is no unknown tier and no safe default. See [Retrievable](./the-loop/primitives/retrievable).

### Thought

Reasoning kept separate from dialogue. A [`Thought`](https://adk.nht.io/api/@nhtio/adk/common/classes/Thought) exists because reasoning has different authority, replay behavior, and compaction value than something the assistant actually said to the user — and because it needs its own [reasoning fence](#reasoning-fence). See [Thought](./the-loop/primitives/thought).

### Media

A typed handle to a binary asset — image, audio, video, document — that rides on messages and tool results without inlining bytes into a string. [`Media`](https://adk.nht.io/api/@nhtio/adk/common/classes/Media) keeps bytes lazy; the renderer reaches into the asset only at the wrap site. It carries a required two-axis trust pair: provenance ([trust tier](#trust-tier)) and [modality hazard](#modality-hazard). See [Media](./the-loop/primitives/media).

### Tool call

A request for a tool invocation plus its eventual result, bound by a stable checksum so the loop can detect repetition and tie output to the call that produced it. Persisted [`ToolCall`](https://adk.nht.io/api/@nhtio/adk/forge/classes/ToolCall) records are the audit trail and the model-visible history your tool loop needs. See [ToolCall](./the-loop/primitives/toolcall).

## Tools and artifacts

### Tool

A validated callable capability offered to the model: name, description, input schema, and handler, with the schema as the single source of truth for the contract. A [`Tool`](https://adk.nht.io/api/@nhtio/adk/forge/classes/Tool) has its arguments validated and downstream errors wrapped by ADK; you decide which tools exist and how their results are handled. See [Tools](./the-loop/tools).

### Trusted tool

A tool marked `trusted: true`, whose string/artifact results render in the trusted [envelope](#envelope). The flag describes *delivery*, not the safety of whatever the tool fetched — see the [Trusted Courier Fallacy](#trusted-courier-fallacy) — and it is **not** consulted for [media](#media) results, which always carry their own trust. See [Trust and safety](./the-loop/tools/trust-and-safety).

### Ephemeral tool

A one-[dispatch](#dispatch) capability, usually forged around a specific [artifact](#artifact) handle. If it survives past its dispatch the model sees stale handles, so the registry prunes it on `ack`. See [bindContext and describe](./the-loop/tools/bind-context-and-describe).

### Artifact

The ADK's answer to a tool that produces more output than belongs in a context window: a produced result with identity that can be inspected without pretending it is just another string in the prompt. Small results inline; serious ones get a handle. See [Artifacts](./the-loop/artifacts).

### Spooled artifact

An [artifact](#artifact) backed by a re-openable reader instead of an eagerly held body. [`SpooledArtifact`](https://adk.nht.io/api/@nhtio/adk/spooled_artifact/classes/SpooledArtifact) gives the model a query surface — `head`, `tail`, `grep`, range reads — so large outputs stay out of both process memory and the context window until a specific slice is actually needed. See [Artifacts](./the-loop/artifacts).

## Boundaries and integration

### Bring Your Own Everything

The architectural contract. Bring your own model provider, API client, persistence layer, vector index, queue, auth, telemetry, prompt format, tool-calling protocol, and deployment environment. ADK supplies the boundaries so those choices stay explicit instead of buried inside an adapter. See [What ADK is](./what-adk-is).

### Battery

An opt-in prebuilt integration — an LLM adapter, a storage spool, a tool collection — not a default behavior. Batteries save wiring when they fit; ADK will not secretly load one just because your app would be nicer if it did. Importing one (and its peer dependency) is always your explicit choice. See [Assembly](./assembly/).

### Gate

ADK's cooperative suspension point for safety, authorization, and human oversight: open a [`TurnGate`](https://adk.nht.io/api/@nhtio/adk/common/interfaces/TurnGate) with `ctx.waitFor(gate)` and the pipeline pauses until something external settles it. It pauses exactly the scope where you open it — which is why placing it in the wrong pipeline is not a small mistake. Every human-in-the-loop and approval flow attaches here. See [Gates](./the-loop/gates).

### Standing instruction

A persistent operational rule loaded into every future turn — developer-, operator-, or model-updated. It has a far larger blast radius than ordinary [memory](#memory): a wrong memory costs a few ignored tokens, a wrong standing instruction becomes policy forever. That asymmetry is why writing one is gated and writing a memory is not. See [Persistence](./the-loop/trust-tiers/persistence).

### Functional bus

The event interface for things that are part of product behavior: streamed messages, thoughts, tool calls. The test is simple — if removing the listener changes what the agent *does or shows*, it belongs here. See [Events](./the-loop/events).

### Observability bus

The event interface for instrumentation: turn/dispatch/iteration lifecycle, gate and tool execution events, errors-as-telemetry. If an observer decides product behavior, you have wired a feature to your telemetry by mistake. See [Events](./the-loop/events).
