sync-claude-permissions — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited sync-claude-permissions (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Global, project-agnostic skill. Reads only the current project's .codex/rules/default.rules, translates prefix_rule(...) entries to Claude Code Bash(...) permission syntax, diffs against .claude/settings.local.json, and writes only the user-approved new entries. Every proposed rule requires explicit per-rule approval before any write.
This skill intentionally syncs project-local rules only. Do not read or fall back to ${CODEX_HOME:-~/.codex}/rules/default.rules: personal/global Codex rules may affect the active Codex session, but they are outside this project-local sync workflow.
Complements setup-permissions (which predicts rules from the stack) by operating on already-written project-local Codex rules rather than generating from scratch. Treat .codex/rules/default.rules as the source for this operation even when its rules were originally adapted from Claude Code settings.
Reconstruct the longest unambiguous prefix from the pattern array:
Codex pattern | Claude rule(s) |
|---|---|
["git", "status"] | Bash(git status:*) |
["git", ["status", "diff", "log"]] | Bash(git status:*), Bash(git diff:*), Bash(git log:*) |
["git", "-C", "/repo", ["status", "log"]] | Bash(git -C /repo status:*), Bash(git -C /repo log:*) |
["npm", "run", "test"] | Bash(npm run test:*) |
["./install.sh"] | Bash(./install.sh:*) |
When a pattern contains nested lists (one-of alternatives), expand each alternative into one Claude rule. If expansion would produce more than 8 rules from a single source entry, collapse to the common prefix and warn the user that the translation is broader.
Codex decision | Claude target |
|---|---|
"allow" | permissions.allow |
"deny" | permissions.deny |
"prompt" | NOT ported — Claude Code's default for uncovered commands is already to prompt; no rule needed |
["cp", "/home/user/...", "..."]) → flag as"manually review — contains absolute paths"; never auto-port.
Always use Bash(prefix:*) colon notation (e.g. Bash(git status:*), never Bash(git status *)).
Read .codex/rules/default.rules relative to the current working directory. If the file does not exist, report it and stop - do not create it and do not fall back to ${CODEX_HOME:-~/.codex}/rules/default.rules.
Parse all prefix_rule(...) blocks. A block spans from prefix_rule( to its matching ). Within each block extract:
pattern — the inline TOML array (may span multiple lines); parse it as a whole unit.decision — "allow", "deny", or "prompt".justification — informational string; surface it in the approval prompt.Read .claude/settings.local.json if it exists; if not, treat permissions.allow and permissions.deny as empty (the file will be created in step 5). Also peek at .claude/settings.json for already-present entries to avoid duplicates across both files, but write exclusively to .claude/settings.local.json.
Parse permissions.allow and permissions.deny arrays.
For each prefix_rule block:
decision = "prompt", absolute-path pattern, or expansion > 8entries (collapse case).
If every rule is either already synced or not portable, report "Already in sync — nothing to add." and stop.
Before asking for approval, display:
Rules to add (N new)
allow:
- Bash(git status:*) ← allows git status; does NOT allow git push or git reset
...
deny:
- Bash(rm:*)
Already synced (M rules, skipped)
- Bash(./install.sh:*)
...
Deliberately NOT ported
- [git reset / checkout / push] decision = "prompt" — already Claude Code default behavior
- [cp /home/user/...] absolute paths — flag for manual reviewUse AskUserQuestion with multiSelect: true, grouping proposed rules by category (git / build-test / package-manager / project-scripts / other). For each rule show:
Bash(git status:*))justification: "allows X; does NOT allow Y"Also display the "Deliberately NOT ported" section as informational (not a question), so the user sees what was withheld and why.
If there is only one category, a single multiSelect question is fine.
For each approved rule:
permissions.allow or permissions.deny in .claude/settings.local.json. {
"permissions": {
"allow": [],
"deny": []
}
}permissions key, add it.Echo back exactly what was written and to which file.
.codex/rules/default.rules; never read personal ${CODEX_HOME:-~/.codex}/rules/default.rules as a fallback, and never modify the project-local source file.
with the note "already Claude Code default behavior (prompt); no rule needed." Never add it to allow or deny.
user decide whether a portable equivalent makes sense.
.claude/settings.json,global ~/.claude/settings.json, or any Codex file.
Bash(...) rule must use prefix:* colon notation.file from scratch.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.