memory-sync-setup — generate a project-tailored memory sync

Caution

Generic memory sync produces generic results. A one-size sweep cannot tell an intentional Russian trigger alias from a language violation, cannot tell a stale lint-rule claim from a correct one, and cannot prove a removed fact is gone from the codebase rather than merely deleted from a doc.

Tip

This skill writes the skill that syncs memory. /brewdoc:memory-sync-setup analyzes the target repo, then emits a self-contained .claude/skills/memory-sync/ with its batches, invariants, fact-verification commands, agent roster and language policy.

What's new in 6.2.0

Adds references/prompting-guide.md (18 merged rules) and a prompt-quality step — see Prompt quality pass.

Note

Upgrade refreshes verified surface and batch facts while preserving hand-edits, then finishes with generate.sh restamp. Restamping updates metadata without rewriting the body; it can clear a stale stamp, while genuine source drift still requires the corresponding verified correction.

Quick reference

FieldValue
Command/brewdoc:memory-sync-setup [prompt] [status|install|upgrade|enable|disable|uninstall|purge] [fine-tune-prompt]
Canonical modesstatus · install · upgrade · enable · disable · uninstall · purge
No argumentstatus when .claude/skills/memory-sync/ exists, install when it does not
ExtrasFree-form fine-tune text; an explicit mode can appear anywhere
Invocationuser-invoked only — disable-model-invocation: true
Modelopus
ToolsRead, Edit, Glob, Grep, Bash, Agent, AskUserQuestion

What it does

/brewdoc:memory-sync-setup is a generator, in the same family as brewcode:superreview-setup and brewtools:task-board-setup: it produces a working artifact instead of doing the work itself. It scans the target project — memory surface (root and every nested CLAUDE.md, rules, conventions, the AGENTS.md family, agents, skills, the memory dir), exclusions, default branch, git visibility, language policy, agent and skill rosters — then emits five files into <target>/.claude/skills/memory-sync/. docs/** stays explicitly out of scope, owned by a separate doc flow (/docs, docsync-setup) — this skill covers instruction memory, not prose documentation.

The emitted /memory-sync coordinates disjoint bounded batches and verifies changes with independent checkers. It inventories project rules recursively, including nested .claude/rules/**/*.md, through the generator’s shared surface producer. Its default write set covers instruction memory; explicit user restrictions filter that set before dispatch and self-sync. It applies non-growth with documented repair/salvage exceptions and re-checks itself between runs.

Ordinary focus text steers emphasis. Explicit instructions such as “only rules” or “do not touch agents” narrow authorized writes across every reach, batch, salvage and self-sync operation. Skipped layers are reported. Facts precede dedup and compression.

When to use

ScenarioCommand
First time wiring memory sync into a repo/brewdoc:memory-sync-setup install
Bias the emitted skill toward a specific concern/brewdoc:memory-sync-setup install "weight stale-fact removal over compression"
Check whether an installed memory-sync is still true to the repo/brewdoc:memory-sync-setup status
Repo gained a new agent, rule, or CLAUDE.md since install/brewdoc:memory-sync-setup upgrade
Pause /memory-sync without losing hand-edits/brewdoc:memory-sync-setup disable
Bring a paused /memory-sync back/brewdoc:memory-sync-setup enable
Drop the emitted skill from the repo, keep user-added files/brewdoc:memory-sync-setup uninstall
Drop the whole .claude/skills/memory-sync/ directory, no survivors/brewdoc:memory-sync-setup purge
Actually sync memory in a repo that already has it installed/memory-sync (the emitted skill, not this one)

Example

/brewdoc:memory-sync-setup install
[memory-sync-setup] MODE: install - matched token install
Target:   /Users/you/project
Emphasis: none

The skill scans the project and asks once about unresolved material scoping. Illustrative output for a scanned project follows; actual counts come from that project’s inventory:

memory-sync generated -> .claude/skills/memory-sync/

Surface:    68 files: 5 root, 15 rules, 3 conventions, 26 agents, 18 skills, 1 local
Batches:    6  (root:5, rules:15, conventions:3, agents:26, skills:18, local:1, disjoint)
Excluded:   docs/** (separate doc flow), source code, secrets, .claude/features/**

Run it:  /memory-sync                       -> scope session (default), whole surface
         /memory-sync all "only rules"      -> re-verify facts in authorized rules only

Workflow

  1. Mode gate

    An explicit lifecycle mode anywhere wins; otherwise prompt evidence resolves it. Empty input means status when installed, install when absent. One bundled question resolves material write ambiguity before work; read-only status asks nothing. Remaining prose supplies fine-tune text.

  2. Phase 0 — read emit material

    Reads its own five emit-material files — references/SKILL.md.template, memory-guide.md, agent-audit.md, hard-sync.md, prompting-guide.md. Missing material is a hard stop — never improvised.

  3. Phase 1 — analyze the target

    Runs generate.sh scan, then determines the memory surface (root + every nested CLAUDE.md, rules, conventions, AGENTS.md family, agents, skills, memory dir), VERIFY-ONLY files, exclusions, default branch (derived, never hardcoded), git visibility, language policy, and a checkable-fact catalogue — one real shell command per claim.

  4. Phase 1.5 — clarify

    AskUserQuestion only for what cannot be reliably inferred: which convention files count as memory, whether the memory dir is in scope, VERIFY-ONLY list, default branch, intentional non-English trigger aliases, batch splits.

  5. Phase 2 — emit

    Exports scalar placeholders and runs generate.sh emit: awk-substitutes them into the template, copies the reference files, then stamps provenance into the emitted skill’s YAML frontmatter — doc_type, version (the brewdoc plugin version, read from plugin.json by script self-location, never hardcoded), generated_by, last_updated, plus surface_files as the drift input, which is what status, validate and upgrade read back. Refuses to overwrite an existing installation — that is what upgrade is for.

  6. Phase 3 — fill block placeholders

    Multi-row tables and multi-line bash go through Edit, not sed — twelve blocks total: ten in the emitted SKILL.md (batch table, exclusions, invariants, fact catalogue, enumeration bash, agent checks, skill checks, roster, proposal precedents, verify-extra assertions) and two in the emitted references/hard-sync.md (paths-precision table, obvious-vs-domain table).

  7. Phase 4 — validate

    generate.sh validate fails on any surviving {PLACEHOLDER}, a missing emitted asset, a cited reference that does not exist, or a disable-model-invocation key in the emitted frontmatter (check 5 — the emitted skill must stay model-invocable). Then every emitted subagent_type is asserted to resolve to a real project agent or a built-in.

  8. Phase 5 — report

    Prints surface counts, batches, exclusions, fact/invariant counts, and how to run the emitted skill — plus how to check on it later with status or refresh it with upgrade.

Technical details

Modes

ModeReadsWritesDoes
status (default when installed)target + emitted skillnothingRuns generate.sh status, which prints a machine-greppable KEY=value block — PLUGIN_VERSION, STAMP_FORMAT, the META_* provenance rows, surface files stamped vs enumerated now, missing emitted files, unfilled placeholders — closed by a verdict: IN SYNC / STALE (n drifts) / STALE-LEGACY (n drifts) (a pre-5.0 install still carrying the old tail-comment stamp — run upgrade to migrate it) / NOT INSTALLED, each prefixed PARKED - when disabled. The skill then enriches it with its own reads: dead batch paths, memory layers gained since install
install (default when nothing is installed)target5 emitted filesFull Phase 0-5 analysis and emit. Refuses if .claude/skills/memory-sync/ already exists
upgradetarget + emitted skilledits the emitted skillReads the same generate.sh status drift list as its refresh worklist, then re-scans and refreshes surface/batch/fact/invariant tables, adds sections for new memory layers, preserves hand-edits — the emitted skill is expected to have self-modified via its own SELF-SYNC phase — and always finishes with generate.sh restamp — which also DELETES a disable-model-invocation key left by a pre-5.5.1 install, printing a REMOVED: line, so an old emit becomes model-invocable without a re-emit
enabletargetone renameSKILL.md.disabled -> SKILL.md, so /memory-sync is offered again next session. Regenerates nothing — no provenance stamp, no hand-edit change
disabletargetone renameSKILL.md -> SKILL.md.disabled. Claude Code discovers a project skill only through SKILL.md, so this withdraws /memory-sync from the roster while the 4 references and every SELF-SYNC hand-edit stay byte-identical on disk. Reversible by enable; deletes nothing
uninstalltargetdeletes the emit manifestRemoves exactly what emit wrote — SKILL.md (or its parked form) plus the 4 references — after confirmation. Files a user added to that dir are kept and listed. Nothing installed -> reports “nothing to uninstall” instead of deleting on a guess
purgetargetdeletes the whole dirRemoves <target>/.claude/skills/memory-sync/ outright, user-added files included, plus any .memory-sync-emit.* staging a crashed emit left behind. Confirmation first

What gets emitted — <target>/.claude/skills/memory-sync/: SKILL.md (scalars substituted, blocks filled), references/memory-guide.md, references/agent-audit.md, references/hard-sync.md, references/prompting-guide.md. Nothing else — no agent, no rule, no hook.

Enable/disable is entry-file parking, not a flag. status reports a parked install as INSTALLED=parked, never collapsed into NOT INSTALLED.

Version resolution never guesses. resolve_plugin_version() reads .version out of the plugin’s own plugin.json by self-location. The string unknown is an internal sentinel only — emit and restamp hard-fail before writing anything (❌ FAILED: cannot read .version from plugin.json - reinstall brewdoc) rather than ever stamping the literal unknown into an artifact.

Git visibility is a real set difference, not a count delta. derive_git_visibility() compares git ls-files against a parallel filesystem find with comm -23, so an untracked file is never cancelled out by an unrelated tracked-but-pruned one — a fix that changed the classification itself, not just its wording. The scalar now reads git-tracked / git-ignored / no-commits / mixed (N tracked, M untracked), and a mixed or git-ignored verdict tells the emitted skill’s VERIFY phase it can never trust a git diff alone and must re-read files directly.

Emitted-skill behavior (what this generator bakes in, not what it runs itself):

AxisEmitted behavior
Scopessession (default, no gather agent), branch (diff vs derived default branch), commit <sha> / commit <a>..<b>, recent[:N] (default 10), all (no diff, every fact re-verified)
DepthNORMAL (default, fact sync + dedup + compression) or HARD (adds the two deletion passes below)
ReachMEMORY (default instruction surface) or REFS (also eligible tracked outside references cited by always-loaded instructions); explicit user write restrictions still apply
PhasesGATHER (parallel read-only) -> SYNC (one bounded agent per disjoint batch, one message) -> VERIFY (independent checker per batch, never the writer) -> SELF-SYNC (re-checks itself) -> PROPOSE (new agent/skill proposed, never auto-created) -> REPORT (chat only, no report file)
Non-growthPer-file and total non-growth by default; HARD paths repair and verified same-agent/same-batch authorized-store salvage have explicit evidence and line-budget exceptions
AgentsRe-audited against current best practice every sweep, not just fact-checked
Prompt qualityreferences/prompting-guide.md’s 18-rule table applied to instruction files every sweep; NORMAL fixes only where it coincides with a fact/dedup edit, HARD rewrites every remaining violation
InvocationModel-invocable by design: emitted frontmatter has no disable-model-invocation; prose activation is best-effort. All distributed suite skills use user-only invocation

Scope and safe evidence

Scope selects change facts, depth selects processing and reach selects eligible editable files. User narrowing overrides all three. At default MEMORY reach, outside references are resolution-checked and findings reported without edits. REFS adds eligible tracked references cited by always-loaded instructions; outside references cited by lazy paths: rules remain reported, not edited. Source code, doc-flow paths and secrets stay excluded from writes at every reach.

Verification reads only the minimum non-secret evidence needed for authorized files. Credential names, key paths and identifiers can be checked; actual keys and secret files must never be read or copied into reports. Explicit read exclusions remain binding. Salvage cannot move evidence into an excluded store or cross another agent’s ownership, and any permitted recipient growth is bounded by removed-store lines with nonpositive total delta.

Depth: NORMAL vs HARD

{SCOPE} picks which change facts drive the sweep; {DEPTH} picks how hard the surface itself is cut. Depth is a property of the request — the token hard, or the same intent in prose (“too much context”, “aggressive”, “почисти жёстко”). Nothing is regenerated to switch it.

NORMAL (default)HARD
Fact sync + dedup + compressionyesyes
Pass A — rules paths: precision auditnoyes
Pass B — obvious-knowledge purgenoyes

A long-running repo accumulates dead weight across every auto-loaded file, not just CLAUDE.md — and neither kind of waste shows up in a diff. HARD targets both, sourced from the emitted references/hard-sync.md:

  • Pass A — paths: precision. paths: is a list; every entry gets its own verdict: OK, TOO_BROAD, TOO_NARROW, DANGLING, MISSING, CORRECTLY_GLOBAL. A rule that fires on every turn when it only concerns one module is pure waste — narrow its glob. A genuinely repo-wide subject is legitimately CORRECTLY_GLOBAL, and an explicitly declared repo-wide glob is never stripped. A DANGLING entry is dropped from the list and reported — the rule file itself is never deleted.
  • Pass B — obvious-knowledge purge. Delete what any competent model already knows — generic quality exhortations, mainstream-feature tutorials, restated tool docs. Keep the domain decisions that only make sense because someone in this repo decided them. The unit is a rule (a numbered row plus its continuation lines), never a line. Two brakes: a Borderline table overrides the discriminator (a line naming a concrete path, command, version or number is always kept), and a file cut by more than half is reported before the edit lands.
/memory-sync all hard

Prompt quality pass

Every sweep applies its prompt-quality table to authorized instruction files: CLAUDE.md at any depth, recursive .claude/rules/**/*.md, the AGENTS.md family and agent/skill bodies. Code and prose documentation stay outside the write set. The table lives in references/prompting-guide.md with 18 rules, detection signals and rewrites; user restrictions remain binding.

NORMAL (default)HARD
Violation on a line a fact/dedup edit already touchesfixedfixed
Violation on an otherwise-untouched linereported onlyfixed

Sample rows from the table:

#RuleAppliesDetect
5Drop scattered ALL-CAPS; at most one true hard-stop word per artifactbothgrep -o for MUST/NEVER/CRITICAL/ALWAYS returns more than one hit in a file
12File-size budgets for authored artifactsbothSKILL.md over 500 lines / 2000 words, agent .md over 1500 words, hook additionalContext over 9000 chars
15AGENTS.md build/size-cap/nested-override mechanicsopenai-onlya nested AGENTS.md restates a root rule instead of overriding it
18Explicit stop conditions and safe/unsafe action boundaries for agentic tasksboth”keep working until done” with no named boundary around a risky action

Applies marks which side reads that copy: claude (Claude 5 reads the file directly), openai-only (only the AGENTS.md projection is read against it), or both. A lossless guard sits underneath every rewrite — paths, CLI flags, thresholds, versions, model ids, an incident-backed !=/NEVER row, and canonical mode/verb lists (status | install | upgrade | ...) are never rewrite targets, even when a rule technically matches.

The Phase 6 report gains a Prompt column per file plus a summary line: Prompt quality: {N} rewrites applied, {M} reported (references/prompting-guide.md).

Error handling highlights — install on an existing installation stops and points to upgrade; upgrade with nothing installed stops and points to install; a fact with no runnable verification command is left out of the catalogue rather than invented; an AGENTS.md symlink or vendor-marked file becomes VERIFY-ONLY, never an edit target.

Frontmatter omissions — no cli (the command already equals the skill name) and no version (behavior lives entirely in the skill dir, whose hash already changes with it).

🔄

docsync-setup

Date-based staleness tracking for touched Markdown; memory-sync verifies instruction claims against source.

✨

Text Optimize

Shares references/prompting-guide.md’s sibling rule table — its own PQ pass rewrites prompt-shaped files the same way this generator’s emitted skill does.

🚀

Brewdoc overview

All brewdoc skills in one place.

🔗

GitHub source

Source code, emit templates, and full SKILL.md for memory-sync-setup.

Updating plugins

Use /brewtools:plugin-update to check and update the brewcode plugin suite in one command. See the FAQ for details.