Explain a single FME feature flag in plain language: purpose, default rule, and per-environment targeting state, flagging inconsistencies across environments inline. A quick-lookup/explain capability, not a search across many flags - disambiguates when the name/key given is ambiguous. Doesn't create, kill, or modify anything - see update-flag-targeting for targeting changes, manage-flag-lifecycle for metadata/archive, discover-feature-flags for multi-flag questions, manage-experiments for experiments. Trigger phrases: what does this flag do, explain this flag, how is X configured, is X on in prod, what's targeted for X.
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Answer "what does this flag do right now" for one named flag: its purpose, what serves by default, and how targeting differs (or doesn't) across environments - without touching anything.
Works through the Harness MCP server or the Harness CLI; names are from tool-map.md.
| Operation | MCP | CLI |
|---|---|---|
| List environments | harness_list · fme_environment · filters: { offset: 0, limit: 100 } · compact: false | harness list fme_environment --json |
| List flags | harness_list · fme_feature_flag · size: 50 · filters: { name, offset: 0 } · compact: false | harness list feature_flag --search <substring> --json |
| Get flag | harness_get · fme_feature_flag · params: { feature_flag_name } | harness get feature_flag <name> --json |
| Get definition | harness_get · fme_feature_flag_definition · params: { feature_flag_name, environment_id } | harness get feature_flag:definition <flag> --env <env-id> --json |
| List definitions | harness_list · fme_feature_flag_definition · params: { feature_flag_name } · filters: { offset: 0, limit: 100 } · compact: false | harness list feature_flag:definition <flag> --json |
Get org_id + project_id if not already known. Don't use the deprecated workspace_id: the Step 4 definition list is Harness-native only.
List environments up front, since Step 4 needs every environment. Complete the inventory per pagination, using explicit MCP filters.limit: 100; a full page whose total equals its length can be a fallback, so fetch another page — one call is not guaranteed to return all environments, and an environment you never fetched is unseen, not confirmed nonexistent; don't diff Step 4 against a partial list. Keep the full list with each environment's isProduction: Step 4 diffs against it for missing definitions, and Step 6 labels production environments ("is X on" questions almost always mean "in production").
Stop condition: if the user hasn't given any identifier at all (no name, key, or tag to search on), ask for one rather than listing every flag in the project as a substitute.
List flags for the substring, paging through every offset until a page returns fewer than requested — a candidate on a later page is unseen, not nonexistent, and stopping early can turn a genuine collision into a false single-match. The name filter is a substring match, so it often returns several candidates (e.g. searching checkout also returns checkout_v2 and new_checkout).
If exactly one candidate's name is an exact, case-sensitive match to what the user typed, use it without asking - the other hits are substring noise. It's genuinely ambiguous only when no candidate is exact and several are plausible.
Stop condition: for genuine ambiguity, list the candidates (name, description, rolloutStatus.name, createdAt, openInHarness link) and ask which one - don't guess by recency. Near-identical flags often share copy-pasted descriptions and rollout status, so createdAt and the link may be the only distinguishing details.
Substring search can't surface a near-duplicate that differs from what the user typed by a transposition or an extra character - neither name contains the other, so each is invisible to the other's search. If the name looks generic (short, numbered, one of a family) or the user seems unsure of the spelling, run a second search on a shorter fragment of it before treating a single hit as certain.
Get flag for the name.
Read description, tags, trafficType (an object - use .name, don't print the raw object), owners (array of {type, name} - join names with commas), rolloutStatus.name (e.g. Pre-Production, Killed), and openInHarness (direct link). Treat a missing description the same as an empty one: "no description set".
rolloutStatus is a manually set, project-level lifecycle label, not live state - a flag labeled Killed can still be live (isKilled: false) in some environments. When it disagrees with Step 4's isKilled, say so and trust isKilled.
List definitions for the flag through every page, explicitly setting MCP filters.limit: 100 and advancing filters.offset until a short page. size is ignored here, and total can be only the page length. Do not diff an incomplete definition inventory against the environment list or call an unseen environment unconfigured; report the missing coverage instead.
For each environment's definition, read isKilled (per environment - a flag can be killed in one and live in another), treatments (including any keys/segments/largeSegments/ruleBasedSegments membership nested on individual treatments - these are the individual targets, evaluated before rules), defaultTreatment (served when the flag is killed or the traffic isn't allocated), defaultRule (buckets served when no targeting rule matches), rules (each with buckets + a condition), trafficAllocation, and impressions.lastImpressionAt (most recent impression; null = never received traffic). If impressions is absent, report last impression as unknown, not as unused.
Diff the returned environments against Step 1's full list explicitly. An environment with no definition is "not configured in <env>" - a distinct state, not a copy of another environment's config.
Compare across environments before writing the summary, not after - inconsistency-spotting is the point of this skill, not an afterthought:
isKilled the same across environments? A flag killed in one environment and live in another is the single most important inconsistency to surface - it usually means a rollback happened in one place and never propagated, or was never meant to.defaultTreatment and defaultRule treatment allocation, or does one environment default differently (e.g. prod at 30/70, staging at 50/50)?rules (same conditions, same treatment allocation), or does one environment have rules the others lack?trafficAllocation, or is one environment running a partial rollout while another is at 100%?Call out every difference explicitly - a flag behaving differently between staging and prod is very often exactly what the user needs to know, not noise to summarize away.
## <flag_name>
<description, or "no description set">
**Traffic type:** <trafficType> **Owners:** <owners, or "none set">
**Rollout status:** <rolloutStatus.name> **Link:** <openInHarness URL>
### Per-environment state
| Environment | Prod? | Killed | Default treatment | Individual targets | Rules | Traffic allocation | Last impression |
|---|---|---|---|---|---|---|---|
| <env> | yes/no | yes/no | <defaultTreatment> (<defaultRule treatment allocation>) | <n> key(s)/segment(s) across treatments, or "none" | <n> rule(s) - <one-line summary each> | <trafficAllocation>% | <lastImpressionAt, "never", or "unknown"> |
### Notable
<any cross-environment inconsistency from Step 5, or "consistent across all environments" if none>One line per rule (condition -> treatment allocation); offer Get definition (from Tools table) for full matcher detail instead of dumping raw JSON. The Prod? column comes from Step 1's isProduction, never from the environment name (names like env-7 or blue say nothing).
If no environment has a definition, skip the table:
## <flag_name>
<description, or "no description set">
**Traffic type:** <trafficType> **Owners:** <owners, or "none set">
**Rollout status:** <rolloutStatus.name> **Link:** <openInHarness URL>
This flag exists but has no targeting configured in any environment yet.If the question was scoped ("is X on in prod?"), answer it in that case too rather than leaving the reader to infer it: with no definition there, the flag isn't serving anything in that environment and SDKs fall back to the control treatment - it's unconfigured, not on or off.
new-checkout flag do?" - Steps 2-3 for purpose, Step 4-6 for full per-environment breakdown.dark-mode on in production?" - Steps 2-4, but answer can be scoped to just the production environment's default treatment/rules rather than full table.checkout-v2 and checkout-v2-mobile; ask which one.beta-banner behaving differently in staging vs prod?" - Jump to Step 4 comparison and lead answer with Step 5 inconsistency.| Problem | Cause | Fix |
|---|---|---|
| Flag name matches nothing | Confirm org_id/project_id first - a flag in a different project looks nonexistent | Don't assume it was deleted |
isKilled disagrees with what the default treatment looks like | Trust isKilled - a flag can default to off without being killed | Report isKilled as "is this live here" and the default rule/treatment separately |
| The definition list is empty for every environment | The flag exists (Step 3 succeeded) but was never configured anywhere, typical for flags created ahead of rollout planning | Say so; don't treat it as an error or retry |
Generic errors: see tool-map.md.
harness/harness-ai
ca2ab81
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.