Process only accumulates. Every hook, rule, and skill was added for a reason, but reasons expire — branches merge, incidents stop recurring, tools change. This audit is the scheduled subtraction pass: evidence decides which gates are safety rails and which have become ritual. (The first audit, 2026-07-13, found a build skill still pointing at a foundation branch that had merged and been deleted, and a double-gated task start.)
Repo-tracked: everything git ls-files .claude returns (hooks, rules, skills, settings.json), CONTRIBUTING.md conventions, and the .github/workflows/ CI gates.
Repo-local (untracked, this machine): .claude/settings.local.json — SessionStart hooks, permission grants.
Machine-global: ~/.claude/CLAUDE.md mandates, ~/.claude/skills/, installed plugins with their session-start injections, and ~/.claude/settings.json — whose enabledPlugins decides which skills exist at all, so it belongs in this layer's inventory rather than being treated as inert config. It is symlinked into tool-settings as of 2026-07-26, so it is version-controlled and in-pass like the rest of layer 3; note the launchd job commits it, not your session.
The memory system: ~/.claude/projects/<project>/memory/ — MEMORY.md, which is always-loaded, plus the memory files it points at, which are lazily recalled. In scope, and this audit now owns both halves of it (scope settled 2026-07-26; see audits/2026-07-26-memory-system.md). Cost is the axis this audit always had — MEMORY.md sits in the same per-session token budget as the rules cascade, and being a different mechanism (recall via <system-reminder>, frontmatter types) is no reason to leave a quarter of that budget uncounted. The content half — per-file merge/retire/stale-date judgment — was originally delegated to the anthropic-skills:consolidate-memory skill and is absorbed below, because that skill's plugin was retired (see the note after the content pass).
The content pass. Run it whenever the cost pass finds regrowth, and at least at each periodic backstop:
[[wikilinks]] and the index pointer stay valid; leave a one-line pointer behind only if something still links the retired name.git log, gh issue list, or one query would answer) and keep what is not: stated preferences, the reasoning behind a decision, who owns what, hard-won traps.- [Title](file.md) — hook. Remove pointers to retired files, shorten any line carrying detail that belongs in the file it points at, and add anything newly important. The index is a table of contents, never storage — a fact that exists only in a hook is always-loaded content masquerading as a pointer, and moving it into the file it points at costs nothing at recall time.Why this is resident rather than delegated (2026-07-26). The content pass above was anthropic-skills:consolidate-memory, which shipped in the bundled anthropic-skills@inline plugin at a measured 4,308 chars ≈ 1,077 est. tok of always-on skill listing for nine skills. Transcript evidence: the other eight (xlsx, docx, pptx, pdf, morning, schedule, setup-cowork, skill-creator) had 0 invocations ever, and consolidate-memory — 112 chars of that 4,308 — had 3, all during the audit that measured it. Paying ~1,077 tok every session for one skill used three times is the same defect this audit found inside MEMORY.md: expensive always-resident space holding what belongs elsewhere. So the method was absorbed here (where it is lazily loaded and adapted to this setup) and the bundle disabled. This is a deliberate fork: Anthropic will keep refining the original and those refinements will no longer arrive. Re-check at each backstop whether the trade still holds; claude plugin enable anthropic-skills@inline restores the original in one command, and the upstream skill is the reference if you want to diff the method against it.
Why both halves must run together, concretely: on 2026-07-26 MEMORY.md was 19,048 chars — under this audit's ~40,000-char ceiling and under the ~25 KB index budget, so neither gate fired, while 92% of its lines were over the ~150-char line and 3 memories' key detail existed only in the always-loaded index. Two gates each individually under threshold, with the defect sitting in the gap between them. That gap is precisely why the two halves are now one skill — when they were two, nothing owned the interaction. Check the interaction, not just each threshold.
The docs/ tier: every spec, system design, runbook, and onboarding guide under docs/. Lazily read, so traffic is the cost multiplier, not file size — rank by inbound reference count (grep each docs/<file> path across *.md, *.py, *.ts, *.tsx, *.yml, excluding self-refs) before ranking by chars, or the audit goes at the biggest file instead of the most-read one. Two checks this layer needs that the others don't: fact-check every milestone/version claim against the live tracker (a doc asserting an issue is on milestone X is a claim, and workflow.md rule 5 requires verifying it — on 2026-07-26 six of seven such claims in the most-referenced spec were wrong, citing a milestone that did not exist), and prefer state-plus-blocker over phase-as-permission: a doc may say shipped, not shipped and blocked on X, or permanent non-goal, but never "not yet, because it's v-whatever" — rule 13 forbids reading a milestone as a defer signal, and buckets cannot be verified where blockers can. Sort each doc into load-bearing (referenced; keep short and correct), on-demand reference (length is fine, spot-check accuracy against the code), or historical (delete it and drop it from the index — docs/ shows only what is present and current; a retired doc left in place still turns up in greps and gets acted on, and git history plus whatever superseded it preserve anything worth keeping — repoint or remove inbound references in the same change so check_doc_references.py stays green). Verdicts apply in-pass; splitting permanent non-goals from not-yet sequencing in a scope doc is the one judgment to propose rather than apply, since a wrong call silently deletes a product boundary. Diff base: audits/2026-07-26-docs-layer.md.
Verdicts for layers 1–2 and 5 are applied in the same pass (.claude/rules/workflow.md rule 10 — safe, reversible, not app code).
Layer 3 is proposal-only unless the file is version-controlled somewhere private — re-test this each audit rather than inheriting it. The original restriction had two reasons: the content describes one contributor's machine, and this repo is public. Both lapsed on 2026-07-26 when ~/.claude/CLAUDE.md became a symlink into ~/Code/tool-settings, a private repo (euglopi/tool-settings) that is not this one — so its edits are as reviewable and revertable as any layer-1 edit, and layer-3 verdicts on it are now applied in-pass and pushed (commit and push that file the same turn; the Edit tool refuses to write through the symlink, so target the real path). For a layer-3 file that is still unversioned, the old rule stands: exact copy-paste proposals in the session summary, never repo files. A scope restriction can expire because the world changed, not because the rule was wrong.
Layer 4 is version-controlled, so its verdicts apply in-pass — same test as layer 3, and it passed the same way, on the same day. ~/.claude/projects/*/memory/ are symlinks into ~/Code/tool-settings (private, euglopi/tool-settings), so git revert is the restore path and no hand-rolled backup is needed. Two details to know: the memory folders are committed by a launchd job (bin/commit-memory.sh, every 15 min) rather than by the session that edited them, so check git log rather than assuming your edit is committed, and never point a session's git add -A at claude/projects/ — sessions own claude/CLAUDE.md path-scoped, the job owns the memory folders. Unlike CLAUDE.md, writing through these symlinks works (the symlink is the parent directory, not the file), so edit via either path.
Two limits that hold regardless of version control. (1) Merging or deleting a memory stays proposal-only: memories are the user's, and removing one changes what every future session knows — revertability makes a bad edit cheap to undo, but nobody notices knowledge that silently stopped existing. Retiring a memory whose own text says the work is done and must not be raised again is the one exception; quote it in the record. (2) Never paste memory content into an audit record in this repo — the repo is public and memory files carry personal detail; report counts, verdicts, and your own prose instead. For an unversioned memory directory (a fresh machine, another project), fall back to satisfying the gate's reason directly: cp -Rp memory memory-backup-<date>-audit && diff -rq, name the restore command in the record, then apply content-preserving edits.
Inventory every gate that fires on the chosen task type, in firing order — session start (hooks, injected context), intake, build, verification, PR, CI, deploy.
Cost each gate in three currencies, worst first:
wc -c every body loaded per session (skills, rules, plugin catalogs) and estimate tokens as chars ÷ 4; per-session fixed loads dominate because they recur on every session. Measure characters, not words: markdown markup (**bold**, backticks) is paid for in context but invisible to wc -w, so word counts understate rule files by ~35%. Hard ceiling: a single always-loaded memory file over ~40,000 chars trips Claude Code's own oversized-file warning (getMaxMemoryCharacterCount — max of 40k and 5% of the context window), and is an automatic trim-or-restructure trigger regardless of how its individual gates score. Report each audited file against that line, before and after.Don't estimate a plugin's cost — ask it, where you can. claude plugin details <name> reports the actual always-on token cost of a plugin's skill listing plus a per-component breakdown, and it is the authority over any chars ÷ 4 figure: for superpowers it reports ~715 tok where a chars-based estimate said 616, so chars ÷ 4 runs low on skill-listing text (verified 2026-07-26). It only works for marketplace-installed plugins. @inline plugins — the ones bundled with the Claude Code app, e.g. anthropic-skills, design, cowork-plugin-management — are not "installed", do not appear in claude plugin list, and details rejects them outright ("Plugin … not found"). For those, fall back to measuring the listing yourself: sum each bundled skill's directory name plus its frontmatter description, from the bundle under ~/Library/Application Support/Claude/local-agent-mode-sessions/skills-plugin/<session>/<bundle>/skills/. Treat the result as a floor, per the undercount above.
There are THREE plugin systems on this machine, not one — and enabledPlugins only governs one of them. Establish which system serves a skill before reasoning about its cost or availability (all verified 2026-07-26): (a) CLI marketplace — ~/.claude/plugins/cache/, listed by claude plugin list, pinned per version+SHA (superpowers, ralph-loop); (b) app-bundled inline — ~/Library/Application Support/Claude/local-agent-mode-sessions/<session>/<bundle>/skills/, which is where anthropic-skills (and consolidate-memory) live — disabled since 2026-07-26, see layer 4; (c) the app's own Knowledge Work marketplace (anthropics/knowledge-work-plugins), served fresh per session into …/<session>/<bundle>/rpm/plugin_<id>/skills/ — 16 plugins on this machine, including design v1.2.0. The trap: settings.json showed design@inline: false while all seven design:* skills were loaded, because the loaded ones come from (c) and that flag governs a different registration entirely. Equally, ralph-loop read disabled while its three skills were still listed. So the skill listing is ground truth for what is loaded; enabledPlugins is not — which is the same is-it-actually-loaded lesson as step 3, hitting from the opposite direction. Note also that being on disk ≠ being in context: most of those 16 served plugins are fetched but not listed.
Update models differ by system, and only two of the three are automatic — this matters when a verdict says "rely on that skill". @inline plugins ship inside the app and are refreshed when it updates, so Anthropic's refinements arrive on their own (evidenced by three distinct bundle ids on this machine dated 2026-05-09, 06-23 and 07-26, and by the app self-updating to 2.1.220 on 2026-07-26). Marketplace plugins do not auto-update: they are pinned to a version and git SHA at install time and only move on an explicit claude plugin update <name> (restart required). Check for drift with git -C ~/.claude/plugins/marketplaces/<mp> ls-remote origin HEAD against local HEAD — on 2026-07-26 superpowers was pinned at 6.1.1 from Jul 12 while 6.2.0 was available, and the claude-plugins-official clone had not been fetched since January. So a stale marketplace skill can silently be the thing your verdict points at. The app's Knowledge Work plugins (system c) refresh on their own like the inline bundle — design went 1.1.0 → 1.2.0 within a day — but their refreshes rename things: ux-writing → ux-copy and design-system-management → design-system, with research-synthesis added. So after any app update, a /skill-name reference in a rule or doc can point at a skill that no longer exists under that name; grep for the old names rather than assuming continuity. The skill listing is always-resident and easy to omit entirely from a budget: on 2026-07-26 the audited always-loaded files came to 16,967 est. tok while the true resident total was ~21k, and the single most over-budget item was a bundled plugin's listing — nine skills charging ~950 tok every session for two lifetime invocations. Count the listing, and state whether your denominator includes it.
Score value on evidence only. A gate earns its keep by pointing at something: a named incident it prevented or caught (PR, issue, observation-log entry) or a correctness guarantee it enforces. Ask "what did this catch in the last ~20 sessions?" — silence is a trim signal. But check the gate's age before reading its silence: a gate younger than the evidence window has no record because it hasn't had time to build one, not because it's idle. Date it (git log --diff-filter=A -1 -- <file>) and, if it postdates the window, record it as not yet assessable and re-test next audit — never trim it. Also weigh how a gate is reached: one invoked by name (a /slash-command, or a skill the maintainer invokes) shows usage that no incident log captures, and search_session_transcripts for its name is the cheap check for whether it has ever actually run. (2026-07-26: six of fourteen skills had zero observation-log evidence, and not one was a trim candidate — three had shipped hours earlier that same day, and the loop pair is slash-invoked.) Also verify each gate's facts are still true (branch names, paths, tool claims): a stale instruction is a negative-value gate — it actively costs time. And check every always-loaded section for a skill twin, not just a rule twin — an invocable skill covering the same ground makes the resident copy pure duplication, and it is the easiest overlap to miss because you are comparing a rule file against a different kind of artifact. Grep the skill directories (~/.claude/skills, .claude/skills, installed plugins) for the section's distinctive phrases; where a skill covers it in equal or greater depth, the resident text becomes a one-line pointer. (2026-07-26: 32% of ~/.claude/CLAUDE.md was restating ~/.claude/skills/model-effort/SKILL.md, which carried the same taxonomy plus a pricing ladder the rule file lacked.) Verify each removed directive by literal string match in the skill before cutting it, and keep any prohibition resident regardless.
Similarity between two gates' descriptions is not evidence their bodies overlap. A description is written to be matched against the user's language, so sibling skills in a set are supposed to read alike — inferring duplication from them is inferring internals from a trigger. Before proposing any merge, run the one-command test: name-normalise both bodies and count identical lines (comm -12 over sorted, name-substituted files); a low count kills the hypothesis outright. (2026-07-26: three of four consolidation hypotheses in the skill-layer audit came from reading descriptions, and all three were wrong and would have been destructive — design-review "duplicating" design-audit's rubric is a division-of-labour table over a rubric that exists once, with zero shared rule prose; loop-run/loop-audit share 4 identical lines and already cross-disambiguate in their first body section; and the two "misfiled" global skills were deliberately placed. Only the fourth survived, and its real defect was wrong environmental claims, not size.)
Read a vendored or plugin-sourced gate's environmental claims against this environment. A borrowed skill can be internally coherent, unedited, well under every size ceiling, and still wrong here — because it describes the tool it was written for. Neither the ceiling nor the churn check points at it: a file nobody edits has no churn, and a lazily-loaded body never trips the resident ceiling. So for any gate you did not author, check its claims of fact: does the tool it names exist in this harness, is the path it calls read-only actually read-only, does its workflow contradict a standing rule here. Each wrong claim is a negative-value instruction on the gate's most-used path. (2026-07-26: task-observer, vendored from a Cowork-targeted original, spent ~18,000 tok telling the agent to deliver skills with a present_files tool that does not exist, to treat writable skill files as a read-only mount, and to stage edits for approval that workflow.md rule 10 already grants — plus grep -oP snippets that fail on macOS. Restructured to 5,887 chars with the original preserved as the licence anchor and upstream diff base.)
Check that what your verdict points at is actually loaded — not just that it exists. A verdict that moves content into a skill, or names a skill as the place to go, creates a dependency on that skill being available, and availability is a separate fact from existence: a skill can be present on disk inside a plugin that is disabled, so it never appears in a session's skill list. Confirm it resolves (it appears in the skill listing, or its plugin is enabled — claude plugin details <name>), and if it is deliberately disabled, say so at the point of reference and give the enable-on-demand command rather than assuming a reader can invoke it. This is the sibling of the ceiling-vs-format lesson in layer 4 above: two correct methods can leave a defect in the gap between them. On 2026-07-26 this audit's memory-system pass named consolidate-memory as the content-pass tool at 11:45, hours after a /doctor pass had disabled the bundled plugin that ships it — neither call wrong alone, and the reference was orphaned the moment both landed (fixed in #635). The general form: verify what your change assumes is loaded, not only what it says. Also flag disproportion and churn as consolidation signals: from the step-2 character counts, note any single gate that dominates its host file, and check its recent edit count (git log --oneline --since=… -- <file>). A gate rewritten 3+ times in a short window, or one ballooned relative to its siblings, is usually accreting special cases a single principle would cover — a trim/merge/restructure candidate (rule 10 reached 42% of workflow.md across ~5 edits before #198 consolidated it to the "blast radius + reversibility + verifiability" principle — then regrew to 67%, which is why step 4 prefers restructure on a repeat offender).
Verdict per gate: keep / trim (shorten, make conditional) / merge / restructure (move it, see below) / drop.
Reach for restructure, not trim, when a gate has already been trimmed and grew back. Compression fails when every new directive still has nowhere else to land, so the bloat returns: rule 10 was consolidated to 718 words on 2026-07-13 and measured 4,969 words — 67% of workflow.md, 9.3× the next-largest rule — thirteen days later, a 6.9× regrowth across ~6 merged PRs. Re-trimming buys weeks. Restructuring changes where content lives: keep the principle plus any prohibitions resident in the rule, and move the clause stack, elaborations, and worked examples into a lazily-loaded skill (.claude/skills/<name>/SKILL.md), where only the one-line description stays in context — the pattern applied to workflow.md rules 4 and 12 (→ file-github-issue, resume-research-workflow). Ask of every clause: does this belong in an always-loaded rule (universal and safety-critical), a task-scoped skill, or a memory? A rule that keeps growing is usually the only place its authors had to put things — fix that, or the growth recurs.
Exempt from trimming and restructuring: safety rails — the leak-guard commit hook, .claude/rules/grounded-answers.md invariants, CI correctness and format checks, plus two rails that live inside otherwise-auditable files: workflow.md rule 10's hard line (never fire an unverified irreversible real-world change) and rule 4's never restructure the project's board fields/options prohibition. Never move a prohibition into a lazily-loaded file, where it might not be loaded when it matters. The target is redundant process, never protection.
Record the repo-layer table in audits/YYYY-MM-DD-<task-type>.md beside this skill. Diff against the most recent previous record and lead with deltas: gates added since, kept gates still silent, dropped gates whose absence caused an incident (a re-add signal).
Apply layer-1/2 verdicts in the same pass (one PR) — including meaning-preserving rewrites of a rule or skill file. Don't propose them for approval: the audit record's before/after diff is the verification and git revert undoes it cleanly, so workflow.md rule 10's "can't cheaply verify → propose-first" bar does not gate audit edits. Only the exempt safety rails (step 4) stay off-limits. Ship layer-3 verdicts as copy-paste edits in the summary.
When the audited gate is workflow.md rule 10, it is also this skill's own apply-mandate — rewriting the clause that authorizes the rewrite is allowed, but weakening it by accident is the failure to avoid. Preserve in meaning: the audit-verdict apply grant, the low-risk-PR merge default, the additive/reversible/verified-migration auto-merge carve-out, and the paid-run authorization (which ~/.claude/CLAUDE.md's cheaper-and-faster-frontier rule cross-references by name). After any rule-10 edit, re-read those four and confirm each still says what it said.
No scheduled runner may exist (decided 2026-07-26: every scheduled task and routine was deleted, including this skill's own monthly one; ~/.claude/scheduled-tasks/ is deliberately empty). Don't create one, re-arm one, or propose one — starting a recurring cadence requires maintainer approval.
Running it ad hoc is not gated. This is a rule about clocks, not autonomy: if a session's work makes a pass worthwhile, run it and report after, exactly as with any other safe, reversible, verifiable work. When it's worthwhile: after adding or materially changing a gate, whenever process friction annoys, or when a long stretch has passed with real churn in the process layer.
Never run it blind, even when asked — an audit without fresh evidence (new gates, new incidents) just restates the last table. Check first whether anything actually moved since the most recent audits/ record, across both homes: git log on the repo's .claude/, .github/workflows/ and CONTRIBUTING.md, plus git -C ~/Code/tool-settings log -- claude/CLAUDE.md claude/settings.json claude/projects for layers 3–4. If nothing moved, say so and stop rather than producing a restatement. Always give --since an explicit time — --since="<date> 00:00" — because a bare date silently means "that date at the current time of day" and hides everything committed earlier that day.
Trimming a gate that can name its incident · micro-optimizing seconds of wall-clock while ignoring per-session token loads and user round-trips · verdicts from vibes ("feels heavy") instead of evidence · treating a timeout cap as the cost (a 30s cap ≠ 30s spent) · letting this skill itself bloat — it stays under a page.
.claude/rules/workflow.md rule 10 (safe/reversible autonomy — the apply mandate) · audits/ (previous decision tables, the diff base) · the task-observer observation log (evidence source; local and gitignored, never committed).
alethical-org/alethical
a84ed3e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.