Inside Claude Code's Dynamic Workflows
TL;DR
Dynamic workflows let Claude Code write a deterministic JavaScript script that orchestrates dozens to hundreds of subagents — fan out, adversarially verify, synthesize — for tasks too big for a single agent. Research preview, launched May 28, 2026 alongside Claude Opus 4.8. Powerful, and token-hungry by design.
A research-preview feature that shipped on May 28, 2026 alongside Claude Opus 4.8, in which Claude Code stops being a single agent and instead writes a small JavaScript program — a harness — that fans work out across dozens to hundreds of subagents, has other agents try to refute their findings, and folds the survivors into one coordinated answer. The orchestration is plain, deterministic code; only the work inside each step is model-powered. Its most interesting property is not the parallelism but the inversion: the model now writes its own coordination logic, on the fly, custom-built for the task in front of it.
A note up front
I wrote the research for this post by running a dynamic workflow. To gather and fact-check the material below, Claude Code spun up 15 subagents across three phases — seven fetched and extracted sources in parallel, seven adversarially tried to refute the flashiest claims, and one synthesized a brief. Per the run’s own usage readout, that burned ~379,000 tokens across 126 tool calls in about seven and a half minutes. It also hit a real bug halfway through (URL is not defined — the sandbox doesn’t expose the URL global), which I fixed by editing the generated script file on disk and relaunching it. So this is partly a feature review and partly a field report.
That dual role means a sourcing caveat is in order, the same one this blog applies to any thinly-documented subject:
Dynamic workflows are a research preview with a deliberately thin and partly self-referential public record. Anthropic’s docs describe the concept; they do not publish a script-API reference. The fullest public account of the actual primitives is a single developer’s write-up. The flagship performance story is a port of one codebase, described by the vendor, that is explicitly not in production. Where a claim rests on one source — or on my own firsthand use — this post says so.
What this actually is
The official definition is short. Per the Claude Code docs:
“A dynamic workflow is a JavaScript script that orchestrates subagents at scale. Claude writes the script for the task you describe, and a runtime executes it in the background while your session stays responsive.”
Three words in that sentence carry the weight.
“JavaScript script.” The coordination logic — the loops, the branches, the fan-out, the place where results get merged — is ordinary, deterministic code. The intelligence lives inside each step. As developer Alexander Opalic put it in the most detailed public walkthrough so far: “You write the control flow as plain code, and each individual step is delegated to a fresh subagent… The orchestration is deterministic; only the work inside each agent() call is model-powered.” This is the load-bearing design decision. A model improvising “who does what next” across fifty turns drifts. A for loop does not.
“Claude writes the script.” You do not author the harness. You describe a task; the model emits the orchestration program. That is the “dynamic” in dynamic workflows, and Anthropic frames it as a capability that only became viable with a strong enough model: “With Claude Opus 4.8 and dynamic workflows, Claude is now intelligent enough to write a custom harness tailor-made for your use case.” (For what it’s worth, the model writing these words is Opus 4.8, and the workflow that researched this post is one it wrote.)
“In the background.” The script runs in an isolated runtime, not in your conversation’s context window. “Intermediate results stay in script variables instead of landing in Claude’s context,” the docs note — which is the whole point. A 200-file migration’s worth of intermediate state never touches the chat history, so the plan can be arbitrarily large without blowing the context budget.
It helps to be precise about what dynamic workflows are not:
- Not one agent thinking harder. The premise is that some problems are “too big for one pass by a single agent.”
- Not a static, hand-written pipeline. Anthropic contrasts them with workflows built using the Claude Agent SDK or
claude -p: those “need to work for all edge cases, [so] they are usually more generic.” A dynamic workflow is disposable and task-specific. - Not model-driven coordination. The script is fixed once written; agents don’t negotiate. (This is the key contrast with agent teams — more below.)
- Not able to touch your files directly. “No direct filesystem or shell access from the workflow itself” — the agents read, write, and run commands; the script only coordinates them.
- Not for everything. “Most traditional coding tasks do not need a panel of 5 reviewers.”
Why it exists: three failure modes
The clearest justification comes from the follow-up essay “A harness for every task,” by Anthropic’s Thariq Shihipar and Sid Bidasaria. Long single-agent runs fail in three recurring ways, and a workflow is a structural fix for each:
- Agentic laziness — “Claude stops before finishing a particularly complex, multi-part task and declares the job done after partial progress, for example addressing 35 of the 50 items in a security review.” A loop that runs until a stop condition doesn’t get bored at item 35.
- Self-preferential bias — “Claude’s tendency to prefer its own results or findings, especially when asked to verify or judge them against a rubric.” A separate agent, with its own clean context and an adversarial prompt, doesn’t have that attachment.
- Goal drift — “the gradual loss of fidelity to the original objective across many turns, especially after compaction.” The objective lives in the script, not in a context window that gets summarized away.
The common mechanism: each subagent gets a fresh context window and exactly one focused goal. Isolation is the feature.
How it works: the script
Here a careful sourcing distinction matters, because it’s the single biggest credibility risk in writing about this feature.
Anthropic’s docs page is a conceptual guide — “Orchestrate subagents at scale” — and it deliberately does not publish function signatures. The four spawn-and-coordinate functions — agent(), parallel(), pipeline(), and workflow() — are documented publicly in exactly one place I could find: Opalic’s write-up, where the signatures are explicitly developer-reported. I can add a third data point — I exercised these primitives directly to produce this post — but you should treat the exact names and shapes as observed, not officially specified; a research preview can rename them tomorrow.
With that caveat loud and clear, the surface looks like this. In my run, every generated script opened with a meta header, then used a handful of orchestration functions:
export const meta = {
name: 'research-feature',
description: 'Gather sources, refute the flashy claims, synthesize a brief',
phases: [{ title: 'Gather' }, { title: 'Verify' }, { title: 'Synthesize' }],
}
// 1. FAN OUT — one agent per source, each forced to return validated JSON
phase('Gather')
const gathered = await parallel(SOURCES.map((s) => () =>
agent(`Fetch ${s.url} and extract the facts that matter, with verbatim quotes.`,
{ phase: 'Gather', schema: SOURCE_SCHEMA })
))
// 2. VERIFY — an adversarial fact-checker per claim, told to refute, not confirm
phase('Verify')
const verified = await parallel(CLAIMS.map((c) => () =>
agent(`Try to REFUTE this claim. Default to skeptical. Find the most primary source.\n${c}`,
{ phase: 'Verify', schema: VERDICT_SCHEMA })
))
// 3. SYNTHESIZE — a barrier: one agent merges everything into a sourced brief
phase('Synthesize')
return await agent(`Turn this material into a brief.\n${JSON.stringify({ gathered, verified })}`,
{ phase: 'Synthesize' })
That is a lightly-cleaned version of the script that researched this article — which makes it a good place to be precise about provenance, including my own. The agent() and parallel() calls it shows line up with Opalic’s public account (so do pipeline() and workflow(), which I describe below). The meta header and the top-level phase() calls do not appear in any public write-up I found — not even Opalic’s — so they rest entirely on my own run. I’m including them because they’re what I actually saw, but treat those two as the most provisional detail in this whole section. A few primitives are worth understanding in detail.
agent(prompt, opts?) spawns one subagent in its own context window. Without a schema it returns text; with a schema (a JSON Schema), the subagent is forced to produce validated structured output, and the validation happens “at the tool-call layer so the model retries on mismatch.” That last detail is what makes fan-out-and-merge practical: every agent hands back a typed object, so the merge step is plain data processing, not brittle string parsing.
parallel(thunks) is a barrier. It runs every thunk concurrently and waits for all of them before returning. You reach for it only when the next stage genuinely needs every prior result at once — deduplicating across a full result set, an early exit on a total count, a synthesis step that references “the other findings.”
pipeline(items, ...stages) is not a barrier. It streams each item through all stages independently — item A can be in stage three while item B is still in stage one — so wall-clock time is the slowest single chain, not the sum of the slowest-per-stage. Opalic’s guidance is blunt: “Default to pipeline(). Reach for a parallel() barrier between stages only when a stage needs all prior results at once.”
Determinism is enforced. Because runs are journaled for resumption, anything non-deterministic would invalidate the cache — so Date.now(), Math.random(), and an argless new Date() all throw inside a workflow. You pass timestamps in as arguments and vary prompts by index instead. It’s an unusual constraint to meet in JavaScript, and a tell that the “deterministic” framing is literal, not marketing.
Behavior and limits
These numbers are official, from the docs, and they puncture one piece of the marketing:
| Property | Value | Source’s stated reason |
|---|---|---|
| Max concurrent agents | 16 (fewer on low-core machines) | “Bounds local resource use” |
| Max agents per run | 1,000 | ”Prevents runaway loops” |
| Typical scale | ”Dozens to hundreds of agents per run” | — |
| Minimum version | Claude Code v2.1.154+ | — |
| Filesystem/shell from the script | None (agents do the I/O) | Isolation |
| Mid-run user input | None (only permission prompts pause it) | — |
The “hundreds of parallel subagents” claim, precisely. Anthropic’s announcement says workflows “run tens to hundreds of parallel subagents in a single session.” That is true as a run total, but the word “parallel” oversells the simultaneity: the runtime executes at most 16 agents at once. The hundreds accumulate over the run, not at a single instant. If you’re sizing a job — or a bill — count on 16-wide concurrency, not hundreds.
Resume, permissions, and saving
Resume is real but session-scoped. Stop a run and restart it, and “agents that already completed return their cached results, and the rest run live.” But the docs add a qualifier the launch blog glosses over: “Resume works within the same Claude Code session. If you exit Claude Code while a workflow is running, the next session starts the workflow fresh.” So the cheerful “a job that’s interrupted picks up where it left off” is true for a pause, not for quitting the app. (I saw the in-session version work: after my URL bug, I edited the on-disk script — every run writes its script to a file under ~/.claude/projects/ — and relaunched it.)
Spawned agents run loose. “The subagents the workflow spawns always run in acceptEdits mode and inherit your tool allowlist, regardless of your session’s mode. File edits are auto-approved.” That’s convenient and worth respecting: a workflow you didn’t read can rewrite files without prompting per-edit. Shell, web, and MCP tools outside your allowlist can still prompt.
Saving and triggering (all from the docs). Press s in the /workflows view to save a run’s generated script as a reusable /<name> command — into .claude/workflows/ (shared via the repo) or ~/.claude/workflows/ (personal); on a name collision the project version wins. You invoke a workflow by just asking, or with the trigger word ultracode (before v2.1.160 the keyword was literally workflow). /effort ultracode pairs xhigh reasoning with automatic orchestration. For recurring jobs, the docs suggest pairing workflows with /loop (run on an interval) and /goal (set a hard completion bar). To turn the whole thing off: disableWorkflows: true in settings, or CLAUDE_CODE_DISABLE_WORKFLOWS=1.
The only workflow that ships in the box is /deep-research, which “fans out web searches… fetches and cross-checks the sources it finds, votes on each claim, and returns a cited report with claims that didn’t survive cross-checking filtered out.” It needs the WebSearch tool.
The orchestration patterns
The harness essay names six reusable shapes. These are the canonical set; learn them and most of what a workflow can do becomes legible:
| Pattern | What it does |
|---|---|
| Classify-and-act | A classifier agent routes work to different agents or behaviors (or labels the output at the end). |
| Fan-out-and-synthesize | Split a task into steps, run an agent per step, then merge. “The synthesize step is a barrier — it waits for all the fan-out agents, then merges their structured outputs into one result.” |
| Adversarial verification | ”For each spawned agent, run a separate spawned agent to adversarially verify its output against a rubric or criteria.” |
| Generate-and-filter | Generate ideas, filter by rubric, dedupe, return only the tested survivors. |
| Tournament | ”Spawn N agents that each attempt the same task using different approaches,” then judge them pairwise until a winner emerges. |
| Loop until done | ”Loop spawning agents until a stop condition is met (no new findings, or no more errors in the logs) instead of a fixed number of passes.” |
The shape that generalizes is fan out → reduce → synthesize, and the highest-leverage one is adversarial verification: independent skeptics, each with a clean context, each prompted to refute a finding rather than rubber-stamp it — the direct antidote to self-preferential bias. The essay also sketches more specialized harnesses: a quarantine pattern for triage (agents that read untrusted public content are barred from privileged actions, which are delegated to separate acting agents — a structural prompt-injection mitigation), root-cause investigation (hypotheses generated from disjoint evidence — separate agents for logs, files, and data — each facing “a panel of verifiers and refuters”), and pairwise-comparison sorting, on the principle that “comparative judgment is more reliable than absolute scoring.”
A caution against pattern inflation: a few names floating around developer chatter are not in Anthropic’s published set. Two of them — “judge panel” and “loop-until-dry” — are Opalic’s coinages for real, useful compositions; others, like “multi-modal sweep” and “completeness critic,” I couldn’t trace to any source at all. None are official vocabulary. I’m flagging it because the gap between “a pattern Anthropic documented” and “a pattern someone found handy” is exactly the kind of thing that gets blurred in a fast-moving preview.
What it costs
There is no way around this, and Anthropic doesn’t try to dodge it. The announcement carries an explicit warning, quoted verbatim:
“Dynamic workflows can consume substantially more tokens than a typical Claude Code session, so we recommend starting on a scoped task to get a feel for usage in your work.”
(Attribution precision, because this blog cares: “substantially more tokens than a typical Claude Code session” is the blog’s phrasing. The docs say the softer “a single run can use meaningfully more tokens than working through the same task in conversation.” Same point, two registers.)
The intuition is just multiplication. Parallelism buys wall-clock time, not discount tokens — running 16 agents at once finishes sooner but costs the same as running them one after another. A community explainer from MindStudio puts illustrative numbers on it: token cost scales roughly linearly with agent count, so “100 agents processing 100 files will use roughly 1,000,000 input tokens and 200,000 output tokens,” and “a large parallel workflow can easily cost $10–$50 for a substantial codebase.” Treat those figures as one author’s back-of-envelope estimate, not Anthropic data — but the linear-scaling intuition is sound, and my own modest research run (~379K tokens for 15 agents) is consistent with it.
The cost controls that do exist:
- Scope down first. Run on one directory or one narrow question before unleashing it on the monorepo.
- Route cheap stages to a cheaper model. “Every agent in a workflow uses your session’s model unless the script routes a stage to a different one” — a classifier can send simple work to a smaller model and hard work to Opus. (The docs assert this routing exists but, again, publish no API for it.)
- Set a budget in the prompt. Per the harness essay, “you can prompt it with a budget like: ‘use 10k tokens,’ which will set the cap.” There is no documented spend-cap primitive; it’s a natural-language instruction plus the hard 16/1,000 agent caps.
- Watch it live and stop. The
/workflowsview shows per-agent token usage as the run progresses, and you can kill a run without losing completed work.
The honest summary is Anthropic’s own: workflows are “best suited for complex, high value tasks,” and “best practices are still developing.”
How it compares
vs. plain subagents
Subagents already let Claude Code delegate. The difference is coordination and scale. Subagents “only report results back to the main agent and never talk to each other,” and you get “a few delegated tasks per turn.” A workflow wraps that same subagent machinery in deterministic code — loops, branches, verification passes — and scales to “dozens to hundreds of agents per run.” Subagents are a tool; a workflow is a program that uses the tool many times.
vs. agent teams
Claude Code also has an experimental agent teams feature (behind CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1), and the contrast is the cleanest way to understand both. In a team, “you tell the lead what you want in natural language. It handles team coordination, task assignment, and delegation,” teammates “communicate directly with each other” over a shared mailbox and task list, and “the lead makes approval decisions autonomously.” That is model-driven coordination — Claude improvising the org chart turn by turn.
A dynamic workflow is the opposite: code-driven coordination. The plan is a script, fixed once written, and the agents never talk. Teams improvise; workflows commit the plan to code.
One honesty note: Anthropic never draws this comparison directly — the agent-teams docs don’t mention dynamic workflows at all. The framing above is my synthesis of two separate pages, not a claim Anthropic makes. Useful, but mine.
vs. external frameworks (LangGraph, CrewAI, and friends)
This comparison is entirely my own analysis — none of the sources I gathered mention these frameworks, so take it as editorial, not reported. Tools like LangGraph, CrewAI, or OpenAI’s Swarm are orchestration frameworks you write and maintain by hand: persistent, general-purpose graphs that must anticipate every case, living in your repo as code you own. Dynamic workflows invert the ownership model. Claude generates the orchestration per task, scoped to the job in front of it, disposable after the run unless you choose to save it — and it lives inside Claude Code rather than in a separate Python service. InfoQ’s framing is the closest supportable hook: the feature “formalizes workflows that many developers have already been assembling manually.” Whether you want the model authoring your coordination logic, versus owning a stable graph you can test in CI, is the real trade — and it’s unsettled.
The Bun proof-of-concept
Every launch needs a flagship number, and this one is genuinely striking — which is exactly why it deserves careful handling. From Anthropic’s announcement:
“Jarred Sumner used dynamic workflows to port Bun from Zig to Rust with 99.8% of the existing test suite passing, roughly 750,000 lines of Rust, and eleven days from first commit to merge.”
The described method is a near-perfect illustration of the patterns above: “One workflow mapped the right Rust lifetime for every struct field in the Zig codebase. The next wrote every .rs file as a behavior-identical port of its .zig counterpart, hundreds of agents working in parallel with two reviewers on each file. A fix loop then drove the build and test suite until both ran clean.” Fan-out, adversarial review, loop-until-done — the whole catalog, on a real million-line codebase.
Now the caveats, because the headline number invites three different ways to be wrong:
- It is not in production. Anthropic states it plainly — “while not yet in production, all of this was handled by dynamic workflows.” The Rust Bun is a proof of concept available only via
bun upgrade --canary. “Ported Bun to Rust in 11 days” must not be read as “shipped a production runtime in 11 days.” - “11 days” and “6 days” are both real, and measure different things. Anthropic’s “eleven days from first commit to merge” is the calendar span of PR oven-sh/bun#30412 from its first commit to the May 14, 2026 merge. Jarred Sumner’s own widely-quoted “6 days” measures the active rewrite to the test-passing milestone. They’re not in conflict; they’re different stopwatches. Cite either, but never a bare day-count.
- The line count depends on what you count. Anthropic says “roughly 750,000 lines of Rust.” The raw GitHub diff shows ~1,009,257 additions across 2,188 files and 6,755 commits; Sumner separately described a ~960,000-line rewrite. The 750K refers specifically to Rust source. And the 99.8% test-pass figure was, by Sumner’s own May 9 account, initially scoped to Linux x64 glibc — the merged PR later claimed all platforms.
- The clock rests on Anthropic’s word. The port branch was rebased before merge (only 250 of 6,755 commits carry exposed dates, all May 12–13), so GitHub timestamps can’t independently confirm the “first commit” that anchors the 11-day count.
It’s a remarkable demonstration. It’s also a vendor describing its own showcase, on a codebase whose maintainer Anthropic acquired in December 2025. Both things are true at once.
When to reach for it — and when not
The feature’s own documentation is refreshingly anti-hype about this, so I’ll just channel it. Reach for a workflow when a task needs breadth, verification, or scale that a single context window can’t hold: a bug hunt across an entire service, a migration touching hundreds of files, a security audit you want done to the last item, a plan worth drafting from several independent angles before you commit, a research question whose sources should be cross-checked against each other. These are the cases where the token premium buys something a single agent structurally cannot deliver.
Don’t reach for it for ordinary coding. “Most traditional coding tasks do not need a panel of 5 reviewers.” A single capable agent fixing a bug, writing a function, or refactoring a module is cheaper, faster, and just as correct. The right question before invoking one, straight from the docs, is whether the task “really needs more compute.”
Closing thoughts
The interesting part isn’t the parallelism — it’s the inversion. We’ve had parallel agents for a while; what’s new is that the model writes the coordination program itself, tailored to the task, and that the program is deterministic code rather than another layer of improvisation. That’s a genuine shift in where the intelligence sits. The hard, drift-prone, easy-to-fake part of a big agentic job — staying organized across hundreds of steps — gets handed to a for loop and a few barriers, and the model is freed to do the one focused thing each subagent is good at.
The honest framing is “promising and unproven.” It’s a research preview; Anthropic itself says best practices are “still developing” and “there is still much to discover.” The script API isn’t formally documented, the marquee benchmark is a single non-production port narrated by the vendor, and the headline “hundreds of parallel agents” is really 16-wide concurrency with a large total. None of that makes it less real — the workflow that researched this post worked, caught a discrepancy I’d have missed (the announcement was May 28, not the June date half the internet repeats), and cost about what you’d expect. It just means the right posture is curiosity with a hand on the token meter.
It changes what “asking the model to do something” can mean. The unit of work used to be a conversation. Now it can be a small program the model writes about your problem, runs against your code, checks against itself, and hands back finished. That’s worth understanding well — which is the whole reason I let it write this post’s research, watched what it did, and then told you exactly where the seams are.
A note on the sources and numbers
This feature is unusually thinly and self-referentially documented for its visibility, so, in this blog’s tradition, the honest caveats in one place:
- The announcement date is May 28, 2026, confirmed by two primary Anthropic sources (the launch blog and the Opus 4.8 news page). The early-June dates everywhere are secondary coverage — the June 2 “harness for every task” essay and InfoQ’s June 1 writeup — not the launch.
- The script API (
agent/parallel/pipeline/schema/etc.) is not in Anthropic’s official docs. It’s developer-reported (alexop.dev) and firsthand-observed (me). Signatures may change without notice. - The hard limits (16 concurrent / 1,000 total / v2.1.154+) are official. The “tens to hundreds of parallel” framing is marketing; the concurrency ceiling is 16.
- Resume is in-session only, despite the launch blog’s unqualified “picks up where it left off.”
- Cost figures of $10–$50 and “1M tokens for 100 agents” are a community author’s estimates, not Anthropic numbers. The “substantially more tokens” warning is Anthropic’s, and it’s real.
- The Bun port is a not-yet-in-production proof of concept; the 11-day span rests on Anthropic’s account, and the line/day/test numbers each depend on what’s being measured.
- Plan availability has already drifted: the launch named Max, Team, and Enterprise (admin-enabled); the current docs say “all paid plans,” adding Pro as an opt-in via
/config. - The agent-teams and external-framework comparisons are my synthesis, not positions Anthropic stated.
References
Primary / official (Anthropic)
- Introducing dynamic workflows in Claude Code — the launch announcement (May 28, 2026): definition, availability, the token warning, the Bun case study.
- A harness for every task: dynamic workflows in Claude Code — Thariq Shihipar & Sid Bidasaria (June 2, 2026): the six named patterns, the three failure modes, the static-vs-dynamic distinction,
ultracode, saving and sharing. - Orchestrate subagents at scale with dynamic workflows — official docs: the hard limits,
v2.1.154+, the resume-within-session qualifier, permissions, the/configtoggle. - Orchestrate teams of Claude Code sessions — official docs for the agent-teams contrast.
- Introducing Claude Opus 4.8 — confirms the May 28, 2026 co-launch.
Independent
- Claude Code Workflows: Deterministic Multi-Agent Orchestration — Alexander Opalic: the fullest public account of the script-level API.
- Claude Code Adds Dynamic Workflows for Parallel Agent Coordination — InfoQ.
- Rewrite Bun in Rust — PR #30412 — the primary technical artifact behind the Bun numbers (merged May 14, 2026).
Community (illustrative, lower confidence)
- Claude Code Dynamic Workflows: Spawning Parallel Sub-Agents — MindStudio: the illustrative cost/scaling estimates ($10–$50, linear token scaling). The author’s figures, not Anthropic’s.
FAQ
What are dynamic workflows in Claude Code?
A dynamic workflow is a JavaScript script that Claude Code writes on the fly to orchestrate subagents at scale. A runtime executes it in the background while your session stays responsive, fanning work out across dozens to hundreds of subagents, verifying their results, and returning a single coordinated answer. It launched in research preview on May 28, 2026, alongside Claude Opus 4.8.
How are dynamic workflows different from regular subagents?
Plain subagents handle a few delegated tasks per turn and only report back to the main agent — they never coordinate with each other. A dynamic workflow wraps subagents in deterministic orchestration code (loops, branching, verification passes) and scales to dozens or hundreds of agents per run, with hard caps of up to 16 concurrent agents (fewer on low-core machines) and 1,000 agents total per run.
Do dynamic workflows use more tokens?
Yes — substantially. Anthropic’s announcement warns that a workflow “can consume substantially more tokens than a typical Claude Code session” because it spawns many agents, and recommends starting on a scoped task. Runs count against your plan’s usage and rate limits like any other session, and parallelism reduces wall-clock time without reducing total cost.
When were dynamic workflows released?
Anthropic announced dynamic workflows for Claude Code on May 28, 2026, in research preview, alongside the Claude Opus 4.8 model release. The widely-cited “June 2” date refers to a follow-up blog post and press coverage, not the announcement itself.