From 5eeb32fe89b326b8ea5160d64d968075e49a60a8 Mon Sep 17 00:00:00 2001 From: Sal Date: Sat, 12 Sep 2026 12:35:04 +0100 Subject: [PATCH] refactor(skills): rename new-zsh-plugin to zsh-plugin Organization skill names split between domain nouns (code-review, gh-cli, github-issues, zunit-test) and verb-first names. With one skill per artifact type owning its whole lifecycle, domain nouns are the correct convention: a name is an address, and the description states the current contract. Rename the directory, the `skill-*` identifier, the frontmatter name, and every path reference in PATTERNS.md, the instruction manifest, the plugin-standard alias instructions, and the policy validators and tests. The skill body is unchanged and still scaffolds only, which its description continues to say. Growing it to cover repair and audit then needs no second rename. The frozen consumer-parser golden covers one of the renamed paths, so its digest is updated in the same commit as the change that moved it, per the guidance in that test. Refs #614 --- .github/instruction-surfaces.json | 6 +-- ...sh-plugin-standard-aliases.instructions.md | 2 +- .../{new-zsh-plugin => zsh-plugin}/SKILL.md | 2 +- .../templates/plugin.plugin.zsh | 0 PATTERNS.md | 6 +-- scripts/test_validate_agent_policy.py | 2 +- scripts/test_validate_zsh_standard_policy.py | 52 +++++++++---------- scripts/validate-zsh-standard-policy.py | 4 +- 8 files changed, 37 insertions(+), 37 deletions(-) rename .github/skills/{new-zsh-plugin => zsh-plugin}/SKILL.md (99%) rename .github/skills/{new-zsh-plugin => zsh-plugin}/templates/plugin.plugin.zsh (100%) diff --git a/.github/instruction-surfaces.json b/.github/instruction-surfaces.json index cfa00fad5..af68c5af4 100644 --- a/.github/instruction-surfaces.json +++ b/.github/instruction-surfaces.json @@ -247,7 +247,7 @@ "consumers": ["codex", "claude-code", "copilot", "gemini-cli", "human"], "tasks": ["code-review", "readme-authoring", "zsh-plugin-scaffolding"], "file_patterns": [ - "**/*.plugin.zsh,**/init.zsh,templates/readme/zsh-plugin.md,.github/skills/new-zsh-plugin/**,.github/agents/zsh-plugin-standard-reviewer.agent.md" + "**/*.plugin.zsh,**/init.zsh,templates/readme/zsh-plugin.md,.github/skills/zsh-plugin/**,.github/agents/zsh-plugin-standard-reviewer.agent.md" ], "required": true, "review_owner": "z-shell maintainers", @@ -370,8 +370,8 @@ "canonical_for": [] }, { - "id": "skill-new-zsh-plugin", - "path": ".github/skills/new-zsh-plugin/SKILL.md", + "id": "skill-zsh-plugin", + "path": ".github/skills/zsh-plugin/SKILL.md", "kind": "skill", "authority": "advisory", "consumers": ["copilot"], diff --git a/.github/instructions/zsh-plugin-standard-aliases.instructions.md b/.github/instructions/zsh-plugin-standard-aliases.instructions.md index 8bb511928..d4fed956f 100644 --- a/.github/instructions/zsh-plugin-standard-aliases.instructions.md +++ b/.github/instructions/zsh-plugin-standard-aliases.instructions.md @@ -1,6 +1,6 @@ --- description: "Route generic review and README tasks on plugin-shaped files to the canonical Zsh plugin guidance" -applyTo: "**/*.plugin.zsh,**/init.zsh,templates/readme/zsh-plugin.md,.github/skills/new-zsh-plugin/**,.github/agents/zsh-plugin-standard-reviewer.agent.md" +applyTo: "**/*.plugin.zsh,**/init.zsh,templates/readme/zsh-plugin.md,.github/skills/zsh-plugin/**,.github/agents/zsh-plugin-standard-reviewer.agent.md" --- # Zsh Plugin Standard Task Aliases diff --git a/.github/skills/new-zsh-plugin/SKILL.md b/.github/skills/zsh-plugin/SKILL.md similarity index 99% rename from .github/skills/new-zsh-plugin/SKILL.md rename to .github/skills/zsh-plugin/SKILL.md index 4a6cd4cbb..7cda00c81 100644 --- a/.github/skills/new-zsh-plugin/SKILL.md +++ b/.github/skills/zsh-plugin/SKILL.md @@ -1,5 +1,5 @@ --- -name: new-zsh-plugin +name: zsh-plugin description: Use when a user asks to create a new Zsh plugin, start a plugin from scratch, or add a plugin skeleton. disable-model-invocation: true --- diff --git a/.github/skills/new-zsh-plugin/templates/plugin.plugin.zsh b/.github/skills/zsh-plugin/templates/plugin.plugin.zsh similarity index 100% rename from .github/skills/new-zsh-plugin/templates/plugin.plugin.zsh rename to .github/skills/zsh-plugin/templates/plugin.plugin.zsh diff --git a/PATTERNS.md b/PATTERNS.md index f97224e8a..39f00486e 100644 --- a/PATTERNS.md +++ b/PATTERNS.md @@ -30,7 +30,7 @@ function name instead of the source file. New work must follow `.github/instructions/zsh-scripting.instructions.md` and start from -`.github/skills/new-zsh-plugin/templates/plugin.plugin.zsh`. No replacement is +`.github/skills/zsh-plugin/templates/plugin.plugin.zsh`. No replacement is published here because a safe replacement has not yet been observed in at least two listed repositories. @@ -53,7 +53,7 @@ exact pre-load value, so an unload function cannot restore that state. New work must follow `.github/instructions/zsh-scripting.instructions.md` and use -`.github/skills/new-zsh-plugin/templates/plugin.plugin.zsh`. This catalog does +`.github/skills/zsh-plugin/templates/plugin.plugin.zsh`. This catalog does not publish a replacement until the complete snapshot and restoration shape is observed in at least two listed repositories. @@ -78,7 +78,7 @@ derivation or lifecycle ownership safe. New work must follow `.github/instructions/zsh-scripting.instructions.md` and use -`.github/skills/new-zsh-plugin/templates/plugin.plugin.zsh`. This catalog does +`.github/skills/zsh-plugin/templates/plugin.plugin.zsh`. This catalog does not publish a replacement because the complete first-source ownership and unload-restoration shape has not been observed in at least two listed repositories. diff --git a/scripts/test_validate_agent_policy.py b/scripts/test_validate_agent_policy.py index b2ccd19a4..4b8f85fd7 100644 --- a/scripts/test_validate_agent_policy.py +++ b/scripts/test_validate_agent_policy.py @@ -1911,7 +1911,7 @@ def test_public_manifest_routes_zsh_plugin_standard(self) -> None: "file_patterns": [ "**/*.plugin.zsh,**/init.zsh," "templates/readme/zsh-plugin.md," - ".github/skills/new-zsh-plugin/**," + ".github/skills/zsh-plugin/**," ".github/agents/zsh-plugin-standard-reviewer.agent.md" ], "required": True, diff --git a/scripts/test_validate_zsh_standard_policy.py b/scripts/test_validate_zsh_standard_policy.py index 61a9bf7e9..f4680c18a 100644 --- a/scripts/test_validate_zsh_standard_policy.py +++ b/scripts/test_validate_zsh_standard_policy.py @@ -27,8 +27,8 @@ ) CONSUMER_PATHS = ( ".github/agents/zsh-plugin-standard-reviewer.agent.md", - ".github/skills/new-zsh-plugin/SKILL.md", - ".github/skills/new-zsh-plugin/templates/plugin.plugin.zsh", + ".github/skills/zsh-plugin/SKILL.md", + ".github/skills/zsh-plugin/templates/plugin.plugin.zsh", ".github/skills/zunit-test/SKILL.md", "PATTERNS.md", ".github/README.md", @@ -1559,7 +1559,7 @@ def test_rejects_hidden_consumer_canonical_references(self) -> None: ) reference_consumers = ( ".github/agents/zsh-plugin-standard-reviewer.agent.md", - ".github/skills/new-zsh-plugin/SKILL.md", + ".github/skills/zsh-plugin/SKILL.md", ".github/skills/zunit-test/SKILL.md", "PATTERNS.md", ".github/README.md", @@ -1611,7 +1611,7 @@ def test_rejects_hidden_consumer_canonical_references(self) -> None: def test_rejects_container_fenced_or_indented_canonical_references( self, ) -> None: - relative_path = ".github/skills/new-zsh-plugin/SKILL.md" + relative_path = ".github/skills/zsh-plugin/SKILL.md" canonical_paths = ( ".github/instructions/zsh-scripting.instructions.md", "lib/zsh-standard-policy.json", @@ -1714,7 +1714,7 @@ def test_rejects_coordinated_consumer_manifest_path_drift(self) -> None: ) def test_rejects_consumer_rule_definition_heading(self) -> None: - relative_path = ".github/skills/new-zsh-plugin/SKILL.md" + relative_path = ".github/skills/zsh-plugin/SKILL.md" cases = ( ("plain", "### zsh/options/localize"), ("backticked", "### `zsh/options/localize`"), @@ -1756,7 +1756,7 @@ def test_rejects_consumer_rule_definition_heading(self) -> None: self.assertEqual(errors, []) def test_rejects_valid_atx_h3_rule_heading_variants(self) -> None: - relative_path = ".github/skills/new-zsh-plugin/SKILL.md" + relative_path = ".github/skills/zsh-plugin/SKILL.md" visible_headings = ( " ### zsh/options/localize", "### zsh/options/localize ###", @@ -1835,7 +1835,7 @@ def test_rejects_valid_atx_h3_rule_heading_variants(self) -> None: def test_container_fences_hide_only_their_normative_h3_content( self, ) -> None: - relative_path = ".github/skills/new-zsh-plugin/SKILL.md" + relative_path = ".github/skills/zsh-plugin/SKILL.md" container_fences = ( ( "list", @@ -1922,7 +1922,7 @@ def test_visual_column_and_continuation_fences_reprocess_visible_h3( ) root = self.make_fixture() - relative_path = ".github/skills/new-zsh-plugin/SKILL.md" + relative_path = ".github/skills/zsh-plugin/SKILL.md" path = root / relative_path path.write_text( path.read_text(encoding="utf-8") + "\n" + source + "\n", @@ -1953,8 +1953,8 @@ def test_repair_2_consumer_parser_outputs_match_frozen_golden(self) -> None: paths = ( ".github/instructions/zsh-scripting.instructions.md", ".github/agents/zsh-plugin-standard-reviewer.agent.md", - ".github/skills/new-zsh-plugin/SKILL.md", - ".github/skills/new-zsh-plugin/templates/plugin.plugin.zsh", + ".github/skills/zsh-plugin/SKILL.md", + ".github/skills/zsh-plugin/templates/plugin.plugin.zsh", ".github/skills/zunit-test/SKILL.md", "PATTERNS.md", ".github/README.md", @@ -1991,7 +1991,7 @@ def test_repair_2_consumer_parser_outputs_match_frozen_golden(self) -> None: self.assertEqual( digest, - "a8d395e678f606f0fd0c1e2a72dc233e5c82ed31887e8d967fa31a62ab7790b7", + "37c72293a0126040e1a5cc071a0082badbf1d396667d3d7feeb82b35a2659dc4", msg=( "The frozen golden covers the parsed output of every path in " f"{paths}. Editing any of them changes this digest, which is " @@ -2003,7 +2003,7 @@ def test_repair_2_consumer_parser_outputs_match_frozen_golden(self) -> None: ) def test_rejects_list_and_nested_container_rule_headings(self) -> None: - relative_path = ".github/skills/new-zsh-plugin/SKILL.md" + relative_path = ".github/skills/zsh-plugin/SKILL.md" additions = ( "- ### zsh/options/localize", "- ### `zsh/options/localize`", @@ -2183,7 +2183,7 @@ def test_positive_markdown_state_distinguishes_indented_content( def test_visible_paragraph_and_blank_list_continuations_satisfy_references( self, ) -> None: - relative_path = ".github/skills/new-zsh-plugin/SKILL.md" + relative_path = ".github/skills/zsh-plugin/SKILL.md" cases = ( ( ".github/instructions/zsh-scripting.instructions.md", @@ -2277,7 +2277,7 @@ def test_rejects_indented_blockquote_paragraph_contradiction(self) -> None: def test_rejects_blockquoted_h3_and_invalid_backtick_fence_opener( self, ) -> None: - relative_path = ".github/skills/new-zsh-plugin/SKILL.md" + relative_path = ".github/skills/zsh-plugin/SKILL.md" additions = ( "> ### zsh/options/localize", "> ### `zsh/options/localize`", @@ -2304,7 +2304,7 @@ def test_rejects_blockquoted_h3_and_invalid_backtick_fence_opener( def test_code_span_normalization_keeps_doubled_edge_spaces(self) -> None: root = self.make_fixture() - relative_path = ".github/skills/new-zsh-plugin/SKILL.md" + relative_path = ".github/skills/zsh-plugin/SKILL.md" path = root / relative_path path.write_text( path.read_text(encoding="utf-8") + "\n### ` zsh/options/localize `\n", @@ -2488,7 +2488,7 @@ def test_list_owned_fence_preserves_visible_reference_continuations( def test_leaf_blocks_cannot_supply_structural_headings(self) -> None: rule_id = "zsh/options/localize" - consumer_path = ".github/skills/new-zsh-plugin/SKILL.md" + consumer_path = ".github/skills/zsh-plugin/SKILL.md" hidden_h3_blocks = ( f"
\n### `{rule_id}`\n
", f"", @@ -2671,7 +2671,7 @@ def test_rejects_copied_normative_rule_inventory(self) -> None: def test_rejects_nonconforming_plugin_template(self) -> None: root = self.make_fixture() - relative_path = ".github/skills/new-zsh-plugin/templates/plugin.plugin.zsh" + relative_path = ".github/skills/zsh-plugin/templates/plugin.plugin.zsh" path = root / relative_path path.write_text( path.read_text(encoding="utf-8") @@ -2888,8 +2888,8 @@ def test_rejects_retired_patterns_contract_mutations(self) -> None: ), ( "template-route", - ".github/skills/new-zsh-plugin/templates/plugin.plugin.zsh", - ".github/skills/new-zsh-plugin/templates/missing.plugin.zsh", + ".github/skills/zsh-plugin/templates/plugin.plugin.zsh", + ".github/skills/zsh-plugin/templates/missing.plugin.zsh", ), ( "instruction-route-suffix", @@ -2898,8 +2898,8 @@ def test_rejects_retired_patterns_contract_mutations(self) -> None: ), ( "template-route-suffix", - ".github/skills/new-zsh-plugin/templates/plugin.plugin.zsh", - ".github/skills/new-zsh-plugin/templates/plugin.plugin.zsh.bak", + ".github/skills/zsh-plugin/templates/plugin.plugin.zsh", + ".github/skills/zsh-plugin/templates/plugin.plugin.zsh.bak", ), ) + tuple( @@ -3471,7 +3471,7 @@ def test_rendered_plugin_template_restores_lifecycle_state(self) -> None: if zsh_path is None: self.fail("zsh is required for lifecycle tests") template_path = ( - PUBLIC_ROOT / ".github/skills/new-zsh-plugin/templates/plugin.plugin.zsh" + PUBLIC_ROOT / ".github/skills/zsh-plugin/templates/plugin.plugin.zsh" ) with tempfile.TemporaryDirectory() as temporary_directory: plugin_root = Path(temporary_directory) / "plugin [literal]*? space" @@ -3659,7 +3659,7 @@ def test_public_zsh_consumers_defer_to_canonical_standard(self) -> None: policy_path = "lib/zsh-standard-policy.json" consumers = ( ".github/agents/zsh-plugin-standard-reviewer.agent.md", - ".github/skills/new-zsh-plugin/SKILL.md", + ".github/skills/zsh-plugin/SKILL.md", ".github/skills/zunit-test/SKILL.md", "PATTERNS.md", ".github/README.md", @@ -3684,7 +3684,7 @@ def test_public_zsh_consumers_defer_to_canonical_standard(self) -> None: self.assertIn(fragment, reviewer) new_plugin_skill = ( - PUBLIC_ROOT / ".github/skills/new-zsh-plugin/SKILL.md" + PUBLIC_ROOT / ".github/skills/zsh-plugin/SKILL.md" ).read_text(encoding="utf-8") for fragment in ( "sourced-library", @@ -3710,7 +3710,7 @@ def test_public_zsh_consumers_defer_to_canonical_standard(self) -> None: self.assertIn(fragment, zunit_skill) template = ( - PUBLIC_ROOT / ".github/skills/new-zsh-plugin/templates/plugin.plugin.zsh" + PUBLIC_ROOT / ".github/skills/zsh-plugin/templates/plugin.plugin.zsh" ).read_text(encoding="utf-8") self.assertNotIn("TODO", template) self.assertNotIn("#funtions-directory", template) @@ -3776,7 +3776,7 @@ def test_patterns_retire_unsafe_zsh_lifecycle_snippets(self) -> None: retired_lifecycle = "\n".join(blocks) for fragment in ( ".github/instructions/zsh-scripting.instructions.md", - ".github/skills/new-zsh-plugin/templates/plugin.plugin.zsh", + ".github/skills/zsh-plugin/templates/plugin.plugin.zsh", "not publish a replacement", "zsh/sourced/preserve-caller-state", "zsh/plugin/exact-lifecycle", diff --git a/scripts/validate-zsh-standard-policy.py b/scripts/validate-zsh-standard-policy.py index c3b528f6d..510256057 100644 --- a/scripts/validate-zsh-standard-policy.py +++ b/scripts/validate-zsh-standard-policy.py @@ -23,14 +23,14 @@ VALIDATOR_PATH = "scripts/validate-zsh-standard-policy.py" ADVISORY_CONSUMER_PATHS = ( ".github/agents/zsh-plugin-standard-reviewer.agent.md", - ".github/skills/new-zsh-plugin/SKILL.md", + ".github/skills/zsh-plugin/SKILL.md", ".github/skills/zunit-test/SKILL.md", ) REFERENCE_CONSUMER_PATHS = ADVISORY_CONSUMER_PATHS + ( "PATTERNS.md", ".github/README.md", ) -PLUGIN_TEMPLATE_PATH = ".github/skills/new-zsh-plugin/templates/plugin.plugin.zsh" +PLUGIN_TEMPLATE_PATH = ".github/skills/zsh-plugin/templates/plugin.plugin.zsh" RETIRED_PATTERN_SECTIONS = { "Plugin entry-point skeleton": { "evidence": (