Feature: Expose active effort level to hooks and Bash ($CLAUDE_EFFORT or hook payload field)

Resolved 💬 2 comments Opened May 3, 2026 by tractorjuice Closed May 8, 2026

Summary

Expose the active effort level (after any silent downgrade) to hook handlers and Bash tool invocations, similar to the existing $CLAUDE_SESSION_ID proposal in #25642. Today there is no programmatic way to determine which effort level was actually used to produce a turn's output.

Motivation

When a slash command or skill declares effort: max in frontmatter and runs on a model that doesn't support it (e.g. Sonnet 4.6), Claude Code silently downgrades to the highest supported level. This is documented behavior and works as designed — but it is opaque to anything outside the harness:

  • Hook payloads (Stop, PostToolUse, SessionEnd) do not include effort.
  • No environment variable surfaces it (CLAUDE_CODE_EFFORT_LEVEL is a session input only).
  • The model itself cannot self-report it (the knob lives in the harness, not in the prompt).
  • Transcript JSONL records model name but not per-turn effort (as far as we can observe).

Use case

We maintain ArcKit (https://github.com/tractorjuice/arc-kit), an enterprise-architecture governance toolkit with 70 slash commands. 16 commands declare effort: max and 71 declare effort: high because the deliverables (requirements specs, business cases, strategy documents) materially benefit from deeper reasoning.

Generated artifacts go into governance audit trails and we stamp **Model**: <model> into a footer. We would like to also stamp **Effort**: <effective-effort> so reviewers can see whether a document was produced at the requested depth or at a downgraded level. Today we can only record the requested effort from frontmatter, which can mislead auditors.

Proposed API

Any of the following would solve it (in order of preference):

  1. Environment variable exposed to hooks and Bash: \$CLAUDE_EFFORT (current effective level) and optionally \$CLAUDE_REQUESTED_EFFORT (what was asked for, before downgrade).
  2. Hook payload field: include effort and requested_effort in the JSON input to Stop, PostToolUse, SessionEnd, PreCompact.
  3. Transcript field: record per-turn effort alongside model in ~/.claude/projects/*/transcript.jsonl.

Option 1 is simplest for our use case and consistent with the precedent set by #25642 (\$CLAUDE_SESSION_ID).

Related

  • #25642 — Expose session ID as \$CLAUDE_SESSION_ID env var (same shape of request)
  • #51059 — Per-model effort level configuration
  • #50328, #54249, #49538 — assorted bugs/UX gaps around effort visibility

Environment

  • Claude Code: latest
  • ArcKit min Claude Code: v2.1.117

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗