Skip to content

Audit

/flow-next:audit is the agent-native staleness review for the .flow/memory/ store.

Memory entries decay. A bug note logged six months ago might reference a renamed file, a deleted function, or a codepath that no longer exists. Without periodic review, memory-scout ends up surfacing outdated advice.

The host agent walks .flow/memory/, reads each entry, verifies references against the current codebase via Read / Grep / Glob / git, and decides per entry.

OutcomeWhen
KeepEntry is still accurate and useful.
UpdateCore point holds; references or wording need a refresh - or the entry is fine and hard to find, and its retrieval surface gets repaired.
ConsolidateMultiple entries cover the same ground; merge them.
ReplaceConclusion has changed; write a successor, mark the old one superseded.
DeleteCode is gone AND the problem domain is gone. Rare.
HardenThe lesson keeps recurring and is mechanizable: graduate it into an enforced gate (a lint rule or a CI step in a surface the repo already has) and demote the entry to a pointer at the gate.

Delete is reserved for unambiguous cases. When in doubt, the audit prefers Replace or Consolidate so the prior context is preserved.

Harden (added in 3.4.5) is the graduation path. A lesson your agent keeps re-learning should stop riding the context window and become a gate. The audit verifies the gate actually fires before demoting the entry - the file stays on disk with hardened_into pointing at the gate, so provenance survives, and flowctl memory mark-fresh un-graduates it if the gate is ever removed. Harden never applies unattended. In autofix runs, and under any autonomy marker (flow --auto sets FLOW_AUTONOMOUS for the stages it dispatches), it only reports candidates, because lint configs, CI workflows, and instruction files are shared repo infrastructure.

Harden picks the gate from the same hardening ladder as flow’s repeated-mistake route: remove the opening first, then make the bad state unwritable, then a lint or CI check whose message names the fix, then a test, and instruction text last, only for judgment calls. Audit writes only the lint or CI level. When the right fix changes code (one owner for the state, a type, a test), or the repo has no lint or CI surface to host the gate, the audit recommends the repeated-mistake route instead and leaves the entry active; it no longer writes a CLAUDE.md or AGENTS.md rule for a lesson a check could enforce. Entries hardened into an instruction-file rule earlier keep their liveness check. When the entry names a past occurrence, the new gate must fail on it before the entry is demoted.

Update carries a retrieval fix (added in 4.13.0) for the lesson Harden cannot take. When an entry keeps recurring but states a rule no lint or CI step can check, the audit asks whether the entry is hard to find rather than wrong, and repairs its title, tags, module, and applies_when - moving a misfiled entry into the category the lesson belongs to, since a category-scoped search never reaches an entry filed somewhere else. The retrieval rationale never rewrites the entry’s body; plain reference drift in the same entry is still repaired on its own evidence, in the same Update. A nameable defect in the retrieval surface is required, so an already-findable entry falls through to the ordinary drift check. The report counts retrieval fixes inside Updated.

  • All categorized entries under .flow/memory/bug/ and .flow/memory/knowledge/.
  • decisions/ entries get a calibrated judging question: does the constraint that motivated this choice still hold?
  • GLOSSARY.md terms are scanned for code usage; zero-hit terms get a <!-- stale: ... --> marker.

Legacy flat files (pitfalls.md, conventions.md, decisions.md at the memory root) are skipped with a pointer to /flow-next:memory-migrate.

ModeBehavior
Interactive (default)Ask one question at a time on ambiguous classifications. Batch obvious Keeps and Updates. Confirm Consolidate / Replace / Delete / Harden one at a time.
Autofix (mode:autofix)No user questions. Apply safe actions directly. Ambiguous cases are marked stale, not deleted. Harden candidates are reported only, never applied. On the default branch it commits to a new local branch, docs/audit-memory-<date>, and reports its name; on a feature branch it adds a separate commit. It never pushes or opens a pull request unless asked.

A scope hint after the mode token narrows the audit to a concept, category, module, or path.

knowledge/decisions/ entries persist on disk even when superseded. Replace means writing a new entry and marking the old one decision_status: superseded with a superseded_by: pointer - never git rm. Decision history is the audit trail.

  • Not a way to mass-rename code from a glossary finding. The audit reports file:line locations and stops there.
  • Not a substitute for thoughtful curation when adding memory. Bad entries are still bad after an audit.
/flow-next:audit src/auth
Scope: module src/auth - 6 memory entries matched
keep bug/runtime-errors/token-refresh-race (still reproduces at src/auth/refresh.ts:88)
keep knowledge/patterns/session-store-convention (convention still followed)
update knowledge/decisions/cookie-vs-header-auth (decision text references moved file; path fixed)
delete bug/build-errors/legacy-esbuild-flag (flag removed in the build revamp; entry obsolete)
Applied: 4 kept, 1 updated, 1 deleted.

Every verdict names its evidence in the current codebase - an entry is never kept just because it exists.

Recipes that compose with audit in the cookbook:

  • Evidence-first - memory hygiene keeps the evidence trail trustworthy for the skills that read it.

After running, review the report and the skills that read memory pick up the updated store:

Terminal window
/flow-next:plan <spec-id> # plans now ground on fresh memory