# Setup

> Verify claude-config's readiness for this repository: the external CLI prerequisites its audit scripts need, jq (the JSON-parsing audit scripts) and curl (the plugin-drift check), and the tracked suppression record audit-pass reads at .claude/audit-pass.md, so the audit skills run instead of failing. Use when: 'set up claude-config', 'configure claude-config', 'is claude-config working', 'set up audit-pass suppressions', or an audit skill reported a missing prerequisite. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe.

- Skill: `melodic-software/setup-39` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add melodic-software/setup-39`
- Raw SKILL.md: https://api.skillmd.com/api/skills/melodic-software/setup-39/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: melodic-software (https://skillmd.com/u/melodic-software)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/melodic-software/setup-39

---


## Purpose

Setup per the uniform setup contract (`docs/PLUGIN-PHILOSOPHY.md` "Setup is explicit and repeatable" in
the marketplace repository): `check` inspects and reports, `apply` resolves. This plugin declares no
`userConfig`, and has two setup concerns:

- the external command-line tools its bundled scripts require, where `apply` is guidance-and-verify
  with no write path: it points at platform install instructions and never installs a system package;
- the **tracked consumer-project configuration** `audit-pass` reads, the suppression record at
  `.claude/audit-pass.md`, the one surface `apply` may write.

Action routing: no argument or `check` runs the check; `apply` runs the check first, then remediation.
Both are non-interactive, so never prompt when the action is given.

## `check` (read-only)

The bundled scripts are the single source of truth for what this plugin requires.

**Read it first.** Probe what it actually does, don't recite this file. Then run each probe via
Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything.

The runtime scripts and their tools:

- `${CLAUDE_PLUGIN_ROOT}/skills/audit/scripts/check-plugin-drift.sh`: jq **and** curl, plus awk and sort
- `${CLAUDE_PLUGIN_ROOT}/skills/audit/scripts/check-structure.sh` and `check-hook-coverage.sh`: jq; `fix-plugin-drift.sh`: jq plus sort
- `${CLAUDE_PLUGIN_ROOT}/skills/audit-automation-gaps/scripts/inventory.sh`: jq
- `${CLAUDE_PLUGIN_ROOT}/skills/audit-permission-grants/scripts/permission-rule-check.sh`: jq plus awk and sort
- `${CLAUDE_PLUGIN_ROOT}/skills/audit-permission-state/scripts/*.sh`: jq (required; `permission-state.sh` exits 2 without it), awk and sort; `automode-block-lint.sh` and `automode-entry-diff.sh` add python3 for an optional lane
- `${CLAUDE_PLUGIN_ROOT}/skills/draft-auto-mode-rules/scripts/draft-automode-block.sh`: jq plus awk
- `${CLAUDE_PLUGIN_ROOT}/skills/audit-pass/scripts/run-state.sh` and `${CLAUDE_PLUGIN_ROOT}/lib/check-retirements.sh`: jq (`run-state.sh` falls back to python3, then to a scan that announces itself)
- `${CLAUDE_PLUGIN_ROOT}/skills/audit-instructions/scripts/instruction-scan.sh`: grep only (POSIX; no jq)
- `${CLAUDE_PLUGIN_ROOT}/skills/audit-instructions/scripts/conflict-scan.sh`: awk **and** sort (no jq)

Only `conflict-scan.sh` and `permission-state.sh` probe for their tools; the rest call them with no
guard, so read each script's actual calls rather than trusting a single script's prerequisite block to
speak for the plugin.

1. **`jq`**, via `command -v jq`. FAIL if absent: the JSON-parsing scripts need it (`inventory.sh` degrades
   to an empty inventory; the others `exit 2` with an install remediation). Missing `jq` blocks every
   skill whose scripts parse JSON (`audit`, `audit-automation-gaps`, `audit-permission-grants`,
   `audit-permission-state`, `draft-auto-mode-rules`, and `audit-pass`'s run-state and retirement
   helpers); `audit-instructions` scans markdown and is unaffected.
2. **`curl`**, via `command -v curl`. FAIL if absent, but scoped: only the plugin-drift check
   (`check-plugin-drift.sh`) uses it and `exit 2`s without it. The rest of `audit` and every other
   skill still run; say so in the remediation line.
3. **`awk` and `sort`**, via `command -v awk` and `command -v sort`. FAIL if either is absent, and **not**
   scoped to one skill: `conflict-scan.sh` executes both and `exit 2`s naming the missing one, while
   `check-plugin-drift.sh` (both), `permission-rule-check.sh` (both), and `fix-plugin-drift.sh`
   (`sort`) reach them with no prerequisite check at all, so `audit` and `audit-permission-grants`
   fail mid-run on a bare `command not found` rather than on a named prerequisite. Say in the
   remediation line that this FAIL reaches three skills, not just `audit-instructions`. Report `awk`
   and `sort` by name rather than as one row, since a minimal shell can carry one and not the other.
4. **Bash shell**, INFO: the scripts are bash (arrays, `[[ ]]`, process substitution, `BASH_SOURCE`),
   run through Claude Code's Bash tool, which is the bash shell on every platform and Git Bash on native Windows.
   Report the resolved interpreter; FAIL only if no bash is resolvable.
5. **Network reachability**, INFO only: `audit`'s drift/freshness fetches read
   `raw.githubusercontent.com`, and a failed fetch degrades to SKIP rather than a setup failure. Do not
   fetch here; `check` performs no network call.

### The `audit-pass` suppression record

`audit-pass` reads a tracked suppression record layered per the marketplace's config-cascade
convention. Read the operative shape from
`${CLAUDE_PLUGIN_ROOT}/skills/audit-pass/reference/suppression.md` rather than inferring it. That
reference ships inside this plugin, so it resolves in an installed cache where a path out to the
marketplace's own docs does not. The cross-consumer key contract is the marketplace's published
**finding-suppression** convention, which is not a runtime dependency of this plugin. All layers
absent is a valid state (no suppressions), so report INFO, never FAIL, when none exists.

Anchor at the repo root (`${CLAUDE_PROJECT_DIR}`, else `git rev-parse --show-toplevel`), never a
CWD-relative read, which resolves a different (or missing) file depending on the subdirectory or
nested worktree the skill was invoked from, then report one row per layer. The same
tracked/ignored question has opposite correct answers per layer, so verify each on its own terms:

- **user-global** `~/.claude/audit-pass.md`: outside the worktree; no git command applies. INFO only.
- **team** `.claude/audit-pass.md`: must be tracked, probed as the pair —
  `git check-ignore -v` reports no match (a match is FAIL with the pattern) AND
  `git ls-files --error-unmatch` exits 0. Untracked while present is a hard STOP:
  teammates never receive the shared suppressions.
- **local overlay** `.claude/audit-pass.local.md`: must be gitignored and never staged. Staged or
  tracked is a FAIL: a personal deviation can reach team history.

Parse each present layer and report as malformed any entry missing **any** of its five required
keys: `check`, `claim`, `sites`, `reason`, `date`. Checking only `reason` and `date` would pass an
entry that `audit-pass` itself rejects, so readiness would report green on configuration that cannot
suppress anything. Report as malformed too an entry whose stored constituents do not hash to its own
key: the constituents are authoritative and the key is derived from them. A malformed entry does not
suppress, and a silent partial parse would turn a formatting slip into a lost check.

Report a **user-global or overlay entry for an id the team layer does not carry** as INFO
`personal-only, not applied`, naming promotion to the team layer as what makes it take effect. The
team layer is the only one that enacts a suppression, so a personal-only entry that looks live is a
finding the operator believes is accepted and is not.

## `apply` (idempotent)

Run `check`, then for each FAIL give the platform install instructions from the README Requirements.
This skill never installs system packages:

- **missing `jq`:** the platform's jq install (for example `winget install jqlang.jq`, `brew install
  jq`, or `apt-get install jq`); rerun `check` after.
- **missing `curl`:** the platform's curl install. Modern Windows and Git Bash already ship `curl`.
  Only the plugin-drift check needs it, so the rest of the plugin works meanwhile.
- **missing `awk` or `sort`:** both ship with every POSIX userland, so absence means the shell
  environment is minimal rather than that one package is missing. Git Bash and Windows `busybox`
  shims are where this shows up. Remediate by installing a full userland rather than the single tool:
  Git for Windows, which bundles both; the distribution's `gawk`/`mawk` and `coreutils` on Linux;
  `brew install gawk coreutils` on macOS. Report the two separately, since a minimal shell can carry
  one and not the other. Five skills depend on them (`audit`, `audit-permission-grants`,
  `audit-permission-state`, `draft-auto-mode-rules`, and `audit-instructions`), and only
  `conflict-scan.sh` and `permission-state.sh` `exit 2` cleanly, so do not offer the others as still
  working meanwhile.
- **no resolvable bash:** also not remediable by one package. The scripts use arrays, `[[ ]]`,
  process substitution, and `BASH_SOURCE`, so they need a real bash on `PATH`: Git for Windows on
  native Windows, the distribution's `bash` elsewhere. Nothing bundled runs until it resolves, so
  say that this FAIL blocks the plugin rather than offering a partial workaround.

The network row stays INFO and has no `apply` entry on purpose: a failed fetch degrades to SKIP by
design, so there is nothing to remediate.

After any install, re-run the relevant `check` probe and report its actual result. Never claim resolved
on the install command's exit code alone. Re-running `apply` once every probe passes changes nothing and
reports "already configured".

Then converge the one surface this plugin owns, conservatively:

- **No suppression record anywhere**: leave it that way and say so. Absent is valid; an empty
  scaffold is noise. Scaffold the team layer with the documented shape only on an explicit request.
- **Team layer present but untracked**: report the STOP and the exact `git add` the operator should
  run. Never stage on their behalf.
- **Overlay present but not ignored**: recommend the recursive `.claude/**/*.local.*` line and leave
  the `.gitignore` edit to the consumer.
- **Malformed or unrecognized entries**: report them and stop. Never rewrite, reorder, or drop an
  operator's suppression: an entry this skill cannot reconcile is a question for the operator, and a
  silent rewrite would hide the very finding the entry was suppressing.

Every write names the file and the exact change before making it, and preserves unrelated content.

## Gotchas

- **Never run a git command against the user-global layer.** `~/.claude/audit-pass.md` is outside the
  worktree, so `git check-ignore` and `git status` return a meaningless verdict there, or a
  confidently wrong one when the home directory is itself a git repository.
- **Missing config is not a failure.** All three suppression layers absent means no suppressions,
  which is the normal state for a repo that has never suppressed a finding. INFO, never FAIL.
- **Recommend the recursive gitignore line, and leave the edit to the consumer.** `.claude/**/*.local.*`
  covers flat, folder-form, and profiled overlays alike; the narrower `.claude/*.local.*` silently
  misses any nested overlay. The consumer's ignore file is their artifact; this skill never writes it.
- **An install command's exit code is not verification.** After any install, re-run the probe and
  report its actual result.

## What this skill does NOT do

- Run an audit; that is the plugin's audit and drafting skills (`/claude-config:audit`,
  `audit-automation-gaps`, `audit-instructions`, `audit-pass`, `audit-permission-grants`,
  `audit-permission-state`, `audit-prompting-postures`, `draft-auto-mode-rules`, `unhobble`).
- Write the plugin cache, Claude Code user settings, or `pluginConfigs`.
- Install system packages.
- Write the consumer's `.gitignore`, stage anything, or edit an operator's suppression entries.
- Download anything. `check` makes no network call; the audit skills' own doc/marketplace fetches are
  theirs, not setup's.

