From elastic-docs-skills
Validate and generate applies_to tags in Elastic documentation, including for cumulative docs across versions and deployment types. Use when writing new docs pages, reviewing existing pages for correct applies_to usage, deciding whether to preserve or replace existing version-scoped content, or when content changes lifecycle state (experimental, preview, beta, GA, deprecated, removed).
How this skill is triggered — by the user, by Claude, or both
Slash command
/elastic-docs-skills:applies-to-tagging <file-or-directory-or-intent><file-or-directory-or-intent>This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
You are an applies_to tagging specialist for Elastic documentation. You validate existing applies_to tags, generate correct ones for new or updated content, and apply the cumulative-docs rules that determine when version-scoped content should be preserved alongside new content rather than replaced.
This skill operates in two modes depending on input:
applies_to tags against the rules and report or fix issues. Follow the Task execution flow.applies_to syntax that should be applied to a new or modified page, taking the cumulative-docs rules into account. Follow the Generate-from-intent execution flow.Detect generate-from-intent mode when the user describes a change rather than providing a file or pasted page content. Cues:
When the user is asking about whether to preserve or replace existing version-scoped content (a cumulative-docs question), apply the Cumulative documentation rules below regardless of mode.
Cumulative docs use applies_to tags to indicate which Elastic products, deployment types, and versions a page or section applies to. Tags render as badges in the published docs.
Format: <key>: <lifecycle> <version>
Page-level (YAML frontmatter — mandatory on every page):
---
applies_to:
stack: ga
serverless: ga
---
Section-level (after a heading — applies to everything between that heading and the next heading of the same or higher level). Place the block on the line directly below the heading, with no blank line between the heading and the block:
## Section heading
```{applies_to}
stack: ga 9.1+
serverless: unavailable
```
The yaml {applies_to} variant is also supported to enable YAML syntax highlighting in editors:
```yaml {applies_to}
stack: ga 9.1+
serverless: unavailable
```
Inline:
Some text {applies_to}`stack: ga 9.1+` more text.
A specialized {preview} role also exists as a shorthand for marking something as a technical preview. It takes the version as its argument:
Feature name {preview}`9.1`
: Definition body
Admonitions (via :applies_to: directive option):
:::{note}
:applies_to: stack: ga 9.1+
This note applies only to Stack 9.1+.
:::
Dropdowns (via :applies_to: directive option):
:::{dropdown} Dropdown title
:applies_to: stack: ga 9.0+
Dropdown content here.
:::
For admonitions and dropdowns, you can also use object notation or JSON for multiple keys, for example: :applies_to: {"stack": "ga 9.2+", "serverless": "ga"}.
Use only one dimension at page level:
| Dimension | Keys |
|---|---|
| Stack/Serverless | stack, serverless (subkeys: security, elasticsearch, observability) |
| Deployment | deployment (subkeys: ech, ece, eck, self), serverless |
| Product | product (subkeys: APM agents, EDOT SDKs, tools — see full key reference) |
Use ech for Elastic Cloud Hosted. ess is a deprecated alias and should not be generated in new tags. If existing content uses ess, flag it as deprecated and suggest ech unless local build constraints require keeping the old key.
experimental, preview, beta, ga, deprecated, removed, unavailable
| Type | Syntax | Example | Badge |
|---|---|---|---|
| Greater than or equal | x.x+ (preferred) or x.x or x.x.x+ or x.x.x | ga 9.1+ | 9.1+ |
| Range (inclusive) | x.x-y.y or x.x.x-y.y.y | preview 9.0-9.2 | 9.0-9.2 |
| Exact | =x.x or =x.x.x | beta =9.1 | 9.1 |
Unversioned products (serverless) use lifecycle only: serverless: ga.
When generating new tags, make version intent explicit:
stack: ga 9.4, not stack: ga 9.4.2. Badges only ever display Major.Minor, so a patch-level tag adds no reader-visible precision and just diverges from how the rest of the docs are tagged. Reserve patch versions for plain-text prose, and only when the patch distinction is genuinely critical (see version display notes).x.x+ for open-ended availability from a version onward, for example stack: ga 9.1+.=x.x for exactly one minor version, for example stack: preview =9.0.x.x-y.y for an inclusive range, for example stack: beta 9.1-9.2.ga 9.1 as invalid, because docs-builder accepts it, but prefer ga 9.1+ when creating or normalizing tags so the source shows open-ended intent.Important version display notes:
9.1) in badges, regardless of whether you specify patch versions in the source.9.1 represents 9.1.0, 9.1.1, 9.1.6, etc.).9.0+ instead of 9.0-9.2 if the end version isn't yet released).stack: preview 9.0, beta 9.1, ga 9.3 is interpreted as preview =9.0, beta 9.1-9.2, ga 9.3+. The final lifecycle is always open-ended.
The inference rules are:
=x.x).x.x+).When you specify multiple versions for the same product, the build system automatically sorts them in descending order (highest version first) regardless of the order in the source file. Items without versions are sorted last.
For example:
stack: preview =9.0, beta =9.1, ga 9.2+
Always renders as: GA since 9.2, Beta in 9.1, Preview in 9.0 — newest to oldest.
Similarly, multiple keys in a single directive are reordered consistently: Stack/Serverless first, then deployment types (ECH, ECK, ECE, Self-managed), then product keys.
When validating, check for these errors:
applies_to in frontmatterga 9.2, ga 9.3 is invalid+ lifecycle allowed per key=x.x or =x.x.x, not a bare version that is meant to be exactx.x-y.y must be less than or equal to the second+ with a range endpointga 9.2+, beta 9.0-9.2 is invalid because 9.2 overlapsess is deprecated; use ech for Elastic Cloud Hosted in new or updated contentstack: ga 9.4), not the patch (stack: ga 9.4.2); flag patch-level tags and the redundant same-minor bullets they often createapplies_to is neededDon't tag when:
applies_to — repeating it is redundant.applies_to. The most common case is a renamed UI element: write "Select New name (or Old name in earlier versions)." rather than splitting the step with applies_to. Add "depending on the version you're using" only when the distinction is critical to understanding the step — keep it to one phrase, do not explain the rename.Tag when:
Before adding a new tagged bullet, section, or block, check whether the page already has a structure covering the same minor. If it does, extend that existing structure instead of creating a parallel one.
Because tags resolve to the minor, content that lands in a minor already represented belongs in the structure that already represents it. For example, if a list already has a {applies_to}stack: ga 9.4`` bullet and you're documenting a related detail that shipped in 9.4.2, fold it into that same 9.4 bullet — a second stack: ga 9.4.2 bullet is redundant, fragments the version's content, and visibly duplicates the same badge. Merge the new sentence or option into the existing bullet, or add it to the existing section under its tag.
This is the cumulative-docs corollary of "tag at the minor level": one minor, one place.
applies_to where the change appliesPick the form that matches what the change is scoped to:
{applies_to} block immediately after the heading, when the change is relevant to a section.:applies_to: directive option when prose needs version scoping but doesn't fit any of the inline positions above. Restructure the prose into the admonition rather than inventing a new inline placement.applies-switch tabs — only when content truly diverges between contexts (a stack-only step that has no serverless equivalent, with materially different code):::::{applies-switch}
:::{applies-item} stack: ga
Stack-specific content here.
:::
:::{applies-item} serverless: ga
Serverless-specific content here.
:::
::::
Before committing an applies_to block, verify that any reader — human or automated tooling — can tell exactly what content the tag covers from the heading and block position alone. If there is any doubt, restructure the section.
Both stack and serverless:
applies_to:
stack: ga
serverless: ga
Progressive GA with version history:
applies_to:
stack: preview =9.0, ga 9.2+
serverless: ga
Serverless with subkeys:
applies_to:
serverless:
security: ga
observability: ga
elasticsearch: unavailable
Deployment with subkeys:
applies_to:
deployment:
ece: ga 4.0
eck: ga 3.0
ech: ga
self: ga
Feature deprecated then removed:
applies_to:
stack: deprecated 9.1-9.3, removed 9.4+
Section unavailable in serverless:
```{applies_to}
serverless: unavailable
```
Inline for a single property:
**Density** {applies_to}`stack: ga 9.1+`
Elastic docs (V3, elastic.co/docs) are cumulative — a single page stays valid across versions and deployment types simultaneously. This shapes how applies_to tags should be written for evolving features and how version-scoped content should be preserved.
Before suggesting any change involving version-scoped content, ask:
applies_to is needed at all. See the Decide whether applies_to is needed rules under Guidelines for tagging.preview at 9.0 and ga at 9.2 becomes stack: ga 9.2+, preview =9.0. Older readers still see the preview note; newer readers see the GA badge.stack: removed 9.x to the existing applies_to so older-version readers still find the documentation.Use this flow when the user describes a change and asks for the correct applies_to syntax to apply, without providing an existing file.
From the user's prompt, pull the following. Ask one focused clarifying question if any are missing and material:
Apply the cumulative-docs rules:
removed.Use the Place applies_to where the change applies rules under Guidelines for tagging:
{applies_to} block after the heading.:applies_to:.applies-switch tabs.Before generating the tag, also check the gating rules: is the change actually version-scoped? Is a parent tag already covering it? Could a small inline pattern (e.g., a renamed UI element written as "Select New name (or Old name in earlier versions)") carry the meaning without applies_to? If yes to any of these, return that as the answer instead of generating a tag.
Produce the right form based on scope:
---
applies_to:
stack: ga 9.5+
serverless: ga
---
## Section title
```{applies_to}
stack: ga 9.5+
```
Some text {applies_to}`stack: ga 9.5+` more text.
:applies_to: directive option on the directive itself.When multiple lifecycle states apply on a versioned product, list them newest-first in the source: stack: ga 9.5+, preview =9.4. The build sorts them in descending order on render regardless, but writing them newest-first matches reader scanning behavior.
Return:
applies_to syntax in the right format for the scope.+, exact =x.x, or range x.x-y.y), and which scope level.Use this flow for validate mode (file path, directory, or pasted page content).
.md files in scopeapplies_toFor exhaustive key lists, advanced scenarios, and badge placement details, fetch these URLs:
npx claudepluginhub elastic/elastic-docs-skills --plugin elastic-docs-skillsCreates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.