From flow-next
Audits .flow/memory/ entries against the current codebase to decide Keep/Update/Consolidate/Replace/Delete. Useful for keeping memory store fresh and removing stale entries.
How this skill is triggered — by the user, by Claude, or both
Slash command
/flow-next:flow-next-auditThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Memory entries decay. A `.flow/memory/bug/runtime-errors/` entry logged six months ago might reference a renamed file, a deleted function, or a codepath that no longer exists. Without periodic review, the store accumulates zombie entries and `memory-scout` surfaces outdated advice.
Memory entries decay. A .flow/memory/bug/runtime-errors/ entry logged six months ago might reference a renamed file, a deleted function, or a codepath that no longer exists. Without periodic review, the store accumulates zombie entries and memory-scout surfaces outdated advice.
This skill IS the audit. The host agent (Claude Code / Codex / Droid) walks .flow/memory/, reads each entry, uses Read/Grep/Glob/git to verify references against the current codebase, applies engineering judgment, and decides per entry whether to Keep / Update / Consolidate / Replace / Delete. Optional autofix mode applies unambiguous actions and marks ambiguous as stale.
Decision entries (.flow/memory/knowledge/decisions/) and glossary terms (GLOSSARY.md files at the repo root and on the ancestor chain) are walked alongside the rest of memory. Decisions get a calibrated judging question — "does the constraint that motivated this choice still hold?" — and Replace becomes a two-step supersession (write successor, mark old decision_status: superseded, never git rm). Glossary terms are scanned for code usage; zero-hit terms get a <!-- stale: ... --> HTML comment via Edit tool (no flowctl glossary mark-stale exists), _Avoid_ aliases appearing in code surface as alias-creep findings.
There is no Python audit-engine, no codex/copilot subprocess dispatch, no deterministic scorer. The host agent is already an LLM and does the work directly. flowctl provides only thin persistence plumbing (memory mark-stale, memory mark-fresh, memory search --status) — landed by Task 2 of this spec.
Read workflow.md for the full phase-by-phase execution. Read phases.md for the 5-outcomes lookup with memory-schema-specific calibration.
CRITICAL: flowctl is BUNDLED — NOT installed globally. which flowctl will fail (expected). Define once; subsequent blocks (here and in workflow.md) use $FLOWCTL:
FLOWCTL="${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/scripts/flowctl"
[ -x "$FLOWCTL" ] || FLOWCTL=".flow/bin/flowctl"
Inline skill (no context: fork) — AskUserQuestion must stay reachable across phases. Subagents can't call blocking question tools (Claude Code issues #12890, #34592). Phase 3 (Ask) and Phase 6 (Discoverability check) both require user choice in interactive mode. (sync-codex.sh rewrites this to a plain-text numbered prompt in the Codex mirror.)
Parse $ARGUMENTS for the literal token mode:autofix. If present, strip it from the arguments — the remainder is the scope hint.
RAW_ARGS="$ARGUMENTS"
MODE="interactive"
if [[ "$RAW_ARGS" == *"mode:autofix"* ]]; then
MODE="autofix"
# Strip token, collapse whitespace, trim.
SCOPE_HINT=$(printf "%s" "$RAW_ARGS" | sed 's/mode:autofix//' | tr -s ' ' | sed 's/^ //;s/ $//')
else
SCOPE_HINT="$RAW_ARGS"
fi
| Mode | When | Behavior |
|---|---|---|
| Interactive (default) | User is at the terminal | Ask decisions on ambiguous cases via blocking-question tool; confirm batched actions; run discoverability check with consent |
Autofix (mode:autofix in arguments) | Ralph or batch usage | No user questions. Apply Keep/Update/Consolidate/auto-Delete/Replace-with-sufficient-evidence directly. Mark ambiguous as stale. Print the full report. Discoverability surfaces as a recommendation, not an edit |
git rm subsumed), auto-Delete (only when code AND problem domain both gone), Replace (only with sufficient evidence to write a trustworthy successor).flowctl memory mark-stale <id> --reason "..." instead of guessing. Stale-marking writes are atomic and round-trip safe.In autofix mode, skip user questions entirely and apply the rules above.
In interactive mode, follow these principles:
AskUserQuestion (call ToolSearch with select:AskUserQuestion first if its schema isn't loaded). Fall back to numbered options in plain text only if the tool is unreachable or errors. Never silently skip the question.The goal is automated maintenance with human oversight on judgment calls — not a question for every finding.
.flow/memory/pitfalls.md, conventions.md, decisions.md at the memory root). Skip with a warning that recommends /flow-next:memory-migrate first. Report includes the skipped count._audit/, _review/, or any other _* directory under .flow/memory/.git rm on superseded decision entries. Decision history stays on disk. Replace for knowledge/decisions/ entries means write a new entry and mark the old decision_status: superseded with superseded_by: <new-id> — never delete the old file.memory mark-stale, memory mark-fresh, memory search --status). fn-38 task 2 ships only glossary {add,list,read,remove} — there is no flowctl glossary mark-stale; use Edit tool. Use Write tool + git for moves and deletes.context: fork — blocking-question tools must stay reachable.Compare .flow/meta.json setup_version to the plugin version; on mismatch, escalate once per plugin version. Fail-open throughout: a missing jq, .flow/meta.json, or plugin manifest silently continues.
SETUP_VER=$(jq -r '.setup_version // empty' .flow/meta.json 2>/dev/null)
PLUGIN_JSON="${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/.claude-plugin/plugin.json"
PLUGIN_VER=$(jq -r '.version' "$PLUGIN_JSON" 2>/dev/null || echo "unknown")
VERSION_ACK=$(jq -r '.version_ack // empty' .flow/meta.json 2>/dev/null)
if [[ -n "$SETUP_VER" && "$PLUGIN_VER" != "unknown" && "$SETUP_VER" != "$PLUGIN_VER" ]]; then
if [[ "${FLOW_RALPH:-}" == "1" || -n "${REVIEW_RECEIPT_PATH:-}" \
|| "${FLOW_AUTONOMOUS:-}" == "1" || "${ARGUMENTS:-}" == *mode:autonomous* || "${ARGUMENTS:-}" == *mode:autofix* \
|| "$VERSION_ACK" == "$PLUGIN_VER" ]]; then
echo "Local setup v${SETUP_VER} differs from plugin v${PLUGIN_VER}. Run /flow-next:setup to refresh local scripts." >&2
else
echo "FLOW_SETUP_ASK ${SETUP_VER} ${PLUGIN_VER}"
fi
fi
If the block printed a FLOW_SETUP_ASK line, before proceeding ask the user with AskUserQuestion (local setup differs from the plugin; refresh now?), offering exactly the options Refresh now, Remind me next version, Skip this run, then continue the skill whichever is chosen:
/flow-next:setup in this session (do not run setup yourself), then continue once it finishes.PJ="${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/.claude-plugin/plugin.json"
PV=$(jq -r '.version' "$PJ" 2>/dev/null)
[[ -n "$PV" && "$PV" != "null" ]] && rm -f .flow/meta.json.tmp && jq --arg v "$PV" '.version_ack = $v' .flow/meta.json > .flow/meta.json.tmp && mv .flow/meta.json.tmp .flow/meta.json
Any other output (the one-line differs notice, or nothing) is non-blocking: continue.
Execute the phases in workflow.md in order:
.flow/memory/{bug,knowledge}/<category>/, group by module / category, count, choose interaction path (focused / batch / broad), skip legacy + _* directories with a counted warning. knowledge/decisions/ entries are picked up automatically by the same glob.
0.5 Glossary scan — enumerate GLOSSARY.md files via flowctl glossary list --json; per term, grep tracked code for the term and each _Avoid_ alias (case-insensitive whole-word, normalized whitespace); zero hits + zero alias hits → mark stale via Edit tool (HTML comment after the term heading); alias hits → surface as alias-creep finding for Phase 3 (interactive) or report (autofix); skip husk files (count: 0) with a single advisory.decision_status: superseded, superseded_by: <new-id>; never git rm the old).git rm subsumed. Replace: write new entry, git rm old (decisions: write new + edit old's frontmatter to mark superseded, never git rm). Delete: git rm (only when code AND problem domain both gone). Glossary stale: Edit comment after term heading. Ambiguous in autofix: flowctl memory mark-stale.@-including the other) mentions .flow/memory/ with schema basics (track / category / module / tags / status) and when to consult. Add a minimal line if missing — interactive asks consent, autofix surfaces as recommendation.The full report is the deliverable — print it as markdown to stdout. Do not summarize internally and emit a one-liner.
Report structure (see workflow.md §5 for full schema):
Memory Audit Summary
====================
Scanned: N entries
Skipped legacy: M (run `/flow-next:memory-migrate` first to make these auditable)
Kept: X
Updated: Y
Consolidated: C
Replaced: Z
Deleted: W
Marked stale: S
Glossary
--------
Files scanned: F (H husks)
Terms scanned: T
Kept: K_g
Marked stale: S_g
Alias-creep flagged: A_g
Then per-entry detail (id, classification, evidence, action taken). For Consolidate: which entry was canonical, what unique content was merged, what was deleted. For Replace: what the old entry recommended vs what current code does, path to successor (decision Replace also notes the old entry now carries decision_status: superseded). For Marked stale: why ambiguous. For glossary terms: only stale + alias-creep cases get per-term lines (Keep is silent); husks get a one-line advisory each.
Autofix mode splits actions into Applied (writes succeeded) and Recommended (writes failed — e.g. permission denied). The structure is the same; only the bucket differs.
npx claudepluginhub gmickel/flow-next --plugin flow-nextAudits CLAUDE.md, rules, and memory files for stale references, orphaned content, contradictions, duplicates, misplacement, budget overruns, and unenforced claims.
Reviews and analyzes Claude Code's auto-memory system, identifying promotion candidates, stale entries, consolidation opportunities, and health metrics. Run via /si:review.
Audits Claude Code's auto-memory (MEMORY.md) for promotion candidates, stale entries, consolidation opportunities, and health metrics. Run via /si:memory-review.