[BUG] Skill effort: frontmatter is documented but has no runtime effect

Open 💬 0 comments Opened Jun 18, 2026 by bboretzky

What's Wrong?

A skill's effort: YAML frontmatter is documented as overriding reasoning effort while the skill is active, with precedence env > frontmatter > session. In the tested configurations it has no runtime effect.

When a skill whose frontmatter sets a lower effort than the session (e.g. effort: medium, or effort: low) is invoked, the skill-active turns run at the session effort level — not the frontmatter level. There is no step-down in reasoning at the skill boundary.

This reproduced at session --effort max in both headless (-p) and interactive runs, and additionally at session --effort high. In every tested run the skill-active turns tracked the session level and never the (lower) frontmatter level.

Critically, the environment/session effort lever does work as a positive control: CLAUDE_CODE_EFFORT_LEVEL=medium reduced reasoning ~50% across all turns. So the effort mechanism and the measurement method are sound — it is specifically the skill frontmatter that is ignored.

What Should Happen?

Per the documented precedence (env > frontmatter > session), a skill with effort: medium active during a session running at --effort max should lower reasoning effort to medium on the skill-active turns (and restore the session level afterward).

The documented behavior, for reference:

  • Model configuration: "Frontmatter effort applies when that skill or subagent is active, overriding the session level but not the environment variable." — and on precedence: "The environment variable takes precedence over all other methods, then your configured level, then the model default."
  • Skills frontmatter reference: effort"Effort level when this skill is active. Overrides the session effort level. Default: inherits from session."

Either the frontmatter should take effect as documented, or the documentation should be corrected to state that skill effort: frontmatter does not control reasoning effort.

Error Messages/Logs

(none — silent no-op)

There is no error. The documented field is accepted but produces no behavior change, so nothing is logged. Detection requires measuring reasoning/thinking-token usage per turn (see Steps to Reproduce).

Steps to Reproduce

  1. Create a minimal skill whose frontmatter sets a lower effort than the session will use. For example, at <project>/.claude/skills/effort-demo/SKILL.md:

``yaml
---
name: effort-demo
description: Minimal skill to test whether effort frontmatter lowers reasoning effort.
effort: medium
---
Produce a short, deterministic output: one fenced mermaid flowchart of a 3-stage CI
pipeline (build, test, deploy), then 2-3 sentences explaining the choice.
``

  1. Start a session at a higher effort:

``
claude --effort max
`
(Also reproduces at
--effort high paired with effort: low` in the skill — a larger gap makes the absence of any step-down unambiguous.)

  1. Invoke the skill — e.g. enter /effort-demo (or whatever invocation activates a skill in your setup) — so its instructions are injected and the model continues on subsequent turns. Use the fixed brief above so output size is constant across conditions.
  2. Inspect per-turn token usage from the session transcript — each assistant turn's output_tokens (which include reasoning/thinking tokens), and the reasoning portion in particular. Compare the skill-active turns to the pre-skill turns within the same session (a within-session comparison controls for run-to-run variance).
  3. Observed: skill-active turns sit at the session (max/high) reasoning level — no reduction toward the frontmatter (medium/low) level.

Expected: skill-active turns drop to the frontmatter level.

Positive control (confirms the measurement detects real effort changes — and gives a tool-free sanity check, since lower effort visibly shortens/flattens responses): repeat with CLAUDE_CODE_EFFORT_LEVEL=medium instead of skill frontmatter — reasoning drops ~50% on every turn, as expected.

Environment

  • Claude Code version: 2.1.179
  • Model: Claude Opus 4.8
  • Platform: Anthropic API
  • Operating System: Windows (the defect is at the harness/effort layer, not OS-specific — also reproduced headless / non-interactive -p)
  • Terminal: PowerShell (and headless -p)
  • Regression: unknown — only 2.1.179 was tested

Additional Information

Documentation. The effort: frontmatter override and the env > frontmatter > session precedence are documented at model-config ("Frontmatter effort applies when that skill or subagent is active, overriding the session level but not the environment variable") and the skills frontmatter reference ("Overrides the session effort level. Default: inherits from session.").

About the numbers below. "Hidden" tokens = output_tokens (which include reasoning/thinking tokens) minus an estimate of the visible content length — a noisy residual estimate, so absolute values are approximate and vary run-to-run. The signal is the within-run comparison (skill-active vs pre-skill) and the large gap to the expected lower level — not absolute thresholds. Approximate reference bands (which overlap, precisely because the estimate is noisy): max ≈ 880–1370, high ≈ 460, medium ≈ 430–670, low ≈ 150–250.

Positive control — environment effort works (so the measurement is sensitive):

| turn | session --effort max | CLAUDE_CODE_EFFORT_LEVEL=medium | Δ |
|---|--:|--:|--:|
| pre-skill | 894 | 440 | −51% |
| skill-invocation | 886 | 432 | −51% |
| post-skill | 1372 | 666 | −51% |

Skill frontmatter effort: medium at session --effort max — inert (headless and interactive); skill-active turns stay at the max band, never the medium band:

| turn | baseline (max, no frontmatter) | max + frontmatter medium (headless) | max + frontmatter medium (interactive) |
|---|--:|--:|--:|
| skill-invocation | 886 | 1166 | 984 |
| post-skill | 1372 | 1487 | 1344 |

Skill frontmatter effort: low at session --effort high — inert (rules out a "max is a special floor" explanation). The skill-invocation turn stays at the high band; it does not fall to the low target (~150–250):

| run | pre-skill turns | skill-invocation turn | expected if low engaged |
|---|--:|--:|--:|
| 1 | 465, 182 | 457 | ~150–250 |
| 2 | 461, 167 | 453 | ~150–250 |

(Across all skill-active turns the level stays at or above the pre-skill turns — i.e. no step-down toward the low target. The invocation-turn values, 457 and 453, are the cleanest signal and sit squarely in the high band.)

Precedence discrepancy. The documentation states env > frontmatter > session. The observed behavior is consistent with env > session only — skill frontmatter is absent from the effective effort chain.

Likely root cause (hypothesis). Skills appear to be instruction-injection into the parent context rather than an isolated execution with its own reasoning budget. The parent model does the work on subsequent turns at the session effort, so there is no separate "skill execution" for an effort: override to govern. The skill-active state is set on those turns; the session effort still governs them.

How this differs from related issues.

  • #34553 is a feature request to add an effortLevel: field to command/agent frontmatter. This is a defect report: the skill effort: field that is already documented has no runtime effect — a different surface (skills vs commands/agents) and a different nature (existing-but-broken vs not-yet-existing).
  • Related effort-reliability reports (#33000 /effort "Unknown skill"; #26950 effort propagation unreliable) describe intermittent effort issues; here the skill effort: frontmatter is inert in every tested run, at every session level tested.

Scope of claim. Verified with one templated skill at --effort max (headless and interactive) and --effort high, on Claude Code 2.1.179 / Claude Opus 4.8. This is not a proof for every skill or every effort level. The behavior appears consistent with a harness/effort-layer issue rather than skill content — broader skill coverage would further confirm that — but a single skill is sufficient to demonstrate the defect.

View original on GitHub ↗