sonnet read-only cross-plugin

Quick reference

FieldValue
Command/brewcode:setup-status [<plugin>|<skill>]
Argumentsempty = full report; a plugin name filters to its rows; a skill name prints one row with its detection rule spelled out
Modelsonnet
ToolsRead, Bash, Glob, Grepno Write, no Edit, no Agent
Covers11 setup skills across brewcode, brewtools and brewdoc
Writesnothing, ever

What it does

You open an unfamiliar repo and want one answer: what of the brewcode suite is already wired in here, what drifted since the last plugin update, and what was never installed. setup-status probes the project and hands back one table plus an ordered run-list.

Every probe is an existence check, a cmp against the installed plugin asset, or a one-line grep. Nothing is created, edited or deleted — that is a capability, not a policy: allowed-tools carries no Write, no Edit and no Agent, so the skill physically cannot mutate your project or spawn a subagent that could.

Staleness is decided from three signals, never mtime and never a guess: the artifact’s own version stamp (which plugin release produced it), its owner stampgenerated_by compared against the setup that should have written the path — and cmp against the plugin asset, which only corroborates the other two. A cmp source missing from the plugin cache reports version unknown (plugin asset missing), never stale.

A setup you switched off on purpose is reported disabled, not broken: the state is evaluated before missing, partial and stale, its command column offers enable, and it never enters the run-list.

Why it refuses to run the setups

There is no --run and no --fix, by design

Every setup skill is an interactive generator: it fans out subagents, analyses the repo and asks you real questions. Run two back-to-back in one session and both degrade — the context fills with the first one’s analysis, and the second one’s questions get answered against stale findings. So this skill reports and stops, and you run each setup by hand, ideally one per fresh session.

Ask it to “install everything” or “fix them all” and it refuses once, plainly, then prints the run-list instead. The flag does not exist because of the failure mode above, not because nobody got around to adding it.

When to use

SituationCommand
New repo, no idea what is wired in/brewcode:setup-status
Just updated the plugins, what drifted?/brewcode:setup-status
Only care about one plugin’s rows/brewcode:setup-status brewtools
One row, with its detection rule in full/brewcode:setup-status semble-setup
Free text, RU or EN — answers in your language/brewcode:setup-status что установлено

Example

/brewcode:setup-status
4 of 11 setups are behind the installed plugin (2 stale by version, 1 legacy stamp, 1 stale by wiring).

| Skill                           | State                   | Version         | Found                                                              | Command
| /brewcode:semble-setup          | stale                   | A.B.C            | rule + all five live hook files current; semble-explore.mjs (RETIRED, superseded by semble-subagent.mjs) is still on disk — wiring shows only 5 of the 6 settings.json entries the current version wants | /brewcode:semble-setup install "remove the retired hook file, re-wire all six settings entries"
| /brewtools:task-board-setup     | stale (X.Y.Z -> A.B.C)  | X.Y.Z -> A.B.C   | board.md + tracker present, .claude/skills/task-spec/ absent      | /brewtools:task-board-setup upgrade "retrofit the spec + design layer onto the deployed board, keep every task id"
| /brewtools:agent-deadline-setup | stale (X.Y.Z -> A.B.C)  | X.Y.Z -> A.B.C   | guard + config present, JSON trio never restamped since an older release | /brewtools:agent-deadline-setup upgrade "restamp the config trio at the current budget"
| /brewdoc:memory-sync-setup      | stale (legacy stamp)    | legacy -> A.B.C  | emitted SKILL.md has no frontmatter version: (the current carrier); the retired <!-- memory-sync template v1.0.0 --> tail survives only as the legacy detector | /brewdoc:memory-sync-setup upgrade "migrate the pre-5.0 tail stamp to provenance frontmatter"
| /brewdoc:docsync-setup          | missing                 | --               | nothing under .claude/docsync/                                    | /brewdoc:docsync-setup install
| /brewcode:teams-setup           | installed               | A.B.C            | team.md (Version A.B.C) + trace.jsonl + trace-ops.sh, all bytes match | /brewcode:teams-setup status
| /brewtools:think-short-setup    | disabled                | A.B.C            | 4 hooks wired, prompt renamed to think-short-prompt.md.disabled   | /brewtools:think-short-setup enable
| /brewtools:manager-setup        | n/a                     | --               | brewtools not installed                                            | claude plugin install brewtools@claude-brewcode

Run in this order, ONE PER SESSION:
  1. /brewcode:semble-setup install "..."           <- stale first
  2. /brewtools:task-board-setup upgrade "..."
  3. /brewtools:agent-deadline-setup upgrade "..."
  4. /brewdoc:memory-sync-setup upgrade "..."
  5. /brewdoc:docsync-setup install                 <- new installs last

Each of these spawns several subagents and will ask you questions. Running two in one
session degrades both. Start a fresh session per command.

think-short-setup is disabled on purpose — enable with /brewtools:think-short-setup enable.

roster: 11/11 in sync

A.B.C stands for the installed plugin version and X.Y.Z for an artifact’s own, older stamp in the samples above — the real report always prints real numbers, never these placeholders.

The last line is separate: it is Phase 5’s roster self-check, not part of the table above — it confirms the skill’s own roster still matches every *-setup directory shipped in the installed plugins.

The Command column is ready to paste. For stale and partial it always carries a concrete fine-tune prompt naming what to refresh — a bare upgrade with no prompt is not acceptable output. Only canonical verbs appear there (status · install · upgrade · enable · disable · uninstall · purge), plus the extras two setups genuinely add after them: reindex | optimize | resume for semble-setup, and level <...> for agent-router-setup and manager-setup.

Workflow

  1. Resolve plugin roots

    Finds the newest cached version of each of the four plugins under ~/.claude/plugins/cache/claude-brewcode/. A plugin that is not installed makes all of its rows n/a, never missing. All four absent = stop and say so, rather than printing an all-missing table.

  2. Probe artifacts

    One generic block fed from the roster: an existence check per anchor and secondary path, plus settings.json wiring greps and the global ~/.claude twins for the two setups that install to either scope. Textual grep counts prove a key is mentioned, not that the entry is well-formed — the report says so.

  3. Read the disable switches

    All eleven setups leave a real off-switch on disk, probed directly rather than inferred — the two mechanisms are detailed in Two rules that stop false alarms below. An absent key means OFF on the opt-in agent-deadline and agent-return rows, but ON on the opt-out agent-router and docsync rows — the two defaults ship side by side.

  4. Version signals

    Only for rows whose anchor exists and whose roster cell defines a signal. Read the version stamp, compare generated_by against the row’s own owner, then cmp the project copy against the plugin asset to corroborate. A missing plugin asset reports version unknown (plugin asset missing), never stale.

  5. Classify

    Exactly one state per row, evaluated in this fixed order: n/a, then disabled, then missing, then partial, then stale, then installed — why disabled outranks missing is explained in Two rules that stop false alarms below.

  6. Output

    One table in roster order, then the ordered run-list: partial (broken installs) first, then stale, then missing. disabled, installed and n/a rows stay out of it; a disabled row is mentioned once below the list with its enable command. Answers in the language you wrote in — the prose is translated, never the paths or the commands.

  7. Roster self-check

    Lists the *-setup directories actually present in the installed plugins and compares them against the roster. A setup it does not know about produces a warning above the table, never a silent edit. Match prints one line: roster: 11/11 in sync.

Technical details

A remedy must be able to clear the verdict it follows

Every earlier release verified that an artifact was stamped at install; none verified the stamp could ever move. upgrade used to refresh content and leave the version stamp untouched — status reported stale, upgrade reported success, the next status reported stale again, forever. All eleven setups now close that loop: install at an old version, bump the plugin, status reports stale, upgrade restamps it, status reports installed, and a second upgrade is a no-op with the artifact body byte-identical. A handful of findings genuinely have no clearing mode — a .template-baseline/ diff on superreview-setup, a hand-edited memory-sync reference, a hand-edited semble-first.md — and this skill reports those as a diff to port by hand, never dressed up as a command that would do nothing.

The 11 setups it covers

SetupAnchor artifact
/brewcode:teams-setup.claude/teams/*/team.md
/brewcode:semble-setup.claude/rules/semble-first.md
/brewcode:superreview-setup.claude/skills/superreview/SKILL.md
/brewtools:task-board-setup.claude/features/board.md
/brewtools:think-short-setup.claude/hooks/think-short-session.mjs (or the ~/.claude twin)
/brewtools:agent-deadline-setup.claude/hooks/agent-deadline-guard.mjs (or the twin)
/brewtools:agent-router-setup.claude/hooks/agent-router.mjs
/brewtools:manager-setup.claude/brewtools/manager/state.json
/brewtools:agent-return-setup.claude/hooks/agent-return-guard.mjs (or the twin)
/brewdoc:memory-sync-setup.claude/skills/memory-sync/SKILL.md
/brewdoc:docsync-setup.claude/docsync/config.json

Recurring tools never appear in the report — they have no installed state and are correct to run repeatedly: brewcode:agents, skills, rules, convention, e2e; brewtools:text-optimize, text-human, secrets-scan, ssh, deploy, plugin-update, provider-switch; brewdoc:md-to-pdf, my-claude, publish.

States

Evaluated in this fixed order:

#StateMeans
1n/athat plugin is not installed
2disabledinstalled, then switched off on purpose — a config flag flipped, or the entry file parked as <name>.disabled. Reported as inactive with its real version, never as broken and never as missing, and never queued in the run-list
3missingthe anchor is absent in both spellings, no <name>.disabled twin either — never installed here. A shared file the project happens to contain is not evidence
4partialsome artifacts present and some gone, a version stamp left as an unresolved {PLACEHOLDER}, a row-1/row-4 toggle caught half-parked, or generated_by naming the wrong setup
5stalethe version stamp is behind, ahead, retired, or missing, or the bytes drifted from the plugin asset — one of the four qualifiers below. An absence signal or semble’s wiring signal fires with no stamp or byte problem at all, and prints a bare stale naming the missing artifact in the Found column instead
6installedthe stamp equals the installed plugin version and every cmp pair matches

stale carries one of four qualifiers when a stamp or byte signal fired. Two cases print a bare stale with no qualifier and name the missing artifact in the Found column instead: an absence signal (a deployed board with no task-spec skill, a complete team with no trace-ops.sh) and semble’s wiring signal (retired[]/staleEntries when every file on disk is already byte-current).

QualifierMeans
(X.Y.Z -> A.B.C)the stamp is a plugin version behind (or ahead, printed the same way)
(legacy stamp)a retired stamp spelling is present instead of the current carrier
(legacy, unstamped)the artifact carries no stamp in any carrier at all
(bytes drifted)the version stamp is current but a cmp pair DIFFERS

One case survives outside this vocabulary: a cmp source missing from the plugin cache reports version unknown (plugin asset missing), never stale — the cache is incomplete, not the project.

Two rules that stop false alarms

Anchor MISS is decisive, and every secondary must be exclusive. The anchor is the artifact only that setup writes. A shared file — any hand-written .claude/agents/*.md, or intent-guard.md, which both superreview-setup and teams-setup can emit — is not evidence that this setup ran, and listing one as a secondary made teams-setup report a broken partial install (and jump to the top of the run-list) in every project that merely had an agent file. So teams-setup’s secondaries are now .claude/teams/*/trace.jsonl and .claude/teams/*/trace-ops.sh, superreview-setup no longer claims intent-guard.md, and a setup with no exclusive secondary is decided by its anchor alone.

disabled is evaluated before missing, partial and stale, because all three readings are wrong on a deliberately switched-off setup. Five setups disable by parking the anchor file itself — superreview-setup disable renames SKILL.md away, so checking presence first would report missing (“never installed”) for something the user turned off on purpose. think-short-setup disable renames its prompt file away, so the roster secondary legitimately MISSes — calling that partial tells you to repair something you turned off. Inversely, semble at enabled: false or a manager wall at hard: false has every file in place and byte-identical, and reporting it installed would hide that the mechanism is inert.

All eleven setups leave a real off-switch on disk, under two mechanisms: a live config flag the reader re-checks on every invocation, or entry-file parking, where the one filename Claude Code discovers is renamed to <name>.disabled with the body left byte-identical.

SetupMechanismOff-switchDisabled when
teams-setupentry-file parking.claude/agents/<member>.md.disabledevery roster member of team.md is parked. intent-guard is never parked — it is shared with superreview-setup
semble-setupconfig flag.claude/semble/state.json.enabled is false — every file stays in place
superreview-setupentry-file parking.claude/skills/superreview/SKILL.md.disabledpresent, SKILL.md gone. references/ stays readable
task-board-setupentry-file parkingany of task-tracker.md, task-board/SKILL.md, task-spec/SKILL.md, rules/tasks.md as .disabledevery deployed one of the four is parked; .claude/features/** untouched
think-short-setupentry-file parkingthe hooks dir (project or ~/.claude)think-short-prompt.md.disabled present, think-short-prompt.md absent — hooks stay wired and no-op
agent-deadline-setupconfig flag.claude/agent-deadline.json (or the ~/.claude twin)"enabled": false or the key absent — opt-in, so a key-less config is inert
agent-router-setupconfig flag.claude/brewtools/agent-router.json"enabled": false. An absent key means enabled — opt-out, the hook defaults enabled: true
manager-setupconfig flag.claude/brewtools/manager/state.json.hard is not true — the wall is disarmed, not broken
agent-return-setupconfig flag.claude/agent-return.json (or the ~/.claude twin)"enabled": false or the key absent — opt-in, so a key-less config is inert
memory-sync-setupentry-file parking.claude/skills/memory-sync/SKILL.md.disabledpresent, SKILL.md gone. The 3 references and every self-synced hand-edit stay
docsync-setupconfig flag.claude/docsync/config.json"enabled": false. An absent key means enabled — opt-out, for back-compat installs written before the key existed

Four rows read an absent key differently, and conflating them inverts a row: agent-deadline and agent-return are opt-in (cfg.enabled !== true), so no key means OFF. agent-router and docsync are opt-out (c.enabled !== false), so no key means ON.

How staleness is decided

Three signals, never mtime and never a guess. None answers another’s question — the version stamp cannot see body drift, cmp is meaningless for a generated artifact, and only generated_by catches the wrong setup writing a path that is otherwise perfectly current.

SignalQuestionHow
version stamp (headline)which plugin version produced what is installed here?frontmatter version:, a top-level JSON key, a brewcode-meta: comment after the shebang, or team.md’s | Version | header row — whichever carrier the roster names for that row
owner stampdid the setup that owns this path actually write it?generated_by compared against the row’s own <plugin>:<skill>. A mismatch is partial; a real version with no generated_by beside it is stale (legacy stamp)
cmp vs the plugin asset (corroborating)was this file actually re-copied after the plugin update?byte equality on the copied files — semble’s rule + all five live hook files (never .sembleignore; those five files wire as six settings.json registrations, since semble-stats.mjs fires on both PostToolUse and PostToolUseFailure), think-short’s 4, agent-deadline’s 2, agent-router’s 1, the manager guard, docsync’s 3, two of memory-sync’s 3 references, and trace-ops.sh

semble-setup reads a fourth, independent signal: wiring. .claude/settings.json can list a hook that no longer exists, or omit one the current version wants, while every file on disk is already byte-current — retired[], staleEntries and wiredCount/wantCount catch what a version-and-bytes check cannot see.

Per-row notes worth knowing before reading a row: memory-sync-setup’s version stamp is frontmatter version: resolved from brewdoc/.claude-plugin/plugin.json — the <!-- memory-sync template vX.Y.Z tail is a retired legacy stamp, read only as a fallback. superreview-setup reads the version out of the emitted SKILL.md frontmatter, never out of .template-baseline/, which stays at the unresolved {PLUGIN_VERSION} token by design. teams-setup and task-board-setup both carry real stamps (team.md’s \| Version \| header row, board.md’s frontmatter version:) — an earlier release forced both into an “unknown” state; that state is retired. Two absence signals still stand in for a stamp: a deployed board with no .claude/skills/task-spec/ predates the spec + design layer, and a complete team with no trace-ops.sh is a pre-standard install whose agents cannot trace — both stale, cleared by one upgrade.

The version-comparison heredoc

Every stamp read in the table above comes from one heredoc — plugin|path|expected-owner|content_version-source — twenty-one lines covering the roster’s eleven rows. The fourth field names the plugin file that supplies that SAME artifact’s own content_version, so each row is measured against its own history, never against the release-wide plugin version directly:

brewcode|.claude/teams/*/team.md|brewcode:teams-setup|skills/teams-setup/SKILL.md
brewcode|.claude/rules/semble-first.md|brewcode:semble-setup|skills/semble-setup/assets/semble-first.md.template
brewcode|.claude/skills/superreview/SKILL.md|brewcode:superreview-setup|skills/superreview-setup/SKILL.md
brewtools|.claude/features/board.md|brewtools:task-board-setup|skills/task-board-setup/SKILL.md
brewtools|.claude/hooks/think-short-session.mjs|brewtools:think-short-setup|skills/think-short-setup/assets/think-short-session.mjs
brewtools|~/.claude/hooks/think-short-session.mjs|brewtools:think-short-setup|skills/think-short-setup/assets/think-short-session.mjs
brewtools|.claude/hooks/agent-deadline-guard.mjs|brewtools:agent-deadline-setup|skills/agent-deadline-setup/assets/agent-deadline-guard.mjs
brewtools|~/.claude/hooks/agent-deadline-guard.mjs|brewtools:agent-deadline-setup|skills/agent-deadline-setup/assets/agent-deadline-guard.mjs
brewtools|.claude/agent-deadline.json|brewtools:agent-deadline-setup|skills/agent-deadline-setup/assets/INSTALL.md
brewtools|~/.claude/agent-deadline.json|brewtools:agent-deadline-setup|skills/agent-deadline-setup/assets/INSTALL.md
brewtools|.claude/hooks/agent-router.mjs|brewtools:agent-router-setup|skills/agent-router-setup/assets/agent-router.mjs
brewtools|.claude/brewtools/agent-router.json|brewtools:agent-router-setup|skills/agent-router-setup/assets/INSTALL.md
brewtools|.claude/brewtools/manager/state.json|brewtools:manager-setup|hooks/lib/manager-state.mjs
brewtools|.claude/brewtools/manager/hardmode-guard.mjs|brewtools:manager-setup|hooks/hardmode-guard.mjs
brewtools|.claude/hooks/agent-return-guard.mjs|brewtools:agent-return-setup|skills/agent-return-setup/assets/agent-return-guard.mjs
brewtools|~/.claude/hooks/agent-return-guard.mjs|brewtools:agent-return-setup|skills/agent-return-setup/assets/agent-return-guard.mjs
brewtools|.claude/agent-return.json|brewtools:agent-return-setup|skills/agent-return-setup/assets/INSTALL.md
brewtools|~/.claude/agent-return.json|brewtools:agent-return-setup|skills/agent-return-setup/assets/INSTALL.md
brewdoc|.claude/skills/memory-sync/SKILL.md|brewdoc:memory-sync-setup|skills/memory-sync-setup/SKILL.md
brewdoc|.claude/docsync/config.json|brewdoc:docsync-setup|skills/docsync-setup/SKILL.md
brewdoc|.claude/hooks/docsync-track.mjs|brewdoc:docsync-setup|skills/docsync-setup/assets/docsync-track.mjs

Twenty-one lines over eleven rows, because several rows contribute more than one carrier: think-short-setup and agent-router-setup two each (project scope plus global, or hook plus config), agent-deadline-setup and agent-return-setup four each (guard and config, project and global scope), manager-setup two (state.json primary, the copied guard as a documented fallback). Two assertions guard the set against silent drift, both a hard exit 1 rather than a warning: TOTAL must equal 21 — a line deleted anywhere aborts the run, even in a plugin group this pass is not scanning — and SEEN must equal the group’s own WANT (brewcode 3, brewtools 15, brewdoc 3).

Reading a stamp also compares its generated_by against the line’s expected owner. A different name reports OWNER-WRONG — some other setup wrote this path — and a real version with no generated_by beside it reports OWNER-NONE, treated as stale (legacy stamp).

Fixed: no more false BEHIND on a missing cache source

An artifact’s headline stamp is measured against its OWN content_version-source — the plugin file that supplies that same artifact’s current content_version — never against the release-wide plugin version directly. When that source file is absent from the plugin cache, the skill used to fall back to comparing against the plugin version anyway, which could print a bogus regression like stale (5.6.0 -> 5.7.0) on an artifact that had not actually changed. It now reports the gap and stops: no source, no verdict, classified unknown, never stale.

Version resolution never guesses

The plugin version every stamp is measured against is resolved, never typed in by hand and never inferred loosely: the installed cache directory’s basename first (~/.claude/plugins/cache/claude-brewcode/<plugin>/*/, newest by sort -V), that root’s .claude-plugin/plugin.json .version second — the same precedence the brewcode SessionStart hook uses. When neither resolves, the skill aborts rather than guessing: feeding an unresolved value to sort -V would silently produce a confident but meaningless BEHIND/AHEAD verdict instead of an honest failure.

Two things that look like staleness and are not

Looks likeActually
manager-setup’s guard DIFFERSOnly means the wall was not re-armed since the last brewtools update. It still works. Reported stale, with that clause attached — a different finding from hard: false, which is disabled and outranks it
A hook under ~/.claude while the project also has oneA scope answer, not a conflict. think-short-setup and agent-deadline-setup are legitimately global
The repo-root .sembleignore reads DIFFERS/bytes driftedUsed to be a false alarm on every healthy project — the installer appends a measured-candidates block to .sembleignore after copying it, so a correct install is never byte-equal to the template by construction. .sembleignore is now out of the cmp set; its presence and its own version stamp are still checked and still valid. unchanged reported by an installer does not mean byte-equal to the template — worth keeping in mind reading any row on this dashboard

Edge cases

ConditionResponse
No .claude/ in the projectEvery row missing; the table and the install run-list print anyway
All four plugin roots absent”no brewcode plugins installed” plus the claude plugin install lines — not an all-missing table
Running with --plugin-dir (dev mode)No cache root to compare against. Says so; a repo checkout is not a substitute
A cmp source path is missing from the cacheversion unknown (plugin asset missing), never stale
A *-setup on disk the roster does not knowWARNING above the table naming it, and the note that its state was not checked

Roster as single source of truth

Every fact the skill knows lives in ONE table in its SKILL.md. Adding a future setup is one row — no script, no second list, no code change, because every probe is a generic inline block fed from that table.

🚀

brewcode overview

Full plugin overview — all skills, agents, and hooks in one place.

🔍

semble-setup

One of the eleven rows: its five hooks and rule are cmpd verbatim against the plugin assets.

superreview-setup

Another row: staleness comes from its .template-baseline/ diff, so your tailoring never counts as drift.

🔗

GitHub source

SKILL.md — the roster table, the probe blocks, and the output contract.

Updating plugins

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