Skip to content

feat(effort): add effort_lock setting to allow Claude Code /effort in-chat#3705

Closed
ckumar1 wants to merge 1 commit intogastownhall:mainfrom
quickserve-ai:feat/effort-lock-optional
Closed

feat(effort): add effort_lock setting to allow Claude Code /effort in-chat#3705
ckumar1 wants to merge 1 commit intogastownhall:mainfrom
quickserve-ai:feat/effort-lock-optional

Conversation

@ckumar1
Copy link
Copy Markdown
Contributor

@ckumar1 ckumar1 commented Apr 20, 2026

Summary

Today gt always sets CLAUDE_CODE_EFFORT_LEVEL in the agent's environment, which causes Claude Code to lock the effort tier for the session and refuse the in-chat /effort command. Some operators want to seed the role default but still let the agent change tier mid-session via /effort. This PR makes the lock optional via a new effort_lock setting.

Motivation

The current behavior is appropriate for tightly-managed fleets where operators want strict per-role effort and don't want agents bumping themselves to higher tiers ad-hoc. But for solo operators and exploratory work, Claude Code's /effort is a natural in-chat knob, and the env-var lock surfaces as a confusing error: "Not applied: CLAUDE_CODE_EFFORT_LEVEL=high overrides effort this session". Today the only escape hatches are gt start --effort or GT_EFFORT, both of which require restarting the session.

Changes

  • internal/config/types.go: add EffortLock *bool to both TownSettings and RigSettings. Pointer for tri-state (nil = use default).
  • internal/config/loader.go: add ResolveEffortLock(townRoot, rigPath) bool — rig overrides town, defaults to true so existing fleets see no behavior change.
  • internal/config/env.go: gate the env["CLAUDE_CODE_EFFORT_LEVEL"] = effort write on ResolveEffortLock returning true.
  • internal/config/env_test.go: tests for effort_lock=false (env var omitted) and unset (defaults to locked).

Behavior

effort_lock Env var written? /effort in-chat
(unset) — default yes refused (current behavior)
true yes refused
false no works; Claude Code starts at its own default tier

When effort_lock=false, the role-resolved effort isn't applied at startup. Operators who want both — start at the role default AND allow /effort — would need a follow-up that passes effort via Claude Code's --effort CLI flag instead of via env var (potentially overridable by /effort); that's deliberately out of scope here so the change stays minimal and predictable.

Configuration

In <townRoot>/settings/config.json or <rigPath>/settings/config.json:

{ "effort_lock": false }

Testing

  • go test ./internal/config/... — green, including the two new test cases.
  • Manual: with effort_lock: false in town settings, started a Claude session and ran /effort high in-chat — applied successfully (no override message). With the setting removed, the override message returns.

Checklist

  • Code follows project style.
  • No breaking changes — default behavior preserved (EffortLock nil → locked, same as before).
  • Tests cover both branches and the default.

…-chat

When gt sets CLAUDE_CODE_EFFORT_LEVEL in agent env, Claude Code locks the
effort tier for the session and refuses to honor the in-chat /effort
command. Some operators want gt to seed the role default but still let
the agent change tier mid-session.

Add `effort_lock: bool` to TownSettings and RigSettings (rig overrides
town; default true preserves existing behavior). When set to false, gt
omits CLAUDE_CODE_EFFORT_LEVEL from agent env entirely; Claude Code
starts at its own default and /effort works.

- internal/config/types.go: add EffortLock *bool to TownSettings/RigSettings.
- internal/config/loader.go: add ResolveEffortLock(townRoot, rigPath) bool.
- internal/config/env.go: gate the env var write on ResolveEffortLock.
- internal/config/env_test.go: cover the new behavior + unset-defaults-to-true.

Executed-By: gastown/crew/woodhouse
@github-actions github-actions bot added the status/needs-triage Inbox — we haven't looked at it yet label Apr 20, 2026
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 21, 2026

Codecov Report

❌ Patch coverage is 80.00000% with 2 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
internal/config/loader.go 75.00% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@ckumar1 ckumar1 closed this Apr 21, 2026
@ckumar1 ckumar1 deleted the feat/effort-lock-optional branch April 21, 2026 04:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/needs-triage Inbox — we haven't looked at it yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants