From fbb0bd52ec72cd8cb1ac28022d5de448f7d6949a Mon Sep 17 00:00:00 2001 From: dietrich ayala Date: Wed, 7 Oct 2026 15:21:06 +0700 Subject: [PATCH] carry the box's autoMode and model into the rendered settings.json Claude Code reads autoMode only from ~/.claude/settings.json, never from settings.local.json or project settings, and /auto-mode-setup and /model both write there. Moving them out disables the rules; leaving them in deferred the file on every run, and applying that deferral would have dropped the box's auto-mode rules. 22-claude-config.sh now copies those two keys from the existing file into the render before comparing. --- flit-spec.md | 8 ++++++++ server/lib/22-claude-config.sh | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/flit-spec.md b/flit-spec.md index edab103..07cf8fb 100644 --- a/flit-spec.md +++ b/flit-spec.md @@ -875,6 +875,14 @@ remediation path is how drift alerts get ignored. > to the comparison: with no delimiter to scope around, nothing in `deliver_rendered()` can tell a > third party's addition apart from a real conflict, so keeping box-local state out of the > delivered file is the only thing that keeps this contract honest. +> +> **Two keys cannot make that move: `autoMode` and `model`.** Claude Code reads `autoMode` only +> from `~/.claude/settings.json` — `settings.local.json` and project settings are ignored for it — +> and `/auto-mode-setup` and `/model` both write there. Moved, the box's auto-mode rules stop +> applying; left in place, they defer the file on every run, and applying the deferral drops +> them. `22-claude-config.sh` therefore carries those two keys over from the existing file into +> the render before comparing. They cannot come from the payload instead: the repository is +> public and auto-mode rules name real hosts. Bail out to printing when the state is **not** already satisfied and: diff --git a/server/lib/22-claude-config.sh b/server/lib/22-claude-config.sh index 7e2862e..b81bfab 100755 --- a/server/lib/22-claude-config.sh +++ b/server/lib/22-claude-config.sh @@ -380,6 +380,21 @@ jq --arg old_handoff "$OLD_HANDOFF" --arg new_handoff "$NEW_HANDOFF" \ ) ' "$SETTINGS_SRC" >"$TMP" || die "could not render settings.json" +# autoMode and model are the box's own, carried over from the existing file +# rather than rendered. Claude Code reads autoMode only from +# ~/.claude/settings.json — never settings.local.json or project settings — and +# /auto-mode-setup and /model both write there, so a box with either set would +# otherwise defer this file on every run, and applying the deferral would +# silently drop its auto-mode rules. Neither can come from the payload: the +# repo is public and auto-mode rules name real hosts. +if [[ -f "$SETTINGS_DST" ]] && jq -e . "$SETTINGS_DST" >/dev/null 2>&1; then + jq --slurpfile box "$SETTINGS_DST" \ + '. + ($box[0] | {autoMode, model} | with_entries(select(.value != null)))' \ + "$TMP" >"$TMP.box" \ + || die "could not carry autoMode and model over from $SETTINGS_DST" + mv "$TMP.box" "$TMP" || die "could not stage the rendered settings.json" +fi + deliver_rendered "$TMP" "$SETTINGS_DST" \ "existing settings.json differs from the rendered delivery; box-local changes belong in settings.local.json, which this script never touches" \ json -- 2.51.2