flow-hygiene
Audit instruction corpus health — CLAUDE.md, rules, and memory for staleness, misplacement, duplication, and contradictions.
Best use case
flow-hygiene is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Audit instruction corpus health — CLAUDE.md, rules, and memory for staleness, misplacement, duplication, and contradictions.
Teams using flow-hygiene should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/flow-hygiene/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How flow-hygiene Compares
| Feature / Agent | flow-hygiene | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Audit instruction corpus health — CLAUDE.md, rules, and memory for staleness, misplacement, duplication, and contradictions.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# FLOW Hygiene
Audit the health of the project's instruction corpus. Reads CLAUDE.md,
`.claude/rules/*.md`, and auto-memory files, then checks for six types
of drift: stale references, orphaned content, unenforced claims,
misplaced content, duplicated constraints, and contradictions. Read-only
— reports findings but does not fix anything.
Complements `/flow:flow-doc-sync`, which compares code behavior against
documentation. This skill compares instruction surfaces against each
other and against the codebase structure they reference.
## Usage
```text
/flow:flow-hygiene
```
## Announce
At the very start, output the following banner in your response (not via Bash) inside a fenced code block:
````markdown
```text
──────────────────────────────────────────────────
FLOW v2.6.0 — flow:flow-hygiene — STARTING
──────────────────────────────────────────────────
```
````
## Finding Taxonomy
Eight finding types, each with a severity tag:
| Tag | Severity | Meaning |
|-----|----------|---------|
| `[STALE]` | High | A file path, function name, test name, or command referenced in an instruction surface no longer exists in the codebase |
| `[ORPHANED]` | Medium | A rule file or CLAUDE.md section describes a feature, hook, or pattern that no longer exists — the content itself is orphaned, not just a single reference |
| `[UNENFORCED]` | Medium | An instruction claims enforcement ("CI enforces via X", "hook blocks Y") but the named enforcer does not exist or does not check the claimed condition |
| `[MISPLACED]` | Low | Content is stored in the wrong persistence layer per the routing decision tree — e.g., an imperative constraint in CLAUDE.md instead of a rule, or a project fact in memory instead of CLAUDE.md |
| `[DUPLICATE]` | Low | The same constraint or fact appears in multiple surfaces with identical or near-identical wording — creates update burden when the constraint changes |
| `[CONTRADICTION]` | High | Two surfaces prescribe opposite behavior for the same situation — one says "always do X", another says "never do X" |
| `[CLAUDE_MD_MANDATE]` | High | A project-local rule file mandates that descriptive content be documented in CLAUDE.md — the mandate is itself the misclassification per `.claude/rules/persistence-routing.md` "Cross-Surface Application". Fix routes the mandated prose to a feature-specific `.claude/rules/<feature>.md` file plus a one-line CLAUDE.md index entry. |
| `[SIZE_BUDGET]` | Medium | CLAUDE.md exceeds the configurable size budget (`claude_md_budget` in `.flow.json`, defaults 12000 chars / 400 lines). Descriptive prose should land in feature-specific rule files, not in CLAUDE.md itself, so the budget overrun signals that recent additions failed the obey-vs-describe gate. |
## Steps
### Step 1 — Discover surfaces
Instruction surfaces are scattered across multiple files and formats.
Before any analysis can happen, the skill needs a complete inventory of
what exists and what each surface claims.
Identify and read all instruction surfaces in the project.
Use the Glob tool to find:
- `CLAUDE.md` in the current working directory
- `.claude/rules/*.md` in the current working directory
Read each discovered file using the Read tool. For each file, note:
- File path
- All file paths, function names, test names, and commands mentioned in backticks
- All enforcement claims ("CI enforces", "hook blocks", "test validates")
- All behavioral constraints (imperatives: "never", "always", "must", "do not")
- All architectural facts (descriptions of how things work)
For auto-memory: read the memory index (`MEMORY.md`) from conversation
context if it is loaded. If individual memory files are referenced in the
index, read them using the Read tool. Memory files live at
`~/.claude/projects/*/memory/` and are user-scoped — they may not exist
for every project.
**CLAUDE.md size budget check.** A CLAUDE.md that grows unchecked
signals that descriptive content is being added where only behavioral
content belongs, per `.claude/rules/persistence-routing.md` "Cross-
Surface Application". Read `.flow.json` from the project root using
the Read tool. If the file exists and contains a `claude_md_budget`
object, parse its `chars` and `lines` fields. If the file is missing
or the field is absent, use the defaults: 12000 chars and 400 lines.
Fail safe to the defaults whenever the input is unreliable: if
`.flow.json` is present but is not valid JSON, or `claude_md_budget`
is present but is not an object, or `chars`/`lines` is present but
is not a positive integer, use the defaults rather than prompting
or erroring.
Measure CLAUDE.md by reading the file with the Read tool — character
count is the byte length of the content, line count is the count of
newlines plus one for the final line. Emit a `[SIZE_BUDGET]` finding
when either count exceeds its budget. The finding's body cites the
measured value, the budget, the override path (`.flow.json` field
`claude_md_budget`), and the recommended fix (route descriptive prose
to feature-specific `.claude/rules/<feature>.md` files plus one-line
CLAUDE.md index entries).
### Step 2 — Structural verification
Instruction surfaces routinely drift from the codebase they describe as
files are renamed, functions deleted, and commands refactored. A
mechanical reference check is the only way to detect this without
reading every file manually.
Verify that references in instruction surfaces point to things that
exist. This is a mechanical pass — each check is a Grep or Glob call.
**File path references.** For each file path mentioned in backticks in
any surface, use the Glob tool to verify the file exists in the current
working directory. Tag missing files as `[STALE]`.
**Function and test name references.** For each function name or test
name mentioned in backticks, use the Grep tool to verify it exists as a
definition in the codebase. Tag missing definitions as `[STALE]`.
**Command references.** For each `bin/flow` subcommand mentioned (e.g.,
`bin/flow check-phase`, `bin/flow tombstone-audit`), use the Grep tool
to verify the subcommand is registered in the dispatcher or source. Tag
missing commands as `[STALE]`.
**Enforcement claims.** For each claim that names a specific enforcer:
- "CI enforces via `test_name`" — Grep for the test function definition
- "hook blocks" or "hook validates" — Grep for the hook name in `hooks/hooks.json`
- "`tests/file.rs` enforces" — verify the test file exists
If the named enforcer does not exist, tag as `[UNENFORCED]`. If the
enforcer exists but does not check the claimed condition (requires
reading the test or hook body), tag as `[UNENFORCED]` with a note
explaining the gap.
**Orphan detection.** After all reference checks, identify rule files
or CLAUDE.md sections where the majority of references are stale. If a
rule file's primary subject (the feature, hook, or pattern it describes)
no longer exists, tag the entire file as `[ORPHANED]`.
### Step 3 — Classification audit
Content placed in the wrong persistence layer creates maintenance burden
— a constraint in CLAUDE.md instead of a rule file must be updated in
two places when it changes, and a memory entry that duplicates a rule
silently diverges over time.
Apply the persistence routing decision tree to each content block.
The decision tree (from `.claude/rules/persistence-routing.md`):
1. Is it specific to this user? → Memory
2. Is it a behavioral constraint? (imperative guardrail) → Rule
3. Is it project knowledge? → CLAUDE.md
4. Can you derive it by reading code? → Do not store anywhere
**CLAUDE.md audit.** Read each section of CLAUDE.md. For each content
block, apply the imperative test: "Can you phrase this as an imperative
('do X', 'never Y', 'when X do Y')?" If yes, it belongs in a rule
file, not CLAUDE.md. Tag as `[MISPLACED]` with a recommendation to
move it to `.claude/rules/<topic>.md`.
Exclude sections that are genuinely project knowledge even if they
contain imperative-sounding language (e.g., "Phase gates prevent
skipping ahead" is a description, not an instruction).
**Memory audit.** For each memory file, check whether its content
duplicates an existing rule or CLAUDE.md section. If the same
constraint appears in both memory and a rule file, the memory entry is
redundant. Tag as `[MISPLACED]` with a recommendation to remove the
memory entry (rules are the authoritative source).
Also check whether memory files contain architecture facts, code
patterns, or file paths — these should be derivable from the code
and do not belong in memory. Tag as `[MISPLACED]`.
**CLAUDE.md mandate scan.** Project-local rules that mandate
CLAUDE.md prose for descriptive content invert the persistence
routing — the mandate is itself the misclassification per
`.claude/rules/persistence-routing.md` "Cross-Surface Application".
Use the Grep tool against `.claude/rules/*.md` (and any project-
local rule subdirectories) for the four canonical paraphrased
substrings the upstream rule catalogs. These four entries are
*pattern shapes*, not literal grep strings — match them by
judgment against the prose a rule file actually uses. In the
first entry, `X` and `Y` are placeholders standing in for a
project-specific noun (the descriptive surface) and a project-
specific documentation requirement; a real rule file will use
concrete nouns in those slots. Read each candidate rule file and
decide whether its prose expresses one of these shapes:
- `treats X added without Y documented in CLAUDE.md` — the
enforcement-claim shape where a project-local rule asserts CI
fails when a descriptive surface is added without a CLAUDE.md
paragraph
- `must be documented in CLAUDE.md` — the direct-mandate shape
- `documentation home is CLAUDE.md` — the routing-destination shape
for descriptive content
- `CLAUDE.md as the canonical destination` — the
authoritative-source shape
For each match, emit a `[CLAUDE_MD_MANDATE]` finding citing the
rule file path, the matched line, and the recommended fix:
"Rewrite this rule to route descriptive content to a feature-
specific `.claude/rules/<feature>.md` plus a one-line CLAUDE.md
index entry per `.claude/rules/persistence-routing.md` Cross-
Surface Application."
Exclude matches inside quoted-example fences (Markdown code blocks)
or in paragraphs whose surrounding prose explicitly names the
pattern as an anti-pattern — those occurrences are documentation of
the pattern, not enforcement of it.
### Step 4 — Cross-reference audit
When the same constraint lives in multiple surfaces, a change to one
copy leaves the others stale. When two surfaces prescribe opposite
behavior, the model follows whichever it reads last — producing
unpredictable results.
Compare all surfaces pairwise for duplicates and contradictions.
**Duplicate detection.** For each behavioral constraint found in
Step 1, search all other surfaces for the same constraint expressed
in similar words. Exact duplicates and near-duplicates (same meaning,
different wording) both count. Tag as `[DUPLICATE]` with the two
source locations.
Focus on constraints that would need to be updated in multiple places
if the rule changed — identical constraints in CLAUDE.md and a rule
file, or the same rule stated in two different rule files.
**Contradiction detection.** For each pair of constraints, check
whether they prescribe opposite behavior. Common patterns:
- "Always do X" in one surface vs "Never do X" in another
- "Use A for this" vs "Use B for this" where A and B are mutually exclusive
- Conflicting scope — one surface says a rule applies to all phases, another limits it to specific phases
Tag as `[CONTRADICTION]` with both source locations and the specific
conflict.
### Step 5 — Report
The audit is only useful if its findings are actionable. Grouping by
source file lets the user address all issues in one file at a time,
and severity tags help prioritize what to fix first.
Produce the findings report inline in the response.
**Summary line.** Start with a one-line summary:
> **Hygiene: N findings (X stale, Y orphaned, Z unenforced, W misplaced, V duplicate, U contradiction, M claude-md-mandate, B size-budget)**
If no findings, output:
> **Hygiene: Clean — no instruction corpus drift detected.**
**Findings by source file.** Group findings by the source file where
the problematic content lives. For each file with findings, show the
file path as a heading, then each finding:
```text
## <source_file_path>
**[STALE]** <description>
- References: <what it references>
- Status: <not found / renamed to X / removed>
**[UNENFORCED]** <description>
- Claims: <what it claims is enforced>
- Enforcer: <named test/hook>
- Status: <enforcer not found / enforcer does not check this>
**[MISPLACED]** <description>
- Content: <summary of the content>
- Current location: <where it is>
- Recommended location: <where it should be>
**[DUPLICATE]** <description>
- Location 1: <file:line>
- Location 2: <file:line>
**[CONTRADICTION]** <description>
- Surface 1: <file> says <X>
- Surface 2: <file> says <Y>
```
**Orphaned files.** List `[ORPHANED]` findings separately at the end
under an "## Orphaned" heading.
After the report, output the following banner in your response (not via Bash) inside a fenced code block:
````markdown
```text
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ FLOW v2.6.0 — flow:flow-hygiene — COMPLETE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
````
## Hard Rules
- Read-only — never fix, edit, or commit anything
- No state file mutations — this is a stateless utility skill
- No AskUserQuestion — produce the report and finish
- No sub-agents — all comparison is inline
- Never use Bash to print banners — output them as text in your response
- Never use Bash for file reads — use Glob, Read, and Grep tools
- Focus on structural accuracy and classification correctness, not styleRelated Skills
flow-triage-issue
Triage a single open GitHub issue from a PM lens. Applies a 'Triage In-Progress' label during triage; reads code, checks for already-shipped work, returns a verdict in {close, decompose} with confidence and a flip-condition. Renders and stops — no other side effects.
flow-start
Phase 1: Start — begin a new feature. Creates a worktree, upgrades dependencies, opens a PR, creates .flow-states/<branch>/state.json, and configures the workspace. Usage: /flow:flow-start <feature name words>
flow-skills
Display the FLOW skill catalog grouped by user role. Maintainer and Private buckets render only when invoked inside the FLOW plugin repo.
flow-review
Phase 3: Review — six tenants assessed by four cognitively isolated agents (reviewer, pre-mortem, adversarial, documentation) launched in parallel. Parent session gathers context, triages findings, and fixes.
flow-reset
Wipe `.flow-states/` on this machine in one pass. PRs, worktrees, and branches are NOT touched — those require per-flow `/flow:flow-abort`.
flow-prime
One-time project setup — configure and commit workspace permissions, install bin/* stubs, and write the version marker. Run once after installing or upgrading FLOW. Usage: /flow:flow-prime
flow-plan
Decompose a problem statement into a pre-planned decomposed issue. Accepts either an issue reference (#N, re-plans in place) or a bare prompt (synthesizes What/Why/AC and files a new issue). Runs a Tech-Lead-default planning conversation, dispatches to PM/Tech Lead/CTO sub-agents on explicit user request, then files or edits the issue ready for /flow:flow-start. Usage: /flow:flow-plan #N or /flow:flow-plan <topic>
flow-orchestrate
Process decomposed issues sequentially overnight via flow-start, tracking outcomes and generating a morning report.
flow-note
Capture a correction or learning to the FLOW state file. Invoke explicitly with /flow:flow-note. Fast — captures and continues without interrupting flow.
flow-learn
Phase 4: Learn — audit rule compliance and identify process gaps. Routes findings to CLAUDE.md, .claude/rules/, and plugin issues.
flow-issues
Group open issues by label into four sections (Blocked, Other, Vanilla, Decomposed) with mechanical sort and a copy-pasteable command per row.
flow-explore
Open a problem-statement conversation. Stays in discussion mode with PM as default voice; on user signal, files a vanilla What/Why/Acceptance Criteria issue against the current repo. Usage: /flow:flow-explore <topic>