claude-api hillclimb guide: default flow dir under protected `.claude/` means allow rules don't cover the loop's own writes

Status Open
Reported on v2.1.288
Maintainer reply None cached
Activity 0 comments · opened Oct 5, 2026

Version: measured on Claude Code 2.1.288; the guide text is unchanged in 2.1.289. Bundled claude-api skill: eval-hillclimb.md (flow layout) and build-eval.md (several commands use .claude/hillclimb/<flow>/).

What happens. The hillclimb guide puts every flow at .claude/hillclimb/<flow>/, and its report command points there. Claude Code treats .claude/ as a protected path, so a permission allow rule does not pre-approve the loop's own Edit/Write calls there (_state.json, vN/change.md, vN/change.patch, narrative.md). The guide advises getting the runner command approved before the first unattended round, but that approval doesn't cover these writes. Headless, the writes are denied. Interactively they presumably prompt every time; that part is from the permission-modes docs, not probed. Either way, a round nobody is watching doesn't get through. The guide also implies the opposite: build-eval.md contrasts prompted writes outside the project with writes in the working directory, as if the latter were silent.

Repro (headless):

# <project>/.claude/settings.local.json
{ "permissions": { "allow": ["Edit(//<project>/.claude/hillclimb/my-flow/**)"] } }

cd <project> && claude -p --permission-mode dontAsk --output-format json \
  "Write the text 'x' to .claude/hillclimb/my-flow/probe.txt"
# → permission_denials lists the Write; the file is not created.

With both paths swapped to flows/my-flow/** (outside .claude/), the file is written with no denial. So it's the .claude/ protection, not the rule syntax.

Suggested fix (either):

  1. Default the flow dir outside .claude/ (e.g. hillclimb/<flow>/ at the project root), or
  2. Say in the setup step that the loop's writes under .claude/ won't be covered by an allow rule, and suggest a flow dir outside it for unattended rounds.

Writes made by the external runner's own process are unaffected; only the loop's Edit/Write tool calls are.

View original on GitHub ↗