Decides optimization-inbox candidates with evidence, applies the approved ones, keeps the ledger. Triggers: "/we:optimize".
Install
npx skillscat add weside-ai/claude-code-plugin/optimize Install via the SkillsCat registry.
/we:optimize
- Act only on what the store says, read from the default branch: the shared checkout often lags,
and where memory disagrees, the files win. Store format:${CLAUDE_PLUGIN_ROOT}/references/optimization-store.md. - No change without evidence and the user's approval. Evidence is a measured number, or a
repository fact (a contradicted claim, a gate violation, a documented limit). Every applied
change carries a review date and is removed again when it does not pay off (step 4). - A product-owner decision (product, comfort, cost above a cap, deleting) is one question with a
recommendation, never a ledger entry on its own. - Commits follow the target repo's own instruction files. Where they say nothing about where
instruction changes land, ask once. - The plugin's own checkout holds no store. Plugin changes go there as a PR; their findings stay in this repo's inbox.
1 · Restore
git fetch -q origin && git show origin/<default>:.weside/optimization/CHARTER.mdRead the charter (goal, decisions, findings, next steps), then LEDGER.md, then every file ininbox/, plus entries staged under ~/.claude/we-inbox/<repo>/ by an auto retro: move those intoinbox/ now. No store → offer /we:setup § Instruction loop and stop. Tell the user briefly where
things stand, what you do now, and whether you need anything.
2 · Audit first?
Read sources.lock. Fetch and hash the sources per${CLAUDE_PLUGIN_ROOT}/references/instruction-sources.md and compare; the lock itself stays the
audit's to write. Recommend /we:instruction-audit before deciding anything when a source hash
changed, the target model or effort differs from .weside/config.json, claude --version differs,
the audit is 30 days old or older, or no audit ran yet. One question; on "no", continue with the
inbox as it is.
3 · Consolidate
- Merge files that carry one key into the oldest; their evidence lines add up.
- Group by target file. Two entries on one file that pull in opposite directions are decided together.
- Order: evidence count × confidence (High 3, Medium 2, Low 1);
gapandG2-conflictentries
with a user correction among their evidence go first. - A rejected key again. An entry whose key has a
rejectedledger row goes on only when its new
evidence answers that row's reason (the count adds the row's evidence: a second occurrence answers
"seen once"). Otherwise delete the file in the store commit; the rejection stands.
4 · Measure "after", sunset, ablation
- After. Ledger rows with an
afterstill pending get their number now via the adapter, or
without one from recurrence (store reference § Measurement adapter); a row
that cannot be measured yet keepspendingand names when it can (a plugin change: after release
and/plugin update). Anappliedrow withoutreview_bygets its date plusoptimization.review_days(default 30), unless its change was a removal (—). - Sunset. An
appliedrow whosereview_byhas passed becomes aremovecandidate
(source: sunset) when itsaftershows no improvement overbefore, when its failure recurred
after the apply date (an evidence line for its key), or when a gate now enforces the same thing. - Unmeasured. A row past
review_bywhose failure never recurred and that nothing measures is
noremovecandidate: the change may be why the failure stopped. With an ablation command it goes
to ablation first; without one itsreview_bymoves forward byreview_days, nothing else. - Ablation. Of the
appliedinstruction changes pastreview_bythat sunset did not pick, two
per run, the unmeasured ones first, then the oldest, go through the adapter's ablation command
(the change reverted in a bench copy, probes run); no difference → aremovecandidate
(source: ablation). No adapter or no ablation command → skip it and say so in one line. - Keys, the row a removal retires, and what a rejection moves:
${CLAUDE_PLUGIN_ROOT}/references/optimization-store.md§ Ledger row. Order them into the step-3
list with one evidence line each, confidence Medium.
5 · Decide
Per candidate, top down, until the user stops or the inbox is empty. Every decided candidate endsapplied or rejected; nothing is put off, because a put-off entry comes back every run.
Only what lasts goes to the user: a gate, a hook, a script, a deletion, a fix of a contradicted
repo fact, or instruction text that passes admission. Everything else isrejectedwith its
reason, unasked.Admission. A candidate that adds or rewords instruction text goes to the user only when all
four hold; otherwise it is rejected with the condition that failed:- it names the observed failure;
- the failure occurred at least twice (evidence lines), once in a high-damage area (money,
security, data loss), or it is a repository fact (a contradicted claim, a gate violation); - when the failure recurred while an instruction on the topic stood, the remedy is a gate, a
hook or a deletion, not a second wording
(${CLAUDE_PLUGIN_ROOT}/references/instruction-authoring.md§ What earns a line); a model-fit
rewrite of a line that did not fail is not such a case; - it states the expected effect, the metric that will show it, and the
review_bydate. The
adapter in.weside/optimization/measure/README.mdgives the before number, or without one
the recurrence metric (store reference § Measurement adapter); a correction
toward a contradicted repo fact uses the re-check of that fact as its metric. No metric →
reject.
A
removecandidate needs only the reason. A plugin skill is measured withclaude plugin eval
(or theskill-creatorplugin's evals); a skill nobody invokes shows up in/skill-doctor.Proposal. The exact lines (NEW or EDIT) against
${CLAUDE_PLUGIN_ROOT}/references/instruction-authoring.md,
the number of lines it adds to always-loaded context (rules withoutpaths:,AGENTS.md,CLAUDE.md), and the gate result after the edit.Batch the questions with
AskUserQuestion,multiSelect: true, two to four candidates per
call: the label names the change, the description its benefit in one sentence. Chosen → applied;
not chosen →rejected("not chosen"). Say so in the question.
6 · Apply
- This repo: edit in a worktree, run the gate
(python3 ${CLAUDE_PLUGIN_ROOT}/scripts/check-instruction-budget.py), commit per the repo's rules. - A sibling repo from
workspace: offer it; on yes,/we:sideload(editing mode) with the
approved proposal as the brief. - The plugin (
target_repo: plugin): with a local checkout, a native session there opens a PR,
audited via/doctor prompt-audit <path>, and the ledger row'safterwaits for the release.
Without a checkout, report the finding with its evidence; filing an upstream issue is the user's call.
7 · Write back
Before the turn ends, each fact once:
- every decided candidate → a
LEDGER.mdrow per the store's § Ledger row, and its inbox file
deleted in the same commit; - a new decision → replace the charter's line on that topic, old wording in parentheses
("replaces : …"); - a changed finding → replace its row; next steps updated;
last_optimize:set to today; - the charter stays within 200 lines.
Commit per ${CLAUDE_PLUGIN_ROOT}/references/optimization-store.md § Layout (where store commits land). Close with one line: candidates applied /
rejected, inbox left, the next step. Then offer each workspace repo whose inbox is not
empty.