From 9f0a6852174c2efcb5478e35d8fc5359fe33cc01 Mon Sep 17 00:00:00 2001 From: Nathaniel Ramm Date: Tue, 28 Apr 2026 20:09:03 +1000 Subject: [PATCH 01/10] docs: add design spec for hook archetype gating Hooks and using-skill are only for always-present plugins. On-demand plugins (like plugin-portability) skip Phase 8 entirely. Includes using-skill template modelled on superpowers. Co-Authored-By: Claude Opus 4.6 (1M context) --- ...2026-04-28-hook-archetype-gating-design.md | 239 ++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-28-hook-archetype-gating-design.md diff --git a/docs/superpowers/specs/2026-04-28-hook-archetype-gating-design.md b/docs/superpowers/specs/2026-04-28-hook-archetype-gating-design.md new file mode 100644 index 0000000..0e2bd70 --- /dev/null +++ b/docs/superpowers/specs/2026-04-28-hook-archetype-gating-design.md @@ -0,0 +1,239 @@ +# Hook & Using-Skill Archetype Gating — Design Spec + +**Date:** 2026-04-28 +**Status:** Approved + +## Problem + +The plugin currently generates session-start hooks and a `using-plugin-portability` skill that get force-injected on every session start. Research confirms that hooks are NOT required for plugin/skill discovery on any platform — all 6 platforms use directory-based auto-discovery. Hooks are purely a "front-of-mind" context injection strategy. + +This strategy makes sense for always-present plugins like superpowers (which govern workflow discipline and must intercept every interaction) but wastes context budget for on-demand plugins like plugin-portability (which are only relevant when explicitly invoked). + +The current `using-plugin-portability` skill is a passive menu card that adds nothing beyond what auto-discovery already provides. Compare with superpowers' `using-superpowers`, which is an aggressive behaviour modifier with `` directives, rationalization red flags, and decision flow graphs. + +## Solution + +Four changes: + +1. **Remove hooks and using-skill from this repo** — plugin-portability is on-demand +2. **Add archetype gating to the skill** — always-present vs on-demand, controls whether Phase 8 (Bootstrap) runs +3. **Create a using-skill template** — modelled on superpowers, for always-present plugins only +4. **Update patterns and references** — bootstrapping, injection-checks, adding-a-platform guide + +## Part 1: Cleanup This Repo + +### Delete + +| Path | Reason | +|------|--------| +| `skills/using-plugin-portability/` (directory) | On-demand plugin; no context injection needed | +| `hooks/hooks.json` | No session-start hook needed | +| `hooks/hooks-cursor.json` | No session-start hook needed | +| `hooks/session-start` | The injection script | +| `hooks/run-hook.cmd` | Windows wrapper | + +The `hooks/` directory is removed entirely. + +### Modify + +| File | Change | +|------|--------| +| `GEMINI.md` | Remove `@./skills/using-plugin-portability/SKILL.md` include | +| `.github/workflows/ci.yml` | Remove or conditionalize the `hooks/session-start` executable check | + +## Part 2: Archetype Gating in the Skill + +### New question in intent-gathering (Phase 1) + +Added after the platforms question (Q2), before any assessment/uplift work begins: + +```pseudocode +archetype = AskUserQuestion( + question: "What is this plugin's invocation pattern?", + header: "Archetype", + options: [ + { label: "On-demand", + description: "Called explicitly when the user needs it (e.g., portability tools, code generators)" }, + { label: "Always-present", + description: "Governs workflows on every session — needs context injection (e.g., superpowers, single-purpose agents)" } + ], + multiSelect: false +) +``` + +The answer is carried as `intent.archetype` alongside `intent.mode` and `intent.platforms`. + +### Phase 8 (Bootstrap) gating + +```pseudocode +BOOTSTRAP(computed, intent): + IF computed.uplift_target == "curated-note-only": SKIP + IF intent.archetype == "on-demand": SKIP + + LOAD_AND_VERIFY("lib/patterns/bootstrapping.md", + proof: content contains steps 4.1 through 4.8) + + # Execute bootstrapping as defined in bootstrapping.md +``` + +On-demand plugins skip Phase 8 entirely. No using-skill, no hooks, no GEMINI.md injection. + +### Assessment impact + +When `intent.archetype == "on-demand"`, the assessment report should note: "Bootstrapping: skipped (on-demand plugin — hooks and using-skill not applicable)." + +When `intent.archetype == "always-present"`, the existing Phase 8 flow runs as before, but uses the new template (Part 3). + +## Part 3: Using-Skill Template + +### File + +Create: `lib/templates/context-files/using-skill.md.tmpl` + +### Content model + +Modelled on superpowers' `using-superpowers` skill. Fixed structural text (aggressive framing) with `{{mustache}}` variables for plugin-specific content. + +### Variables + +| Variable | Source | Example | +|----------|--------|---------| +| `{{name}}` | Plugin name | `my-plugin` | +| `{{usingSkillDescription}}` | Generated from plugin purpose | `Use when starting any conversation — establishes how to find and use skills...` | +| `{{skillTable}}` | Built from discovered skills | Markdown table of skill names and descriptions | + +### Template structure + +``` +--- +name: using-{{name}} +description: {{usingSkillDescription}} +--- + + +If you were dispatched as a subagent to execute a specific task, skip this skill. + + + +If you think there is even a 1% chance a skill might apply to what you are +doing, you ABSOLUTELY MUST invoke the skill. + +IF A SKILL APPLIES TO YOUR TASK, YOU DO NOT HAVE A CHOICE. YOU MUST USE IT. + +This is not negotiable. This is not optional. You cannot rationalize your way +out of this. + + +## Instruction Priority + +{{name}} skills override default system prompt behavior, but **user +instructions always take precedence**: + +1. **User's explicit instructions** (CLAUDE.md, GEMINI.md, AGENTS.md, direct + requests) — highest priority +2. **{{name}} skills** — override default system behavior where they conflict +3. **Default system prompt** — lowest priority + +## How to Access Skills + +**In Claude Code:** Use the `Skill` tool. + +**In Cursor:** Use the `Skill` tool. + +**In Gemini CLI:** Skills activate via the `activate_skill` tool. + +**In other environments:** Check your platform's documentation for how skills +are loaded. + +## Platform Adaptation + +Skills use Claude Code tool names. Non-CC platforms: see `lib/references/` +for platform-specific tool equivalents. + +# Using Skills + +## The Rule + +**Invoke relevant or requested skills BEFORE any response or action.** Even a +1% chance a skill might apply means you should invoke the skill to check. If +an invoked skill turns out to be wrong for the situation, you don't need to +use it. + +## Available Skills + +{{skillTable}} + +## Red Flags + +These thoughts mean STOP — you're rationalizing: + +| Thought | Reality | +|---------|---------| +| "This is just a simple question" | Questions are tasks. Check for skills. | +| "I need more context first" | Skill check comes BEFORE clarifying questions. | +| "Let me explore the codebase first" | Skills tell you HOW to explore. Check first. | +| "This doesn't need a formal skill" | If a skill exists, use it. | +| "I remember this skill" | Skills evolve. Read current version. | +| "The skill is overkill" | Simple things become complex. Use it. | +| "I'll just do this one thing first" | Check BEFORE doing anything. | + +## Skill Types + +**Rigid** (TDD, debugging): Follow exactly. Don't adapt away discipline. + +**Flexible** (patterns): Adapt principles to context. + +The skill itself tells you which. + +## User Instructions + +Instructions say WHAT, not HOW. "Add X" or "Fix Y" doesn't mean skip +workflows. +``` + +### Why this wording + +This template is ONLY used for always-present plugins. The aggressive framing is the point — it ensures the agent treats the plugin's skills as mandatory workflow gates, not optional suggestions. On-demand plugins never see this template because the archetype gate prevents Phase 8 from running. + +## Part 4: Pattern and Reference Updates + +### `lib/patterns/bootstrapping.md` + +- Add archetype check at the top of Step 4.1: `IF intent.archetype == "on-demand": SKIP` with explanation +- Add prose section explaining when bootstrapping is valuable vs unnecessary +- Update Step 4.2 to reference the template at `lib/templates/context-files/using-skill.md.tmpl` instead of inline content + +### `lib/patterns/injection-checks.md` + +- Add note at top: 8-component verification only applies to always-present plugins; on-demand plugins skip injection checks entirely + +### `lib/references/templates/registry.md` + +- Add entry for `using-skill.md.tmpl`: `{ schema: "using-skill", platform: "all", mode: "builder", template_path: "lib/templates/context-files/using-skill.md.tmpl", target_path: "skills/using-{{name}}/SKILL.md" }` + +### `lib/principles/adding-a-platform.md` + +- Update Phase 7 notes to mention hooks and using-skill are only generated for always-present archetype + +### `docs/reconciliation-matrix.md` + +- Update bootstrapping section to reflect archetype-conditional model + +## File Impact Summary + +| Action | File | +|--------|------| +| Delete | `skills/using-plugin-portability/` | +| Delete | `hooks/hooks.json` | +| Delete | `hooks/hooks-cursor.json` | +| Delete | `hooks/session-start` | +| Delete | `hooks/run-hook.cmd` | +| Create | `lib/templates/context-files/using-skill.md.tmpl` | +| Modify | `skills/plugin-portability/SKILL.md` (archetype question + Phase 8 gate) | +| Modify | `lib/patterns/bootstrapping.md` (archetype gate + template reference) | +| Modify | `lib/patterns/injection-checks.md` (archetype note) | +| Modify | `lib/references/templates/registry.md` (new entry) | +| Modify | `lib/principles/adding-a-platform.md` (archetype note) | +| Modify | `docs/reconciliation-matrix.md` (archetype update) | +| Modify | `GEMINI.md` (remove using-skill include) | +| Modify | `.github/workflows/ci.yml` (conditionalize hooks check) | From 949f98a1757d534f063d578b725ace5dd2e6ee7a Mon Sep 17 00:00:00 2001 From: Nathaniel Ramm Date: Tue, 28 Apr 2026 20:36:52 +1000 Subject: [PATCH 02/10] ci: remove hooks/session-start check (on-demand plugin has no hooks) Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/ci.yml | 9 ----- hooks/hooks-cursor.json | 7 ---- hooks/hooks.json | 10 ------ hooks/run-hook.cmd | 46 ------------------------ hooks/session-start | 39 -------------------- skills/using-plugin-portability/SKILL.md | 24 ------------- 6 files changed, 135 deletions(-) delete mode 100644 hooks/hooks-cursor.json delete mode 100644 hooks/hooks.json delete mode 100755 hooks/run-hook.cmd delete mode 100755 hooks/session-start delete mode 100644 skills/using-plugin-portability/SKILL.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8417ce4..bc0d1fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,15 +103,6 @@ jobs: echo "OK: all versions match ($v_pkg)" fi - echo "" - echo "=== Session-Start Hook ===" - if [ ! -x hooks/session-start ]; then - echo "FAIL: hooks/session-start does not exist or is not executable" - errors=$((errors + 1)) - else - echo "OK: hooks/session-start (executable)" - fi - echo "" if [ "$errors" -gt 0 ]; then echo "FAILED: $errors error(s) found" diff --git a/hooks/hooks-cursor.json b/hooks/hooks-cursor.json deleted file mode 100644 index d2794dc..0000000 --- a/hooks/hooks-cursor.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "hooks": { - "sessionStart": [ - { "command": "hooks/run-hook.cmd session-start" } - ] - } -} diff --git a/hooks/hooks.json b/hooks/hooks.json deleted file mode 100644 index 806f200..0000000 --- a/hooks/hooks.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "hooks": { - "SessionStart": [ - { - "command": "hooks/run-hook.cmd session-start", - "matcher": "startup|clear|compact" - } - ] - } -} diff --git a/hooks/run-hook.cmd b/hooks/run-hook.cmd deleted file mode 100755 index ceec3a7..0000000 --- a/hooks/run-hook.cmd +++ /dev/null @@ -1,46 +0,0 @@ -: << 'CMDBLOCK' -@echo off -REM Cross-platform polyglot wrapper for hook scripts. -REM On Windows: cmd.exe runs the batch portion, which finds and calls bash. -REM On Unix: the shell interprets this as a script (: is a no-op in bash). -REM -REM Hook scripts use extensionless filenames (e.g. "session-start" not -REM "session-start.sh") so Claude Code's Windows auto-detection -- which -REM prepends "bash" to any command containing .sh -- doesn't interfere. -REM -REM Usage: run-hook.cmd [args...] - -if "%~1"=="" ( - echo run-hook.cmd: missing script name >&2 - exit /b 1 -) - -set "HOOK_DIR=%~dp0" - -REM Try Git for Windows bash in standard locations -if exist "C:\Program Files\Git\bin\bash.exe" ( - "C:\Program Files\Git\bin\bash.exe" "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9 - exit /b %ERRORLEVEL% -) -if exist "C:\Program Files (x86)\Git\bin\bash.exe" ( - "C:\Program Files (x86)\Git\bin\bash.exe" "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9 - exit /b %ERRORLEVEL% -) - -REM Try bash on PATH (e.g. user-installed Git Bash, MSYS2, Cygwin) -where bash >nul 2>nul -if %ERRORLEVEL% equ 0 ( - bash "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9 - exit /b %ERRORLEVEL% -) - -REM No bash found - exit silently rather than error -REM (plugin still works, just without SessionStart context injection) -exit /b 0 -CMDBLOCK - -# Unix: run the named script directly -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -SCRIPT_NAME="$1" -shift -exec bash "${SCRIPT_DIR}/${SCRIPT_NAME}" "$@" diff --git a/hooks/session-start b/hooks/session-start deleted file mode 100755 index b213bc8..0000000 --- a/hooks/session-start +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -# SessionStart hook for plugin-portability plugin - -set -euo pipefail - -# Determine plugin root directory -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -PLUGIN_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" - -# Read using-plugin-portability content -using_content=$(cat "${PLUGIN_ROOT}/skills/using-plugin-portability/SKILL.md" 2>&1 || echo "Error reading using-plugin-portability skill") - -# Escape string for JSON embedding -escape_for_json() { - local s="$1" - s="${s//\\/\\\\}" - s="${s//\"/\\\"}" - s="${s//$'\n'/\\n}" - s="${s//$'\r'/\\r}" - s="${s//$'\t'/\\t}" - printf '%s' "$s" -} - -using_escaped=$(escape_for_json "$using_content") -session_context="\nThis plugin uses the superpowers portability pattern.\n\n${using_escaped}\n" - -# Output context injection as JSON. -# Cursor hooks expect additional_context (snake_case). -# Claude Code hooks expect hookSpecificOutput.additionalContext (nested). -# Copilot CLI and others expect additionalContext (top-level, SDK standard). -if [ -n "${CURSOR_PLUGIN_ROOT:-}" ]; then - printf '{\n "additional_context": "%s"\n}\n' "$session_context" -elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -z "${COPILOT_CLI:-}" ]; then - printf '{\n "hookSpecificOutput": {\n "hookEventName": "SessionStart",\n "additionalContext": "%s"\n }\n}\n' "$session_context" -else - printf '{\n "additionalContext": "%s"\n}\n' "$session_context" -fi - -exit 0 diff --git a/skills/using-plugin-portability/SKILL.md b/skills/using-plugin-portability/SKILL.md deleted file mode 100644 index 94471f1..0000000 --- a/skills/using-plugin-portability/SKILL.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: using-plugin-portability -description: Use when starting a session with the plugin-portability plugin. Session-start bootstrapping that lists available skills and platform-specific invocation instructions. ---- - -# Using Plugin Portability - -This plugin provides the following skills: - -| Skill | Description | -| ----- | ----------- | -| `plugin-portability` | Assess or uplift a plugin for multi-platform portability. Asks intent upfront (assess/uplift, platforms, uplift target), runs condition-driven scoring, and optionally generates missing artifacts. Platforms: Claude Code, Cursor, Gemini CLI, Codex, Antigravity, OpenClaw. | - -## How to Invoke - -**Claude Code / Cursor:** Use the `Skill` tool with skill name `plugin-portability`. - -**Gemini CLI:** Use the `activate_skill` tool with skill name `plugin-portability`. - -**Antigravity / OpenClaw / Codex:** Skills are auto-discovered. Follow the SKILL.md instructions directly. - -## Tool Name Mapping - -Skills use Claude Code tool names. See `lib/references/` for platform-specific equivalents. From 5204371b2c3f888ea08321fe42ee268815042eae Mon Sep 17 00:00:00 2001 From: Nathaniel Ramm Date: Tue, 28 Apr 2026 20:36:53 +1000 Subject: [PATCH 03/10] feat: remove hooks and using-skill from on-demand plugin Co-Authored-By: Claude Sonnet 4.6 --- GEMINI.md | 1 - 1 file changed, 1 deletion(-) diff --git a/GEMINI.md b/GEMINI.md index c4c3fbd..4d7a507 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -4,7 +4,6 @@ Make any plugin fully portable across all platforms. Accepts Claude Code, Cursor ## Skills -@./skills/using-plugin-portability/SKILL.md @./skills/plugin-portability/SKILL.md ## Platform API From 1c14e9401c8d5287b7ffb9d392e4015e7d14bbea Mon Sep 17 00:00:00 2001 From: Nathaniel Ramm Date: Tue, 28 Apr 2026 20:38:24 +1000 Subject: [PATCH 04/10] feat: add archetype question and Phase 8 gate for on-demand plugins Co-Authored-By: Claude Sonnet 4.6 --- skills/plugin-portability/SKILL.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/skills/plugin-portability/SKILL.md b/skills/plugin-portability/SKILL.md index 45352c1..deadfa0 100644 --- a/skills/plugin-portability/SKILL.md +++ b/skills/plugin-portability/SKILL.md @@ -112,7 +112,18 @@ INTENT_UPFRONT(): ELSE: platforms = ["claude-code", "cursor", "gemini-cli", "codex", "antigravity", "openclaw"] - RETURN { mode, platforms } + # Q3: Archetype + archetype = AskUserQuestion( + question: "What is this plugin's invocation pattern?", + header: "Archetype", + options: [ + { label: "On-demand", description: "Called explicitly when the user needs it (e.g., portability tools, code generators)" }, + { label: "Always-present", description: "Governs workflows on every session — needs context injection (e.g., superpowers, single-purpose agents)" } + ], + multiSelect: false + ) + + RETURN { mode, platforms, archetype } ``` --- @@ -344,6 +355,9 @@ Always runs (`"6_install"` is in all allowed sets). ```pseudocode BOOTSTRAP(computed, intent): IF computed.uplift_target == "curated-note-only": SKIP + IF intent.archetype == "on-demand": + REPORT "Bootstrapping: skipped (on-demand plugin — hooks and using-skill not applicable)" + SKIP LOAD_AND_VERIFY("lib/patterns/bootstrapping.md", proof: content contains steps 4.1 through 4.8) From 96ba6b5165ca5967cf32d40c5e244659880f3639 Mon Sep 17 00:00:00 2001 From: Nathaniel Ramm Date: Tue, 28 Apr 2026 20:38:44 +1000 Subject: [PATCH 05/10] feat: add using-skill template modelled on superpowers Co-Authored-By: Claude Sonnet 4.6 --- .../context-files/using-skill.md.tmpl | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 lib/templates/context-files/using-skill.md.tmpl diff --git a/lib/templates/context-files/using-skill.md.tmpl b/lib/templates/context-files/using-skill.md.tmpl new file mode 100644 index 0000000..f43c3c9 --- /dev/null +++ b/lib/templates/context-files/using-skill.md.tmpl @@ -0,0 +1,85 @@ +{{! fixes: bootstrap.using_skill }} +--- +name: using-{{name}} +description: {{usingSkillDescription}} +--- + + +If you were dispatched as a subagent to execute a specific task, skip this skill. + + + +If you think there is even a 1% chance a skill might apply to what you are +doing, you ABSOLUTELY MUST invoke the skill. + +IF A SKILL APPLIES TO YOUR TASK, YOU DO NOT HAVE A CHOICE. YOU MUST USE IT. + +This is not negotiable. This is not optional. You cannot rationalize your way +out of this. + + +## Instruction Priority + +{{name}} skills override default system prompt behavior, but **user +instructions always take precedence**: + +1. **User's explicit instructions** (CLAUDE.md, GEMINI.md, AGENTS.md, direct + requests) — highest priority +2. **{{name}} skills** — override default system behavior where they conflict +3. **Default system prompt** — lowest priority + +## How to Access Skills + +**In Claude Code:** Use the `Skill` tool. + +**In Cursor:** Use the `Skill` tool. + +**In Gemini CLI:** Skills activate via the `activate_skill` tool. + +**In other environments:** Check your platform's documentation for how skills +are loaded. + +## Platform Adaptation + +Skills use Claude Code tool names. Non-CC platforms: see `lib/references/` +for platform-specific tool equivalents. + +# Using Skills + +## The Rule + +**Invoke relevant or requested skills BEFORE any response or action.** Even a +1% chance a skill might apply means you should invoke the skill to check. If +an invoked skill turns out to be wrong for the situation, you don't need to +use it. + +## Available Skills + +{{skillTable}} + +## Red Flags + +These thoughts mean STOP — you're rationalizing: + +| Thought | Reality | +|---------|---------| +| "This is just a simple question" | Questions are tasks. Check for skills. | +| "I need more context first" | Skill check comes BEFORE clarifying questions. | +| "Let me explore the codebase first" | Skills tell you HOW to explore. Check first. | +| "This doesn't need a formal skill" | If a skill exists, use it. | +| "I remember this skill" | Skills evolve. Read current version. | +| "The skill is overkill" | Simple things become complex. Use it. | +| "I'll just do this one thing first" | Check BEFORE doing anything. | + +## Skill Types + +**Rigid** (TDD, debugging): Follow exactly. Don't adapt away discipline. + +**Flexible** (patterns): Adapt principles to context. + +The skill itself tells you which. + +## User Instructions + +Instructions say WHAT, not HOW. "Add X" or "Fix Y" doesn't mean skip +workflows. From 87e253b97e36b4ff2cc732f50ef86ad5cf87edc4 Mon Sep 17 00:00:00 2001 From: Nathaniel Ramm Date: Tue, 28 Apr 2026 20:39:53 +1000 Subject: [PATCH 06/10] feat: add using-skill template to registry --- lib/references/templates/registry.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/references/templates/registry.md b/lib/references/templates/registry.md index 6a913af..f4641a1 100644 --- a/lib/references/templates/registry.md +++ b/lib/references/templates/registry.md @@ -70,6 +70,10 @@ TEMPLATE_REGISTRY: List[TemplateEntry] = [ { schema: "openclaw-plugin", platform: "openclaw", mode: "plain", template_path: "lib/templates/manifests/openclaw/openclaw.plugin.json.tmpl", target_path: "openclaw.plugin.json" }, + + { schema: "using-skill", platform: "all", mode: "builder", + template_path: "lib/templates/context-files/using-skill.md.tmpl", + target_path: "skills/using-{{name}}/SKILL.md" }, ] ``` From d052d142f2b62385219383816ca016a43b924357 Mon Sep 17 00:00:00 2001 From: Nathaniel Ramm Date: Tue, 28 Apr 2026 20:40:11 +1000 Subject: [PATCH 07/10] docs: update guide and matrix for archetype-conditional bootstrapping --- docs/reconciliation-matrix.md | 1 + lib/principles/adding-a-platform.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/reconciliation-matrix.md b/docs/reconciliation-matrix.md index 3132fcc..490d78c 100644 --- a/docs/reconciliation-matrix.md +++ b/docs/reconciliation-matrix.md @@ -190,6 +190,7 @@ Track every platform-specific claim in the plugin against researched facts in | Claim | Current | Research says | Status | |-------|---------|---------------|--------| | Session-start per platform | Documented | Cursor and Claude Code output verified; Codex falls to else branch (unverifiable) | Correct | +| Archetype gating | Bootstrapping runs unconditionally | On-demand plugins skip Phase 8 entirely; hooks/using-skill only for always-present | Fixed (archetype gate added) | ### inventory.md diff --git a/lib/principles/adding-a-platform.md b/lib/principles/adding-a-platform.md index 228a4d5..4e82b75 100644 --- a/lib/principles/adding-a-platform.md +++ b/lib/principles/adding-a-platform.md @@ -258,6 +258,8 @@ Three locations in the skill's intent-gathering pseudocode: 2. **The `ELSE` fallback list** — the `platforms = ["claude-code", "cursor", ...]` line that defines the "All platforms" default 3. **The "All platforms" option description** — if it enumerates platform names, add the new one +Note: hooks and the `using-` skill are only generated for always-present plugins (archetype gate in Phase 8). If you are adding a platform that supports hooks, ensure `lib/patterns/hook-merging.md` documents the format, but do not assume every target plugin will use hooks. + **Verification gate:** - [ ] Platform appears in the `options` array with `label` and `description` - [ ] `description` accurately summarizes the platform (no fabricated features) From 1404ab565e94c377a8c8266bc4a064ed9a54a9a2 Mon Sep 17 00:00:00 2001 From: Nathaniel Ramm Date: Tue, 28 Apr 2026 20:40:12 +1000 Subject: [PATCH 08/10] feat: add archetype gate to bootstrapping, reference external template Co-Authored-By: Claude Sonnet 4.6 --- lib/patterns/bootstrapping.md | 50 +++++++++++++---------------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/lib/patterns/bootstrapping.md b/lib/patterns/bootstrapping.md index 92213ef..413948e 100644 --- a/lib/patterns/bootstrapping.md +++ b/lib/patterns/bootstrapping.md @@ -1,12 +1,24 @@ # Bootstrapping -Session-start injection logic for generating the `using-` skill and associated hooks that force-inject plugin context at session start across all platforms. +Session-start injection logic for **always-present** plugins. Generates the `using-` skill and associated hooks that force-inject plugin context at session start across all platforms. + +**On-demand plugins skip this entirely.** The archetype gate in Phase 8 prevents bootstrapping from running for on-demand plugins. Hooks and using-skills are context injection — they are NOT required for plugin discovery on any platform. All 6 platforms discover plugins/skills via directory scanning. + +**When bootstrapping is valuable:** Plugins that govern workflows and must intercept every interaction (e.g., superpowers, single-purpose OpenClaw agents). The using-skill ensures the agent treats the plugin's skills as mandatory workflow gates. + +**When bootstrapping is unnecessary:** Plugins invoked explicitly when needed (e.g., portability assessment, code generation tools). These rely on directory auto-discovery and save context budget by not injecting on every session. --- ## Step 4.1: Prompt for Bootstrapping (Step 17) ``` +IF intent.archetype == "on-demand" THEN + skip_bootstrapping = true + reason = "on-demand archetype — hooks and using-skill not applicable" + skip to Step 4.8 (final report note) +END + IF skills/using-{{name}}/SKILL.md exists THEN skip_bootstrapping = true reason = "already configured" @@ -38,37 +50,11 @@ Build skillTable: END END -Write /skills/using-{{name}}/SKILL.md with template below, -substituting {{name}}, {{displayName}}, {{skillTable}}. -``` - -### using-skill Template - -```markdown ---- -name: using-{{name}} -description: Session-start bootstrapping for {{name}}. Lists available skills and platform-specific invocation instructions. ---- - -# Using {{displayName}} - -This plugin provides the following skills: - -| Skill | Description | -|-------|-------------| -{{skillTable}} - -## How to Invoke Skills - -**Claude Code / Cursor:** Use the `Skill` tool with the skill name. - -**Gemini CLI:** Use the `activate_skill` tool with the skill name. - -**Antigravity / OpenClaw / Codex:** Skills are auto-discovered. Follow the SKILL.md instructions directly. - -## Tool Name Mapping - -Skills use Claude Code tool names. See each skill's `references/` directory for platform-specific equivalents. +Write /skills/using-{{name}}/SKILL.md using the template at +lib/templates/context-files/using-skill.md.tmpl, substituting: + - {{name}} = plugin name + - {{usingSkillDescription}} = generated from plugin purpose + - {{skillTable}} = markdown table built from discovered skills ``` --- From f770302d37079bc0abb94800949287e884d6a5cd Mon Sep 17 00:00:00 2001 From: Nathaniel Ramm Date: Tue, 28 Apr 2026 20:40:16 +1000 Subject: [PATCH 09/10] docs: note injection checks only apply to always-present plugins Co-Authored-By: Claude Sonnet 4.6 --- lib/patterns/injection-checks.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/patterns/injection-checks.md b/lib/patterns/injection-checks.md index 1b8f5b7..9c3a32f 100644 --- a/lib/patterns/injection-checks.md +++ b/lib/patterns/injection-checks.md @@ -1,6 +1,9 @@ # Injection Checks 8-component verification for session-start bootstrapping infrastructure. +Only applies to **always-present** plugins (archetype gate). On-demand plugins +skip injection checks entirely — they have no using-skill or hooks. + Only runs when `skills/using-/SKILL.md` exists. --- From b0a40c3d7cb7d0c53b91e632ad6892ecf598e4ab Mon Sep 17 00:00:00 2001 From: Nathaniel Ramm Date: Tue, 28 Apr 2026 20:58:14 +1000 Subject: [PATCH 10/10] chore: bump version to 0.2.1, add design/plan docs Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude-plugin/plugin.json | 2 +- .cursor-plugin/plugin.json | 2 +- .../plans/2026-04-28-hook-archetype-gating.md | 512 ++++++++++++++++++ package.json | 2 +- 4 files changed, 515 insertions(+), 3 deletions(-) create mode 100644 docs/superpowers/plans/2026-04-28-hook-archetype-gating.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 13bbf6e..2e38438 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "plugin-portability", "description": "Make any plugin fully portable across all platforms. Accepts Claude Code, Cursor, Gemini, Codex, Antigravity, OpenClaw, or bare SKILL.md repos as input. Emits every missing platform artifact.", - "version": "0.2.0", + "version": "0.2.1", "author": { "name": "Nathaniel Ramm", "email": "nathaniel.ramm@discretedatascience.com" diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index 13bbf6e..2e38438 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "plugin-portability", "description": "Make any plugin fully portable across all platforms. Accepts Claude Code, Cursor, Gemini, Codex, Antigravity, OpenClaw, or bare SKILL.md repos as input. Emits every missing platform artifact.", - "version": "0.2.0", + "version": "0.2.1", "author": { "name": "Nathaniel Ramm", "email": "nathaniel.ramm@discretedatascience.com" diff --git a/docs/superpowers/plans/2026-04-28-hook-archetype-gating.md b/docs/superpowers/plans/2026-04-28-hook-archetype-gating.md new file mode 100644 index 0000000..63b44bb --- /dev/null +++ b/docs/superpowers/plans/2026-04-28-hook-archetype-gating.md @@ -0,0 +1,512 @@ +# Hook & Using-Skill Archetype Gating Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Make hooks and using-skill generation conditional on plugin archetype (always-present vs on-demand), remove them from this on-demand repo, and create a using-skill template modelled on superpowers. + +**Architecture:** Four sequential phases: (1) delete hooks/using-skill from this repo, (2) add archetype question + Phase 8 gate to the skill, (3) create using-skill template, (4) update patterns, references, and CI. + +**Tech Stack:** Markdown, YAML pseudocode, GitHub Actions YAML, bash + +--- + +### Task 1: Delete hooks and using-skill from this repo + +**Files:** +- Delete: `skills/using-plugin-portability/SKILL.md` +- Delete: `hooks/hooks.json` +- Delete: `hooks/hooks-cursor.json` +- Delete: `hooks/session-start` +- Delete: `hooks/run-hook.cmd` +- Modify: `GEMINI.md:7` + +- [ ] **Step 1: Delete the using-skill directory** + +Run: + +```bash +git rm -r skills/using-plugin-portability/ +``` + +- [ ] **Step 2: Delete the hooks directory** + +Run: + +```bash +git rm -r hooks/ +``` + +- [ ] **Step 3: Remove using-skill include from GEMINI.md** + +In `GEMINI.md`, remove line 7: + +``` +@./skills/using-plugin-portability/SKILL.md +``` + +So the Skills section becomes: + +```markdown +## Skills + +@./skills/plugin-portability/SKILL.md +``` + +- [ ] **Step 4: Verify deletions** + +Run: `ls skills/using-plugin-portability 2>/dev/null; ls hooks/ 2>/dev/null; grep "using-plugin-portability" GEMINI.md` + +Expected: all three commands produce no output (directory not found, directory not found, no grep match). + +- [ ] **Step 5: Commit** + +```bash +git add GEMINI.md +git commit -m "feat: remove hooks and using-skill from on-demand plugin" +``` + +--- + +### Task 2: Remove hooks check from CI + +**Files:** +- Modify: `.github/workflows/ci.yml:107-113` + +- [ ] **Step 1: Remove the Session-Start Hook check block** + +In `.github/workflows/ci.yml`, remove lines 106-113 (the `=== Session-Start Hook ===` block): + +```yaml + echo "" + echo "=== Session-Start Hook ===" + if [ ! -x hooks/session-start ]; then + echo "FAIL: hooks/session-start does not exist or is not executable" + errors=$((errors + 1)) + else + echo "OK: hooks/session-start (executable)" + fi +``` + +- [ ] **Step 2: Verify CI file is valid YAML** + +Run: `python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci.yml'))"` + +Expected: no output (valid YAML). + +- [ ] **Step 3: Commit** + +```bash +git add .github/workflows/ci.yml +git commit -m "ci: remove hooks/session-start check (on-demand plugin has no hooks)" +``` + +--- + +### Task 3: Add archetype question to skill intent-gathering + +**Files:** +- Modify: `skills/plugin-portability/SKILL.md:70-116` (Phase 0a: Intent) + +- [ ] **Step 1: Add Q3 archetype question after Q2** + +In `skills/plugin-portability/SKILL.md`, find the line: + +``` + RETURN { mode, platforms } +``` + +Replace it with: + +```pseudocode + # Q3: Archetype + archetype = AskUserQuestion( + question: "What is this plugin's invocation pattern?", + header: "Archetype", + options: [ + { label: "On-demand", description: "Called explicitly when the user needs it (e.g., portability tools, code generators)" }, + { label: "Always-present", description: "Governs workflows on every session — needs context injection (e.g., superpowers, single-purpose agents)" } + ], + multiSelect: false + ) + + RETURN { mode, platforms, archetype } +``` + +- [ ] **Step 2: Add archetype gate to Phase 8** + +In `skills/plugin-portability/SKILL.md`, find the Phase 8 block: + +```pseudocode +BOOTSTRAP(computed, intent): + IF computed.uplift_target == "curated-note-only": SKIP + + LOAD_AND_VERIFY("lib/patterns/bootstrapping.md", + proof: content contains steps 4.1 through 4.8) + + # Execute bootstrapping as defined in bootstrapping.md +``` + +Replace with: + +```pseudocode +BOOTSTRAP(computed, intent): + IF computed.uplift_target == "curated-note-only": SKIP + IF intent.archetype == "on-demand": + REPORT "Bootstrapping: skipped (on-demand plugin — hooks and using-skill not applicable)" + SKIP + + LOAD_AND_VERIFY("lib/patterns/bootstrapping.md", + proof: content contains steps 4.1 through 4.8) + + # Execute bootstrapping as defined in bootstrapping.md +``` + +- [ ] **Step 3: Verify the edits** + +Run: `grep -n "archetype" skills/plugin-portability/SKILL.md` + +Expected: hits for Q3 question, RETURN statement, and Phase 8 gate. + +- [ ] **Step 4: Commit** + +```bash +git add skills/plugin-portability/SKILL.md +git commit -m "feat: add archetype question and Phase 8 gate for on-demand plugins" +``` + +--- + +### Task 4: Create using-skill template + +**Files:** +- Create: `lib/templates/context-files/using-skill.md.tmpl` + +- [ ] **Step 1: Write the template** + +Write to `lib/templates/context-files/using-skill.md.tmpl`: + +```markdown +{{! fixes: bootstrap.using_skill }} +--- +name: using-{{name}} +description: {{usingSkillDescription}} +--- + + +If you were dispatched as a subagent to execute a specific task, skip this skill. + + + +If you think there is even a 1% chance a skill might apply to what you are +doing, you ABSOLUTELY MUST invoke the skill. + +IF A SKILL APPLIES TO YOUR TASK, YOU DO NOT HAVE A CHOICE. YOU MUST USE IT. + +This is not negotiable. This is not optional. You cannot rationalize your way +out of this. + + +## Instruction Priority + +{{name}} skills override default system prompt behavior, but **user +instructions always take precedence**: + +1. **User's explicit instructions** (CLAUDE.md, GEMINI.md, AGENTS.md, direct + requests) — highest priority +2. **{{name}} skills** — override default system behavior where they conflict +3. **Default system prompt** — lowest priority + +## How to Access Skills + +**In Claude Code:** Use the `Skill` tool. + +**In Cursor:** Use the `Skill` tool. + +**In Gemini CLI:** Skills activate via the `activate_skill` tool. + +**In other environments:** Check your platform's documentation for how skills +are loaded. + +## Platform Adaptation + +Skills use Claude Code tool names. Non-CC platforms: see `lib/references/` +for platform-specific tool equivalents. + +# Using Skills + +## The Rule + +**Invoke relevant or requested skills BEFORE any response or action.** Even a +1% chance a skill might apply means you should invoke the skill to check. If +an invoked skill turns out to be wrong for the situation, you don't need to +use it. + +## Available Skills + +{{skillTable}} + +## Red Flags + +These thoughts mean STOP — you're rationalizing: + +| Thought | Reality | +|---------|---------| +| "This is just a simple question" | Questions are tasks. Check for skills. | +| "I need more context first" | Skill check comes BEFORE clarifying questions. | +| "Let me explore the codebase first" | Skills tell you HOW to explore. Check first. | +| "This doesn't need a formal skill" | If a skill exists, use it. | +| "I remember this skill" | Skills evolve. Read current version. | +| "The skill is overkill" | Simple things become complex. Use it. | +| "I'll just do this one thing first" | Check BEFORE doing anything. | + +## Skill Types + +**Rigid** (TDD, debugging): Follow exactly. Don't adapt away discipline. + +**Flexible** (patterns): Adapt principles to context. + +The skill itself tells you which. + +## User Instructions + +Instructions say WHAT, not HOW. "Add X" or "Fix Y" doesn't mean skip +workflows. +``` + +- [ ] **Step 2: Verify the template has the expected variables** + +Run: `grep -c "{{name}}\|{{usingSkillDescription}}\|{{skillTable}}" lib/templates/context-files/using-skill.md.tmpl` + +Expected: at least 5 (multiple `{{name}}` occurrences + 1 each for the others). + +- [ ] **Step 3: Commit** + +```bash +git add lib/templates/context-files/using-skill.md.tmpl +git commit -m "feat: add using-skill template modelled on superpowers" +``` + +--- + +### Task 5: Update bootstrapping.md + +**Files:** +- Modify: `lib/patterns/bootstrapping.md:1-50` + +- [ ] **Step 1: Add archetype gate and update description** + +Replace lines 1-3 of `lib/patterns/bootstrapping.md`: + +```markdown +# Bootstrapping + +Session-start injection logic for generating the `using-` skill and associated hooks that force-inject plugin context at session start across all platforms. +``` + +With: + +```markdown +# Bootstrapping + +Session-start injection logic for **always-present** plugins. Generates the `using-` skill and associated hooks that force-inject plugin context at session start across all platforms. + +**On-demand plugins skip this entirely.** The archetype gate in Phase 8 prevents bootstrapping from running for on-demand plugins. Hooks and using-skills are context injection — they are NOT required for plugin discovery on any platform. All 6 platforms discover plugins/skills via directory scanning. + +**When bootstrapping is valuable:** Plugins that govern workflows and must intercept every interaction (e.g., superpowers, single-purpose OpenClaw agents). The using-skill ensures the agent treats the plugin's skills as mandatory workflow gates. + +**When bootstrapping is unnecessary:** Plugins invoked explicitly when needed (e.g., portability assessment, code generation tools). These rely on directory auto-discovery and save context budget by not injecting on every session. +``` + +- [ ] **Step 2: Update Step 4.1 to add archetype check** + +In `lib/patterns/bootstrapping.md`, find: + +``` +IF skills/using-{{name}}/SKILL.md exists THEN +``` + +Add before it: + +``` +IF intent.archetype == "on-demand" THEN + skip_bootstrapping = true + reason = "on-demand archetype — hooks and using-skill not applicable" + skip to Step 4.8 (final report note) +END +``` + +- [ ] **Step 3: Update Step 4.2 to reference the template** + +In `lib/patterns/bootstrapping.md`, find lines 41-42: + +``` +Write /skills/using-{{name}}/SKILL.md with template below, +substituting {{name}}, {{displayName}}, {{skillTable}}. +``` + +Replace with: + +``` +Write /skills/using-{{name}}/SKILL.md using the template at +lib/templates/context-files/using-skill.md.tmpl, substituting: + - {{name}} = plugin name + - {{usingSkillDescription}} = generated from plugin purpose + - {{skillTable}} = markdown table built from discovered skills +``` + +- [ ] **Step 4: Remove the inline using-skill template** + +Delete the `### using-skill Template` section (the inline markdown template that follows Step 4.2) since it's now in `lib/templates/context-files/using-skill.md.tmpl`. + +- [ ] **Step 5: Commit** + +```bash +git add lib/patterns/bootstrapping.md +git commit -m "feat: add archetype gate to bootstrapping, reference external template" +``` + +--- + +### Task 6: Update injection-checks.md + +**Files:** +- Modify: `lib/patterns/injection-checks.md:1-4` + +- [ ] **Step 1: Add archetype note** + +Replace lines 1-4 of `lib/patterns/injection-checks.md`: + +```markdown +# Injection Checks + +8-component verification for session-start bootstrapping infrastructure. +Only runs when `skills/using-/SKILL.md` exists. +``` + +With: + +```markdown +# Injection Checks + +8-component verification for session-start bootstrapping infrastructure. +Only applies to **always-present** plugins (archetype gate). On-demand plugins +skip injection checks entirely — they have no using-skill or hooks. + +Only runs when `skills/using-/SKILL.md` exists. +``` + +- [ ] **Step 2: Commit** + +```bash +git add lib/patterns/injection-checks.md +git commit -m "docs: note injection checks only apply to always-present plugins" +``` + +--- + +### Task 7: Update template registry + +**Files:** +- Modify: `lib/references/templates/registry.md:72-73` + +- [ ] **Step 1: Add using-skill template entry** + +In `lib/references/templates/registry.md`, find the closing `]` of the `TEMPLATE_REGISTRY` list (line 73): + +```pseudocode +] +``` + +Add before it: + +```pseudocode + + { schema: "using-skill", platform: "all", mode: "builder", + template_path: "lib/templates/context-files/using-skill.md.tmpl", + target_path: "skills/using-{{name}}/SKILL.md" }, +``` + +- [ ] **Step 2: Commit** + +```bash +git add lib/references/templates/registry.md +git commit -m "feat: add using-skill template to registry" +``` + +--- + +### Task 8: Update adding-a-platform guide and reconciliation matrix + +**Files:** +- Modify: `lib/principles/adding-a-platform.md` +- Modify: `docs/reconciliation-matrix.md` + +- [ ] **Step 1: Add archetype note to Phase 7 in adding-a-platform.md** + +In `lib/principles/adding-a-platform.md`, find the Phase 7 section's "What to update" list. After the third item ("The 'All platforms' option description"), add: + +```markdown + +Note: hooks and the `using-` skill are only generated for always-present plugins (archetype gate in Phase 8). If you are adding a platform that supports hooks, ensure `lib/patterns/hook-merging.md` documents the format, but do not assume every target plugin will use hooks. +``` + +- [ ] **Step 2: Update reconciliation matrix bootstrapping section** + +In `docs/reconciliation-matrix.md`, find the `### bootstrapping.md` section. Add a row to its table: + +```markdown +| Archetype gating | Bootstrapping runs unconditionally | On-demand plugins skip Phase 8 entirely; hooks/using-skill only for always-present | Fixed (archetype gate added) | +``` + +- [ ] **Step 3: Commit** + +```bash +git add lib/principles/adding-a-platform.md docs/reconciliation-matrix.md +git commit -m "docs: update guide and matrix for archetype-conditional bootstrapping" +``` + +--- + +### Task 9: Final verification + +- [ ] **Step 1: Verify hooks directory is gone** + +Run: `ls hooks/ 2>/dev/null; echo "EXIT: $?"` + +Expected: `EXIT: 2` (no such directory). + +- [ ] **Step 2: Verify using-skill is gone** + +Run: `ls skills/using-plugin-portability/ 2>/dev/null; echo "EXIT: $?"` + +Expected: `EXIT: 2` (no such directory). + +- [ ] **Step 3: Verify GEMINI.md has no using-skill reference** + +Run: `grep "using-plugin-portability" GEMINI.md; echo "EXIT: $?"` + +Expected: `EXIT: 1` (no match). + +- [ ] **Step 4: Verify skill has archetype question and gate** + +Run: `grep -c "archetype" skills/plugin-portability/SKILL.md` + +Expected: at least 3 (Q3 question, RETURN, Phase 8 gate). + +- [ ] **Step 5: Verify template exists with expected variables** + +Run: `grep -c "{{name}}\|{{skillTable}}\|{{usingSkillDescription}}" lib/templates/context-files/using-skill.md.tmpl` + +Expected: at least 5. + +- [ ] **Step 6: Verify CI has no hooks check** + +Run: `grep "session-start" .github/workflows/ci.yml; echo "EXIT: $?"` + +Expected: `EXIT: 1` (no match). + +- [ ] **Step 7: Verify bootstrapping.md has archetype gate** + +Run: `grep "on-demand" lib/patterns/bootstrapping.md | head -3` + +Expected: hits for archetype description and the skip condition. diff --git a/package.json b/package.json index da5629f..c234c43 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { "name": "plugin-portability", - "version": "0.2.0", + "version": "0.2.1", "type": "module" }