Type: Bug
Owner decision 2026-09-29 on melodic-software/claude-code-plugins#3172: option A. The owner approved filing the fix here. This issue references #3172 and does not close it; #3172 stays open until this ships.
Summary
The fleet's reviewed permission floor (components/claude-permissions) has no composition mechanism that reaches Claude Code cloud sessions. The one active consumer mechanism, the dotfiles chezmoi user-layer template, never runs in a cloud session (no chezmoi apply there), so cloud sessions get neither the deny safety floor nor the allow grants an unattended loop needs.
Current behavior
A fresh cloud session's ~/.claude/settings.json has no permissions block. The classifier alone governs every shell and tool call, with no reviewed deny floor and no pre-approved grants for routine unattended verbs (git add, git commit, git push, gh pr create, gh issue comment). Re-verified 2026-09-29 from claude-code-plugins#3172: no permissions in any scope, and components/cloud-environment/ and components/cloud-bootstrap/ contain no reference to claude-permissions or permissions.
Desired behavior
Before the first agent turn, a cloud session's ~/.claude/settings.json carries the full claude-permissions floor (allow and deny), composed by jq union and never by overwriting the file.
Approach (option A)
- Site:
components/cloud-environment/setup.sh, not cloud-bootstrap.sh. The floor is fleet-wide, repo-agnostic data. Respect the README's "Calling contract (frozen)" and "Network prerequisite" sections: the entry-point path and env vars stay unchanged, steps may be added, and every step stays best-effort (|| true, script always exits 0, logged WARN on failure).
- Scope: compose the full floor, not a cloud-specific subset. Plugin-scoped
allow entries for plugins a repo has not installed match nothing, so they are inert.
- Mechanism:
jq union of claudePermissions.allow and claudePermissions.deny from components/claude-permissions/claude-permissions.json into ~/.claude/settings.json. Never overwrite existing content. Honoring withdraw is optional (advisory per that key's own framing).
- Precedent for the merge shape: the dotfiles chezmoi
~/.claude/settings.json modify-template.
Verification
- Extend
components/cloud-environment/setup.test.sh and components/claude-permissions/claude-permissions.test.sh; do not replace them.
- Live check: after the composition step runs in a fresh environment,
~/.claude/settings.json contains both the deny floor and the unattended-loop allow grants.
Related
Type: Bug
Owner decision 2026-09-29 on melodic-software/claude-code-plugins#3172: option A. The owner approved filing the fix here. This issue references #3172 and does not close it; #3172 stays open until this ships.
Summary
The fleet's reviewed permission floor (
components/claude-permissions) has no composition mechanism that reaches Claude Code cloud sessions. The one active consumer mechanism, the dotfiles chezmoi user-layer template, never runs in a cloud session (nochezmoi applythere), so cloud sessions get neither thedenysafety floor nor theallowgrants an unattended loop needs.Current behavior
A fresh cloud session's
~/.claude/settings.jsonhas nopermissionsblock. The classifier alone governs every shell and tool call, with no reviewed deny floor and no pre-approved grants for routine unattended verbs (git add,git commit,git push,gh pr create,gh issue comment). Re-verified 2026-09-29 from claude-code-plugins#3172: nopermissionsin any scope, andcomponents/cloud-environment/andcomponents/cloud-bootstrap/contain no reference toclaude-permissionsorpermissions.Desired behavior
Before the first agent turn, a cloud session's
~/.claude/settings.jsoncarries the fullclaude-permissionsfloor (allowanddeny), composed byjqunion and never by overwriting the file.Approach (option A)
components/cloud-environment/setup.sh, notcloud-bootstrap.sh. The floor is fleet-wide, repo-agnostic data. Respect the README's "Calling contract (frozen)" and "Network prerequisite" sections: the entry-point path and env vars stay unchanged, steps may be added, and every step stays best-effort (|| true, script always exits 0, loggedWARNon failure).allowentries for plugins a repo has not installed match nothing, so they are inert.jqunion ofclaudePermissions.allowandclaudePermissions.denyfromcomponents/claude-permissions/claude-permissions.jsoninto~/.claude/settings.json. Never overwrite existing content. Honoringwithdrawis optional (advisory per that key's own framing).~/.claude/settings.jsonmodify-template.Verification
components/cloud-environment/setup.test.shandcomponents/claude-permissions/claude-permissions.test.sh; do not replace them.~/.claude/settings.jsoncontains both thedenyfloor and the unattended-loopallowgrants.Related