claude-skills / audit
CLAUDE.md0 starsChanged 30 days agoMITView on GitHub
Rules and commands bound to /audit's own tooling. Loaded when a file under audit/ is read. Cross-cutting rules that also apply here (orchestrator writes/subagents return, fresh-shell-per-Bash-block, marker hashing, model:inherit, hook scope) live in the root CLAUDE.md. /audit is a PR review before push (rebuilt 2026-10-03, replaces the per-dimension Workflow pipeline). Flow: deterministic pre-checks, then the built-in /code-review high in a review worktree (plus one code-reviewer checklist agent when orch_sensitive_paths returns paths), triage by the orchestrator, one spec-executor fix round, one…
- Reads credentials
- Commits and pushes
In this repository13 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- delegate/CLAUDE.mdCLAUDE.md
- plan-it/CLAUDE.mdCLAUDE.md
- screens/CLAUDE.mdCLAUDE.md
- ship/CLAUDE.mdCLAUDE.md
- store-assets/CLAUDE.mdCLAUDE.md
- auditSkill
- delegateSkill
- plan-itSkill
- readinessSkill
- screensSkill
- shipSkill
- store-assetsSkill
The file
We split this CLAUDE.md into the rules it gives an agent
2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 20
No verifier agents, no backlog file, no start question, no dimension selection.
- Distinctive: line 74
Every test is a single script.
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
/audit internals
Rules and commands bound to /audit's own tooling. Loaded when a file under audit/ is read.
Cross-cutting rules that also apply here (orchestrator writes/subagents return, fresh-shell-per-Bash-block,
marker hashing, model:inherit, hook scope) live in the root CLAUDE.md.
Architecture
/audit is a PR review before push (rebuilt 2026-10-03, replaces the per-dimension Workflow pipeline).
Flow: deterministic pre-checks, then the built-in /code-review high in a review worktree (plus one
code-reviewer checklist agent when orch_sensitive_paths returns paths), triage by the
orchestrator, one spec-executor fix round, one test run, log, push marker. audit/SKILL.md stays under ~150 lines.
Why (evidence, 2026-10-02/03):
- The old pipeline used about 45% of the weekly usage limit in 7 days (single runs 8-78 M weighted tokens).
- A benchmark on 5 historical diffs with 6 known Criticals: built-in
/code-review highfound all 3 security Criticals and 1 of 2 architecture ones, plus 2 serious issues the pipeline missed, at ~0.1-1.7 M per run. - It missed one privacy Critical (third-party map tiles without consent) and one policy bypass;
references/sensitive-checklist.mdcovers those two.
Other decisions:
- No verifier agents, no backlog file, no start question, no dimension selection. Triage is the orchestrator's job.
- Marker only when pre-checks are clean, every dispatched review completed, no Critical/Important is open and tests are green.
orch_marker_writekeeps its argument semantics:selected= reviews run,incomplete= failed reviews plus open findings. - A
DIFF_CLASS=prosediff runs the deterministic checks only (references/prose-gate.md). - Platform:
detect-framework.shemitsPLATFORM=web|native|cross;/screensuses it.check-i18n-keys.shhandles.lprojandvalues-*/strings.xml.
Commands
. audit/bin/lib-orchestrator.sh functions: orch_resolve_audit_root, orch_helper, the two
cwd-hash families orch_hash_passed/orch_hash_progress, orch_progress_claim/touch/release,
orch_state_save/orch_state_load/orch_state_clear, orch_tree_hash,
orch_marker_write/orch_marker_matches/orch_marker_delta, orch_url_host/orch_host_public,
orch_run_log, orch_ship_value, orch_test_command_declared, orch_test_command,
orch_unaudited_record/orch_unaudited_base/orch_unaudited_clear, orch_sensitive_paths,
orch_review_worktree_create/orch_review_worktree_remove, orch_usage_start/orch_usage_report.
orch_progress_claim clears state so a run starts empty.
| Command | Purpose | |
bash audit/bin/collect-scope.sh | BASE_REF plus the ---FILES---, ---FRONTEND---, ---TRANSLATIONS---, ---DIFF--- sections | |
bash audit/bin/pre-checks.sh | Secret scan, lockfile drift, binary artifacts | |
bash audit/bin/check-i18n-keys.sh [root] | Deterministic i18n key-set diff across locales | |
bash audit/bin/check-outdated.sh [root] [--security-only] | Dependency vulnerabilities (push-blocking) and outdated majors (Minor) | |
bash audit/bin/check-ci-hardening.sh [root] | Tag-pinned uses: and missing permissions: in .github/workflows/*.yml | |
bash audit/bin/check-silencing.sh [root] | New suppression comments, disabled tests, empty catches, removed assertions, lowered thresholds; run in Phase 1 and again after the fix round | |
bash audit/bin/check-token-contrast.sh [root] [--tokens FILE] [--all] | WCAG contrast check for SwiftUI design tokens | |
bash audit/bin/check-docs-claims.sh [root] | CLAUDE.md/README.md/*/SKILL.md claims verified against disk | |
bash audit/bin/check-fresh-shell.sh [root] | Bash blocks calling orch_* without sourcing the lib, or reading an unset state variable (FRESH_SHELL_RESULT=OK|HITS (N)|SKIP); scans */SKILL.md and */references/*.md | |
bash audit/bin/classify-diff.sh [--paths] | DIFF_CLASS=prose|code | |
bash audit/bin/run-cost.sh <projects-dir> <session-id> [--since <epoch>] [--json] | --latest <projects-dir> | --window <projects-root> <since-epoch> | Sums agents/turns/tokens of a session plus subagents/*.jsonl against a fixed price table (checked 2026-10-03 against /usage). orch_usage_report combines it with the week since the reset in ~/.claude/usage-limits.conf (defaults Thu 12:00 Europe/Berlin, 2600 USD); 1 % of the week is about 26 USD API value, the percentage is a local estimate, /usage is exact | |
bash audit/bin/test-lock.test.sh | Pins test-lock.sh (direct full runs such as composer test are cached like --cached, filtered ones are not, --cmd, -destination keying, test-isolation: process skips the repo lock, linked-worktree lock dir, test-isolation: worktree key, waiter notice, suite/xcode class selection, --cached hit/miss, reentrant cache under TESTRUN_CACHE_CMD, pre-run tree hash) | |
bash audit/bin/lib-testrun.test.sh | Pins lib-testrun.sh: admission (caps, global budget, stagger, FIFO, pressure rule, dead holders and orphan groups), nesting, event log, TESTRUN_DISABLE, watchdog (one restart, TEST_STALLED_TWICE, CPU and simulator-CPU progress, 1 s exit tick), process-tree kill, orphan reaping, cache rules (identity, expiry, flaky, ignore/prose opt-in), DB name allowlist and cleanup, worker budget (8 alone, 4 with two heavy runs, 3 with three, min 2; exported as TESTRUN_WORKERS/TESTRUN_BROWSER_WORKERS at admission), nice 10 for suite runs (TESTRUN_NICE; not for xcode, TESTRUN_NICE_XCODE), tr_is_full_run (composer test is a full run by definition; exclude-group, grep, shard, changed are partial), tr_db_drop_name, tr_kill_orphan (pid plus descendants; the group only when the orphan leads it, never a group it merely belongs to). Fake processes and a temp state dir only. Timing-sensitive cases print SKIP when the load stays above 4 x cores for 120 s; the summary line counts them | |
bash audit/bin/worktree-setup.sh <worktree> <main-checkout> | Makes a fresh worktree testable, idempotent, per app dir (root plus nested manifests, mobile projects skipped): .env copied, vendor/node_modules APFS-cloned (cp -c -R) when the lockfile matches main (then composer dump-autoload), else composer install/npm ci/bun install; public/build cloned when lockfile, resources/ and the vite configs match and the build is newer than the sources, else npm run build. A pure Swift repo is a no-op. One line on stdout, worktree-setup: FAILED <step> and exit 1 on failure. Called by /worktree new and the Feierabend daemon. A symlinked vendor breaks Pest ("facade root not set"), never use one | |
bash audit/bin/worktree-setup.test.sh | Pins worktree-setup.sh with fake composer/npm/bun: clone vs install per lockfile, .env never overwritten, build clone vs build, idempotence, nested dir, bun, Swift/mobile no-op, composer app with capacitor, failure line | |
bash audit/bin/worktree-cleanup.sh <worktree> | Ends a worktree: refuses (exit 1, one line) for the main checkout, uncommitted changes or commits no remote has; kills the process groups of live run tickets with that cwd and parent-1 orphans in it (never by name), drops the registered test DBs, removes worktree and branch | |
bash audit/bin/worktree-cleanup.test.sh | Pins the refusals, the group kill, the registry-only DB drop, the removal of worktree and branch | |
bash audit/bin/audit-skip-tests.test.sh | Pins the test block of SKILL.md Phase 4: the AUDIT_SKIP_TESTS=1 guard (the Feierabend daemon runs the suite itself) and the affected-tests.sh dispatch (run, none, full) | |
bash audit/bin/affected-tests.test.sh | Pins affected-tests.sh (diff to affected test files per runner: bun, vitest, Pest/artisan, PHPUnit per file; fallback to the full suite on config, lockfile, test-helper or migration changes, unsupported runners, more than 25 files) | |
bash audit/bin/lib-testrun-zsh.test.sh | Pins that the lib's list loops (DB cleanup, kill tree, cache-ignore globs) split the same when sourced from zsh | |
bash audit/bin/test-status.test.sh | Pins test-status.sh (listing, dead-wrapper group and playwright orphan reaped inside the scope, symlink invocation, default scope) | |
bash audit/bin/oracle-lock.sh snapshot|check|clear --run <id> [files...] | Content-hash lock for /delegate's oracle tests plus shared test setup; state under --git-common-dir; check prints ORACLE_CHANGED=<file> and ORACLE_RESULT=OK|CHANGED|NONE | |
bash audit/bin/oracle-lock.test.sh | Pins oracle-lock.sh (unchanged OK, sed edit, deletion, shared setup edit, unknown run NONE, run ids isolated, clear) | |
bash audit/bin/mutate.sh <root> <base-ref> [--oracle-files "<f>..."] | Targeted mutation run for /delegate Phase 5: changed files matching the project's .claude/mutation-targets, Pest (--mutate --covered-only; --class=<FQCN>, --path=<file> for an enum, since --class matches only classes and traits) or Infection, one total budget MUTATE_BUDGET (600 s) inside test-lock.sh (common-dir lock key and DB_DATABASE=<base>_mut), survivors on changed lines +-3, max 15. Target line `<glob> :: TestA | TestBpins the test classes (indirectly tested classes); Infection runs only the selected tests via--test-framework-options=--filter. Emits MUTATE_RESULT=OK|SKIP|TIMEOUT|ERROR; SKIP all-mutants-skipped when every Infection mutant exceeded the per-mutant timeout (MUTATE_INFECTION_TIMEOUT, default 120 s, plus MUTATE_NOTE=skipped-mutants:<file>:<n>); ERROR reasons runner-failedandinitial-tests-failed(Infection refuses a red suite,MUTATE_ERRORnames the failing test file); SKIPs withouttimeout/gtimeout, coverage driver or runner. Infection is a manual one-time install: curl -L -o ~/.local/share/claude/infection.phar https://github.com/infection/infection/releases/latest/download/infection.phar` (verified 2026-10-08 on zeit; INFECTION_PHAR overrides the path) |
bash audit/bin/mutate.sh <root> <base-ref> [--oracle-files "<f>..."] --files "<f>..." | Pin mode for /delegate: measures exactly those files regardless of the diff, also without a .claude/mutation-targets file; entries may be ./relative or absolute. Non-target files get MUTATE_NOTE=not-a-target:<file> only when they produced a result. Survivors on every line (cap 15 still applies) | |
bash audit/bin/mutate.test.sh | Pins mutate.sh (target intersection, SKIP reasons, FQCN, enum --path selection, PAO_DISABLE, Pest (plain and laravel/pao json) and Infection parsers against the real logs in audit/bin/fixtures/mutate/, +-3 filter and cap 15, no-timeout SKIP, stub-runner full flow, --files cases: unchanged target, non-target note, ./ and absolute paths, missing targets file, no note on SKIP) | |
bash audit/bin/test-gate.test.sh | Pins test-gate.sh (admission through the lib: two suites at once, a third waits, handover, dead holder, PID reuse, non-owner release, timeout; run green, flake rerun, repeated flake within 14 days, no rerun on count mismatch, Feature failure or more than 5 files). Fixtures come from a real parallel Pest run | |
bash audit/bin/orch-review-worktree.test.sh | Pins the review worktree: committed, uncommitted and untracked scope files appear as an uncommitted diff at BASE_REF, the user's tree is untouched, remove leaves no entry | |
bash audit/bin/orch-sensitive-paths.test.sh | Pins orch_sensitive_paths (one hit per surface class; tests, style, prose files and author ignored) | |
bash audit/bin/orch-zsh-source.test.sh | Pins that the lib resolves its own directory when sourced from zsh | |
bash audit/bin/orch-tree-hash.test.sh | Pins tree-hash.sh (via orch_tree_hash): untracked non-ignored files count, ignored ones do not, the real index stays untouched, the hash equals HEAD's tree after git add -A and commit | |
bash audit/bin/unaudited-base.test.sh | Pins the quick-fix collection (orch_unaudited_*) | |
bash audit/bin/check-silencing.test.sh | Pins check-silencing.sh (planted assertions-removed, test-disabled, error-swallowed and suppression hits; prose by extension (md, mdx, markdown, txt, rst, adoc, any case) stays silent, a test file under docs/ still hits; threshold in CONSTRAINTS.md still hits) | |
bash audit/bin/classify-diff.test.sh | Pins the prose/code classification of path lists | |
bash audit/hooks/block-unsafe-push.test.sh | Pins the push guard: a push without a fresh marker asks on every branch, with a fresh marker it passes, and a marker over a then-untracked file still matches (same tree-hash.sh as the marker) |
Every test is a single script; there is no wrapper that runs all of them.
Audit Context (auditing this repo itself)
- Markdown + Bash skills repo, no runtime, no dependencies. Findings about missing package manifests, test frameworks, or CI configs for the skills themselves are noise.
- Public repo on GitHub. Secrets/keys/tokens anywhere in the diff are always Critical. There are no per-run audit logs;
suppressions.jsonunder.claude/audits/may be committed, so its entries never contain secrets or file content. audit/bin/*.shand every hook must stay bash 3.2 compatible (macOS default): nodeclare -A, noreadarray, no${var,,}.- German-named contract identifiers (
ALLE_DATEIEN, ...) are deliberate cross-file contracts, NOT English-migration violations. - Deliberate decision: orchestrator writes, subagents return (subagents cannot write under
.claude/);exit 2blocking in the audit Stop hook is intentional,additionalContextwould not block.
Gotchas
- Every Bash block in a SKILL.md is a fresh shell; nothing sourced or assigned survives into the next block. Every block that calls an
orch_function starts with the one-line source loop from the lib header, and every value a later block needs is saved withorch_state_saveand re-read withorch_state_load. Enforced bycheck-fresh-shell.sh. - Marker hash families.
/tmp/claude-audit-passed-*hashes the cwd WITHOUT trailing newline,/tmp/claude-audit-in-progress-*WITH newline (pre-compact.shrecomputes the latter). Never mix them (rootCLAUDE.md). - Push guard: every push needs a fresh marker.
hooks/block-unsafe-push.shasks for anygit pushwithout a marker younger than 30 minutes, whatever the branch name; pinned byhooks/block-unsafe-push.test.sh. - Pre-push marker and
git pushmust be separate Bash calls. The PreToolUse hook scans the command string forgit pushand blocks before a marker write in the same call would execute. - Review worktree helpers by name only.
hooks/block-worktree-wide-git.shdenies the forced worktree-remove git command whenever it appears in a Bash call (it also blocks a heredoc that merely contains it); useorch_review_worktree_create/orch_review_worktree_remove. - The prose gate is the audit's stopping rule. Fixing what an audit finds in prose creates the next diff that deserves an audit, a loop with no exit (2026-08-05).
classify-diff.shemitsDIFF_CLASS; aprosediff runs the deterministic checks only.references/prose-gate.md. - The finding-line format of the chat report is a contract.
- [Severity][source] file:line: descriptionon ONE physical line (SKILL.md Phase 5, "Report format"); humans grep it. - "Which files are frontend?" has one definition,
FRONTEND_EXT_REinlib-git-base.sh.collect-scope.shreads it with an inline literal fallback so a missing lib does not collapse to "nothing is frontend". SOURCE_DIRSfromdetect-framework.shis quoted per element, not as a whole string. Each directory is individually%q-quoted, joined by plain spaces. Capture stdout as text, extract the value afterSOURCE_DIRS=, rebuild the array witheval "SOURCE_DIRS_ARR=($SOURCE_DIRS)"; never one blanketeval "$(...)"over the three lines. The safety against attacker-controlled directory names comes entirely from the per-elementprintf %q. A directory name with a literal newline cannot round-trip.TEST_COMMANDis a repo-supplied command string (.claude/ship.mdtest-command:, else the manifest's own). Every test run, also a hand-assembledxcodebuild test, goes throughtest-lock.sh; two concurrent runs on one simulator kill each other ("Early unexpected exit, operation never finished bootstrapping"). Full-suite runs use--cached(cache, admission, stall watchdog;lib-testrun.shheader documents state, env and layers).test-statusshows what runs; the xcodebuild shim (skills-personal/bin/shims/xcodebuild) admitsxcoderuns (2 at once,-jobs6/3).mutate.shreportsSKIP no-mutationsin a worktree whosevendor/is a symlink to the main project. Pest then resolves the class to the main project's file and printsNo mutations created; nothing was tested. Run the mutation step from the main checkout, or give the worktree its ownvendor/. A runner that dies without a summary (e.g. a Browser test needing Playwright) isERROR, neverOK;Browser/test directories are excluded from discovery. Both routes (--classfor classes,--pathfor an enum) need the worktree's ownvendor/.laravel/paorewrites Pest's output as ONE json line inside an agent session (AI_AGENT,CLAUDECODE), so the score parser read the second word ofMutating application files...(MUTATE_SCORE=<file>:application, 2026-10-09).mutate.shsetsPAO_DISABLE=1on the Pest call andparse_pestalso unwraps the jsonrawarray; pinned bypest-mutate-service-pao.log.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

