Skip to content

new(bin/install-claude-permissions.sh): allow-list the toolkit's safe wrappers in .claude/settings.json - #83

Merged
MendixMau merged 2 commits into
masterfrom
claude/settings-allow-rules
Sep 16, 2026
Merged

MendixMau merged 2 commits into
masterfrom
claude/settings-allow-rules

Conversation

@MendixMau

Copy link
Copy Markdown
Owner

Base of a two-PR stack. The follow-up (exec approval defaults to auto, per-harness auto-run, stale-toolkit-clone warning) lands on top of this branch.

Direct lane

What changed and why (one paragraph):

mxcli init seeds <project>/.claude/settings.json with Bash(./mxcli:*), but every skill and stamped instruction file in this toolkit tells the agent to run the model through the safe wrapper bin/exec.sh (snapshot first, mxbuild after, auto-restore on failure) instead. Neither that wrapper, the other installed bin/*.sh scripts, the toolkit's own bin/*.sh run by absolute path, nor mx under ~/.mxcli/mxbuild/*/modeler/mx were ever allow-listed, so every exec through the safe path raised a harness permission prompt, which defeated bin/exec-approval.sh --set auto (that knob decides whether the agent asks; it has no say over whether the harness prompts). New bin/install-claude-permissions.sh <project> [--check|--uninstall] merges the fixed allow-list into permissions.allow (idempotent, backup first, never touches deny, never adds Bash(*), tracks what it added so --uninstall removes only that). bin/init-project.sh runs it at scaffold time; bin/sync-project.sh runs --check and reports missing entries without writing, since writing settings.json under a live session would race it. Rule syntax verified against the Claude Code permissions docs and cited in the header.

Field evidence: run against a fresh scratch project scaffolded by init-project.sh in this session: 11 entries added, --check afterwards reports all present. The fixture's "existing settings.json" input is a verbatim capture of what mxcli init writes (2026-09-16), not hand-typed.

  • No client data anywhere in the diff
  • For a new/changed instrument: golden input captured (not hand-written); both layouts unaffected (settings.json lives at the project root in both); Bash 3.2 + Python via the same resolver install-claude-hooks.sh uses, check-portability.sh clean
  • For a new skill: routing row added — n/a (README pointer only; render-routing.sh --check passes at 79,975 / 80,000)
  • CHANGELOG.md line appended in this PR, crediting the source project or person (CI-checked)
  • New bug entries headed ## BUG-DRAFT-<slug>: — n/a

Checks run (verbatim counts): check-scripts.sh 77/77 shell + 20/20 node · check-portability.sh clean (129 files) · LEAKGUARD_ALLOW_NO_DENYLIST=1 check-no-client-data.sh clean (549 files) · check-pr-discipline.sh origin/master clean · render-routing.sh --check in sync · new tests/wave2/test-install-claude-permissions.sh PASS=26 FAIL=0.

Known follow-up already scoped into the stacked PR: the two entries carrying the absolute toolkit-root path move to .claude/settings.local.json (untracked, per-machine) so no home-directory path lands in a tracked project file.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw


Generated by Claude Code

r and others added 2 commits September 16, 2026 13:04
… wrappers in .claude/settings.json

mxcli init seeds Bash(./mxcli:*) but nothing for bin/exec.sh, the other
installed bin/*.sh scripts, this toolkit's own bin/*.sh run by absolute
path, or mx under ~/.mxcli/mxbuild/*/modeler/mx -- every skill and
CLAUDE.md tells an agent to run the model through the SAFE wrapper
instead, so every one of those calls raised a Claude Code permission
prompt, silently defeating bin/exec-approval.sh --set auto.

Same merge pattern as install-claude-hooks.sh (Python via
lib/portable.sh's require_py, backup before write, merge never
overwrite). --check reports what's missing without writing;
--uninstall removes only the entries this script itself added
(tracked in a sidecar file), so a pre-existing Bash(./mxcli:*) from
mxcli init is never touched either way. Rule syntax verified against
the Claude Code permissions docs before picking the patterns.

Wired into init-project.sh (scaffold time, non-fatal) and
sync-project.sh (--check, reported as a stale-wiring finding).

New fixture tests/wave2/test-install-claude-permissions.sh (26/26):
fresh project, merge into a real captured mxcli init settings.json,
idempotent re-run, --check naming, --uninstall leaving pre-existing
entries alone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
@MendixMau
MendixMau merged commit cee5e02 into master Sep 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant