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 does not sync memory — it writes the skill that does. /brewdoc:memory-sync-setup analyzes the target repo once, then emits a self-contained .claude/skills/memory-sync/ that already knows this repo’s batches, invariants, fact-verification commands, agent roster and language policy. Replaces the old brewdoc:memory.
Note
A remedy must be able to clear the verdict it follows. Before this release the artifact was stamped once at install and the stamp could never change: status reported stale, prescribed upgrade, and upgrade had no way to clear it — the only documented escape (MEMORY_SYNC_FORCE=1) destroyed every hand-edit in the process. The loop now closes: install at version X, bump the plugin, status says stale, upgrade runs generate.sh restamp as its mandatory last step, and the verdict returns to IN SYNC with the body byte-identical — a second upgrade is a no-op.
Quick reference
| Field | Value |
|---|---|
| Command | /brewdoc:memory-sync-setup [status|install|upgrade|enable|disable|uninstall|purge] [fine-tune-prompt] |
| Canonical modes | status · install · upgrade · enable · disable · uninstall · purge |
| No argument | status when .claude/skills/memory-sync/ exists, install when it does not |
| Extras | an optional free-form fine-tune prompt after the mode token |
| Invocation | user-invoked only — disable-model-invocation: true |
| Model | opus |
| Tools | Read, 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 four 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 skill is a long-running multi-agent coordinator. It sweeps the whole memory surface every run, splits it into disjoint batches (one bounded agent per batch, all spawned in one message), verifies every change with an independent checker that never wrote it, and enforces non-growth — every file ends at or below its original line count. It re-checks and updates itself between runs.
Free-form focus text only steers emphasis. It never narrows the sweep, and facts always come before dedup and compression.
When to use
| Scenario | Command |
|---|---|
| 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, asks about ambiguous scoping (convention files, memory dir, VERIFY-ONLY surfaces) via AskUserQuestion, then reports:
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 every fact, emphasis on rules
Workflow
- Mode gate
First token of the argument, lowercased:
status,install,upgrade,enable,disable,uninstallorpurge. No token at all meansstatuswhen the skill is already installed andinstallwhen it is not. The old aliasesinit/setupparse asinstall,on/offasenable/disable, andremove/reset/cleanupasuninstallorpurge(asked which) — the skill echoes the canonical verb back. Everything else is fine-tune text for{FOCUS_EMPHASIS}. - Phase 0 — read emit material
Reads its own four reference files —
references/SKILL.md.template,memory-guide.md,agent-audit.md,hard-sync.md. Missing material is a hard stop — never improvised. - Phase 1 — analyze the target
Runs
generate.sh scan, then determines the memory surface (root + every nestedCLAUDE.md, rules, conventions,AGENTS.mdfamily, 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. - Phase 1.5 — clarify
AskUserQuestiononly 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. - 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 fromplugin.jsonby script self-location, never hardcoded),generated_by,last_updated, plussurface_filesas the drift input, which is whatstatus,validateandupgraderead back. Refuses to overwrite an existing installation — that is whatupgradeis for. - Phase 3 — fill block placeholders
Multi-row tables and multi-line bash go through
Edit, not sed — twelve blocks total: ten in the emittedSKILL.md(batch table, exclusions, invariants, fact catalogue, enumeration bash, agent checks, skill checks, roster, proposal precedents, verify-extra assertions) and two in the emittedreferences/hard-sync.md(paths-precision table, obvious-vs-domain table). - Phase 4 — validate
generate.sh validatefails on any surviving{PLACEHOLDER}, a missing emitted asset, a cited reference that does not exist, or adisable-model-invocationkey in the emitted frontmatter (check 5 — the emitted skill must stay model-invocable). Then every emittedsubagent_typeis asserted to resolve to a real project agent or a built-in. - 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
statusor refresh it withupgrade.
Technical details
Modes
| Mode | Reads | Writes | Does |
|---|---|---|---|
status (default when installed) | target + emitted skill | nothing | Runs 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) | target | 4 emitted files | Full Phase 0-5 analysis and emit. Refuses if .claude/skills/memory-sync/ already exists |
upgrade | target + emitted skill | edits the emitted skill | Reads 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 |
enable | target | one rename | SKILL.md.disabled -> SKILL.md, so /memory-sync is offered again next session. Regenerates nothing — no provenance stamp, no hand-edit change |
disable | target | one rename | SKILL.md -> SKILL.md.disabled. Claude Code discovers a project skill only through SKILL.md, so this withdraws /memory-sync from the roster while the 3 references and every SELF-SYNC hand-edit stay byte-identical on disk. Reversible by enable; deletes nothing |
uninstall | target | deletes the emit manifest | Removes exactly what emit wrote — SKILL.md (or its parked form) plus the 3 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 |
purge | target | deletes the whole dir | Removes <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. 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):
| Axis | Emitted behavior |
|---|---|
| Scopes | session (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) |
| Depth | NORMAL (default, fact sync + dedup + compression) or HARD (adds the two deletion passes below) |
| Phases | GATHER (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-growth | Every file ends <= its original line count; total delta <= 0 |
| Agents | Re-audited against current best practice every sweep, not just fact-checked |
| Invocation | model-invocable — the emitted /memory-sync carries no disable-model-invocation, so Claude can fire it mid-plan and prose triggers (“sync memory”, “обнови память”) work. That flag belongs only to the distributed -setup skills; a generated artifact is meant to be reachable by the model |
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 + compression | yes | yes |
Pass A — rules paths: precision audit | no | yes |
| Pass B — obvious-knowledge purge | no | yes |
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 legitimatelyCORRECTLY_GLOBAL, and an explicitly declared repo-wide glob is never stripped. ADANGLINGentry 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
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
The other brewdoc tracker: staleness of docs/** by date. memory-sync-setup covers instruction memory, which docsync-setup leaves alone.
Setup Status
Read-only dashboard across every -setup skill — installed, stale or missing, with the hand-run command for each.
Brewdoc overview
All brewdoc skills in one place.
GitHub source
Source code, emit templates, and full SKILL.md for memory-sync-setup.
Updating plugins
/brewtools:plugin-update to check and update the brewcode plugin suite in one command.
See the FAQ for details.