From bca70808d2e9bd0293604f5545f5a440f53eded9 Mon Sep 17 00:00:00 2001 From: hyoshi <4027404+hyoshi@users.noreply.github.com> Date: Sat, 16 May 2026 18:53:01 +0900 Subject: [PATCH] fix(skills): restore the /learn operational skill (regression from #77) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 3 plugin packaging (#77) migrated every .claude/commands/*.md slash command into an operational skill under skills/ and the bundled mureo/_data/skills/, EXCEPT it dropped `learn` entirely (deleted .claude/commands/learn.md, never created a learn skill). README/docs still document /learn, so /learn became uninvocable while every other command kept working. Restore it as an operational skill (skills/learn + bundled copy, byte-identical per the manifest parity test), ported from the deleted command and adapted to the current layout: - name: learn (no _ prefix — operational, surfaces in the picker) - PREREQUISITE + frontmatter match peer skills (daily-check/sync-state) - writes to ../_mureo-pro-diagnosis/SKILL.md (sibling install path); pro-diagnosis is intentionally canonical-only (not shipped, grows per account) so the skill scaffolds it on first use, keeping the _ foundation prefix - approval-required, append-only, no secrets/PII, never Claude memory Tests: EXPECTED_PACKAGED_SKILLS 15->16 + learn install assert (test_setup_cmd); learn added to _BUNDLE_NAMES (remove symmetry); stale in-tree-count comments de-numbered. Parser/discovery/matcher/ manifest-parity auto-cover the new SKILL.md. Test plan: - [x] full suite 3209 passed - [x] code-reviewer APPROVE (no CRITICAL/HIGH) - [x] byte-identical skills/learn vs mureo/_data/skills/learn --- mureo/_data/skills/learn/SKILL.md | 87 +++++++++++++++++++ skills/learn/SKILL.md | 87 +++++++++++++++++++ tests/core/skills/test_discovery.py | 4 +- .../core/skills/test_existing_skills_parse.py | 2 +- tests/test_cli_setup_cmd_remove.py | 1 + tests/test_setup_cmd.py | 3 +- 6 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 mureo/_data/skills/learn/SKILL.md create mode 100644 skills/learn/SKILL.md diff --git a/mureo/_data/skills/learn/SKILL.md b/mureo/_data/skills/learn/SKILL.md new file mode 100644 index 0000000..c97d20d --- /dev/null +++ b/mureo/_data/skills/learn/SKILL.md @@ -0,0 +1,87 @@ +--- +name: learn +description: "Save a marketing diagnosis insight to the pro-diagnosis knowledge base so it is applied in future operations across all platforms. Use when the user runs /learn, explicitly teaches the agent a marketing insight, corrects the agent's analysis, or asks to remember/record an operational learning for next time." +metadata: + version: 0.7.1 +--- + +# Learn + +> PREREQUISITE: Read `../_mureo-shared/SKILL.md` for auth, security rules, output format, and **Tool Selection** (Read/Write on Code, `mureo_strategy_*` / `mureo_state_*` MCP on Desktop / Cowork). + +Save a marketing diagnosis insight to the pro-diagnosis knowledge base +(`../_mureo-pro-diagnosis/SKILL.md`). Saved insights are loaded at the +start of future sessions and applied across `/daily-check`, `/rescue`, +`/budget-rebalance`, and the other diagnostic workflows. + +## When to use + +- The user runs `/learn` followed by an insight, e.g.: + - `/learn CV少ないサイトではマイクロCVを活用すべき` + - `/learn 予算5000円/日で広告グループ8個は多すぎる` + - `/learn Target CPA を下げすぎると逆に CV が減る` +- The user runs `/learn` with no argument — review the current + conversation for corrections or marketing expertise the user shared + and propose those as insights. + +## Steps + +1. **Identify the insight.** If the user passed an insight as the + argument, use it. Otherwise review the current conversation for + moments where the user corrected the agent's analysis or supplied + marketing expertise, and select the most reusable one(s). + +2. **Locate the knowledge base.** The target is the sibling skill file + `../_mureo-pro-diagnosis/SKILL.md` (relative to this skill, i.e. + `~/.claude/skills/_mureo-pro-diagnosis/SKILL.md` for an installed + user). If it already exists, read it first to avoid duplicate or + conflicting entries. If it does **not** exist (it is not shipped — it + grows per account), create the directory and seed the file with this + minimal scaffold before appending: + + ```markdown + --- + name: _mureo-pro-diagnosis + description: "Professional marketing diagnostic frameworks: expert-level campaign analysis that grows with your experience." + metadata: + version: 0.1.0 + --- + + # Pro Diagnosis — Account Knowledge Base + + Insights learned from operating this account, applied by every mureo + diagnostic workflow. + + ## Learned Insights + ``` + +3. **Structure the insight** using this template: + + ```markdown + ### [Short descriptive title] + + **Situation:** [When this insight applies] + **Wrong assumption:** [What an inexperienced agent might think] + **Correct approach:** [The right way to handle this situation] + **Why:** [The reasoning behind the correct approach] + + Date learned: YYYY-MM-DD + ``` + +4. **Present for approval.** Show the formatted insight to the user and + ask for explicit confirmation before writing anything. Capture the + generalized lesson only — never record account IDs, credentials, + access tokens, or personal data in the knowledge base. + +5. **Save.** Append the approved insight under the `## Learned Insights` + section of `../_mureo-pro-diagnosis/SKILL.md` (creating the file from + the scaffold in step 2 first if it was absent). Append only — never + rewrite or reorder existing entries. + +6. **Confirm.** Tell the user the insight was saved and that it will be + applied in future `/daily-check`, `/rescue`, `/budget-rebalance`, and + other diagnostic workflows. + +IMPORTANT: Always save to `../_mureo-pro-diagnosis/SKILL.md`, never to +Claude Code memory. The skill file persists across sessions and is read +by all mureo diagnostic workflows; Claude memory is not. diff --git a/skills/learn/SKILL.md b/skills/learn/SKILL.md new file mode 100644 index 0000000..c97d20d --- /dev/null +++ b/skills/learn/SKILL.md @@ -0,0 +1,87 @@ +--- +name: learn +description: "Save a marketing diagnosis insight to the pro-diagnosis knowledge base so it is applied in future operations across all platforms. Use when the user runs /learn, explicitly teaches the agent a marketing insight, corrects the agent's analysis, or asks to remember/record an operational learning for next time." +metadata: + version: 0.7.1 +--- + +# Learn + +> PREREQUISITE: Read `../_mureo-shared/SKILL.md` for auth, security rules, output format, and **Tool Selection** (Read/Write on Code, `mureo_strategy_*` / `mureo_state_*` MCP on Desktop / Cowork). + +Save a marketing diagnosis insight to the pro-diagnosis knowledge base +(`../_mureo-pro-diagnosis/SKILL.md`). Saved insights are loaded at the +start of future sessions and applied across `/daily-check`, `/rescue`, +`/budget-rebalance`, and the other diagnostic workflows. + +## When to use + +- The user runs `/learn` followed by an insight, e.g.: + - `/learn CV少ないサイトではマイクロCVを活用すべき` + - `/learn 予算5000円/日で広告グループ8個は多すぎる` + - `/learn Target CPA を下げすぎると逆に CV が減る` +- The user runs `/learn` with no argument — review the current + conversation for corrections or marketing expertise the user shared + and propose those as insights. + +## Steps + +1. **Identify the insight.** If the user passed an insight as the + argument, use it. Otherwise review the current conversation for + moments where the user corrected the agent's analysis or supplied + marketing expertise, and select the most reusable one(s). + +2. **Locate the knowledge base.** The target is the sibling skill file + `../_mureo-pro-diagnosis/SKILL.md` (relative to this skill, i.e. + `~/.claude/skills/_mureo-pro-diagnosis/SKILL.md` for an installed + user). If it already exists, read it first to avoid duplicate or + conflicting entries. If it does **not** exist (it is not shipped — it + grows per account), create the directory and seed the file with this + minimal scaffold before appending: + + ```markdown + --- + name: _mureo-pro-diagnosis + description: "Professional marketing diagnostic frameworks: expert-level campaign analysis that grows with your experience." + metadata: + version: 0.1.0 + --- + + # Pro Diagnosis — Account Knowledge Base + + Insights learned from operating this account, applied by every mureo + diagnostic workflow. + + ## Learned Insights + ``` + +3. **Structure the insight** using this template: + + ```markdown + ### [Short descriptive title] + + **Situation:** [When this insight applies] + **Wrong assumption:** [What an inexperienced agent might think] + **Correct approach:** [The right way to handle this situation] + **Why:** [The reasoning behind the correct approach] + + Date learned: YYYY-MM-DD + ``` + +4. **Present for approval.** Show the formatted insight to the user and + ask for explicit confirmation before writing anything. Capture the + generalized lesson only — never record account IDs, credentials, + access tokens, or personal data in the knowledge base. + +5. **Save.** Append the approved insight under the `## Learned Insights` + section of `../_mureo-pro-diagnosis/SKILL.md` (creating the file from + the scaffold in step 2 first if it was absent). Append only — never + rewrite or reorder existing entries. + +6. **Confirm.** Tell the user the insight was saved and that it will be + applied in future `/daily-check`, `/rescue`, `/budget-rebalance`, and + other diagnostic workflows. + +IMPORTANT: Always save to `../_mureo-pro-diagnosis/SKILL.md`, never to +Claude Code memory. The skill file persists across sessions and is read +by all mureo diagnostic workflows; Claude memory is not. diff --git a/tests/core/skills/test_discovery.py b/tests/core/skills/test_discovery.py index c82498a..c75306c 100644 --- a/tests/core/skills/test_discovery.py +++ b/tests/core/skills/test_discovery.py @@ -106,7 +106,7 @@ def _reset_discovery_cache() -> Any: # --------------------------------------------------------------------------- -# Case 1 — built-in scan finds the 16 in-tree skills (integration) +# Case 1 — built-in scan finds the in-tree skills (integration) # --------------------------------------------------------------------------- @@ -129,7 +129,7 @@ def _no_entry_points(group: str) -> tuple[Any, ...]: assert len(entries) >= 1, "built-in scan must yield at least one skill" names = {e.name for e in entries} - # daily-check is one of the 16 known built-ins. + # daily-check is one of the known built-ins. assert "daily-check" in names, f"expected daily-check among built-ins; got {names}" diff --git a/tests/core/skills/test_existing_skills_parse.py b/tests/core/skills/test_existing_skills_parse.py index f96e0b5..ca2d547 100644 --- a/tests/core/skills/test_existing_skills_parse.py +++ b/tests/core/skills/test_existing_skills_parse.py @@ -2,7 +2,7 @@ These tests guard the contract that the parser (P1-08) accepts every SKILL.md currently shipped at the repository root under ``skills/``. -None of the 16 in-tree files declare a ``capabilities`` block in +None of the in-tree files declare a ``capabilities`` block in Phase 1, so every parsed entry must report empty capability frozensets. This sentinel catches accidental drift if someone adds ``capabilities`` without going through the dedicated migration PR (planner tracks this diff --git a/tests/test_cli_setup_cmd_remove.py b/tests/test_cli_setup_cmd_remove.py index 2e8a749..be89403 100644 --- a/tests/test_cli_setup_cmd_remove.py +++ b/tests/test_cli_setup_cmd_remove.py @@ -51,6 +51,7 @@ def _make_skill_dir(parent: Path, name: str, content: str = "skill body") -> Pat "creative-refresh", "daily-check", "goal-review", + "learn", "onboard", "rescue", "search-term-cleanup", diff --git a/tests/test_setup_cmd.py b/tests/test_setup_cmd.py index dba3801..e44ca2a 100644 --- a/tests/test_setup_cmd.py +++ b/tests/test_setup_cmd.py @@ -21,7 +21,7 @@ # Number of skills shipped in mureo/_data/skills/. Update this constant # whenever a skill is added or removed from the packaged set. -EXPECTED_PACKAGED_SKILLS = 15 +EXPECTED_PACKAGED_SKILLS = 16 @pytest.mark.unit @@ -40,6 +40,7 @@ def test_install_skills(tmp_path: Path) -> None: assert dest == tmp_path / "skills" # Operational skills (formerly slash commands) assert (dest / "daily-check" / "SKILL.md").exists() + assert (dest / "learn" / "SKILL.md").exists() assert (dest / "onboard" / "SKILL.md").exists() assert (dest / "rescue" / "SKILL.md").exists() # Foundation skills (referenced as PREREQUISITE by the operational ones)