Merge feature/superpowers-vendored into develop

This commit is contained in:
bastien
2026-09-28 15:08:58 +02:00
35 changed files with 695 additions and 145 deletions
+10
View File
@@ -127,6 +127,7 @@ rules:
| BDR-103 | 2026-09-27 | 6-repo review: 5 verdicts, 3 criteria (grep-verified coverage, per-session cost, doctrine conflict); stars decided nothing | accepted | | BDR-103 | 2026-09-27 | 6-repo review: 5 verdicts, 3 criteria (grep-verified coverage, per-session cost, doctrine conflict); stars decided nothing | accepted |
| BDR-104 | 2026-09-28 | MengTo motion pack: vendor 5 scroll skills pinned via shared lib/vendor-skills.sh + build personal skill site-motion; 17 skipped | accepted | | BDR-104 | 2026-09-28 | MengTo motion pack: vendor 5 scroll skills pinned via shared lib/vendor-skills.sh + build personal skill site-motion; 17 skipped | accepted |
| BDR-105 | 2026-09-28 | skill-catalog prune: 9 gstack out via GSTACK_REMOVED, full ⊇ every profile, max = everything, brightdata + frontend-design plugin off, security-guidance Stop review off, design gate asks `21st login` and waits | accepted | | BDR-105 | 2026-09-28 | skill-catalog prune: 9 gstack out via GSTACK_REMOVED, full ⊇ every profile, max = everything, brightdata + frontend-design plugin off, security-guidance Stop review off, design gate asks `21st login` and waits | accepted |
| BDR-106 | 2026-09-28 | superpowers: 7 wired skills vendored at v6.4.1 via lib/vendor-skills.sh (always_on lock class), plugin + marketplace dropped, citers by bare name, doctrine map for the 4 non-vendored refs | accepted |
--- ---
@@ -1319,3 +1320,12 @@ Branch feature/user-writing-web-rules, UNMERGED (human gate).
- **Alternatives rejected**: rm symlinks by hand (set/reset re-materialize, `gstack on` restores everything → denylist instead); per-skill toggles inside ui-ux-pro-max (all-or-nothing, unverified); drop superpowers in the same run (7 skills wired in ship-feature/init-project → tier 2, own branch); keep the 21st trio in design profiles (redundant with impeccable + ui-ux-pro-max, CLI signed out); raise `SLASH_COMMAND_TOOL_CHAR_BUDGET` (costs context, the opposite goal); keep the official frontend-design plugin and drop the copy (copy is profile-managed and gate-checked); shared 21st auth helper across 3 scripts (breaks 4 fixture suites, changes installer semantics — [[LRN-178]]); in-session `export TWENTYFIRST_TOKEN` remedy (env does not persist across tool calls). - **Alternatives rejected**: rm symlinks by hand (set/reset re-materialize, `gstack on` restores everything → denylist instead); per-skill toggles inside ui-ux-pro-max (all-or-nothing, unverified); drop superpowers in the same run (7 skills wired in ship-feature/init-project → tier 2, own branch); keep the 21st trio in design profiles (redundant with impeccable + ui-ux-pro-max, CLI signed out); raise `SLASH_COMMAND_TOOL_CHAR_BUDGET` (costs context, the opposite goal); keep the official frontend-design plugin and drop the copy (copy is profile-managed and gate-checked); shared 21st auth helper across 3 scripts (breaks 4 fixture suites, changes installer semantics — [[LRN-178]]); in-session `export TWENTYFIRST_TOKEN` remedy (env does not persist across tool calls).
- **Caveats**: kept gstack skills still route to removed names in their upstream prose (Skill call fails, doctrine applies); helper tree links every top-level submodule entry (no SKILL.md exposed, asserted); security-guidance commit review quota unmeasured; doctor constants rebased on 2026-09-28 measures; `apply` is additive → other machines run `set full`, not `apply`. - **Caveats**: kept gstack skills still route to removed names in their upstream prose (Skill call fails, doctrine applies); helper tree links every top-level submodule entry (no SKILL.md exposed, asserted); security-guidance commit review quota unmeasured; doctor constants rebased on 2026-09-28 measures; `apply` is additive → other machines run `set full`, not `apply`.
- **Reference**: f83f8f7 02b62f7 4c86d6d 729d715 (prune), bd3e525 132bcdf (21st gate); contracts `2026-09-28-skill-catalog-prune-0554` (18 criteria, oracles in `.oracles/`) and `2026-09-28-21st-signin-gate-1215` (7); plans r4 / r3 after 3 challengers + 1 confirmation each; GATE 0 MET, verifiers CONFORME (iter 2 / iter 1), security PASS ×2; 42 suites green minus 2 pre-existing T16a. Links [[BDR-030]] [[BDR-101]] [[BDR-093]] [[BDR-095]] [[BDR-080]] [[BDR-025]] [[BDR-070]] [[LRN-175]] [[LRN-176]] [[LRN-177]] [[LRN-178]] [[BLK-023]] [[EVAL-034]]. - **Reference**: f83f8f7 02b62f7 4c86d6d 729d715 (prune), bd3e525 132bcdf (21st gate); contracts `2026-09-28-skill-catalog-prune-0554` (18 criteria, oracles in `.oracles/`) and `2026-09-28-21st-signin-gate-1215` (7); plans r4 / r3 after 3 challengers + 1 confirmation each; GATE 0 MET, verifiers CONFORME (iter 2 / iter 1), security PASS ×2; 42 suites green minus 2 pre-existing T16a. Links [[BDR-030]] [[BDR-101]] [[BDR-093]] [[BDR-095]] [[BDR-080]] [[BDR-025]] [[BDR-070]] [[LRN-175]] [[LRN-176]] [[LRN-177]] [[LRN-178]] [[BLK-023]] [[EVAL-034]].
## BDR-106 — superpowers: 7 skills vendored at v6.4.1, plugin dropped
- **Date**: 2026-09-28
- **Status**: accepted, feature/superpowers-vendored, UNMERGED (human gate)
- **Decision**: (1) plugins.lock.json `superpowers` entry (obra/superpowers @ 5bf4e78 = tag v6.4.1, path `skills`, per-skill file lists, `always_on: true`), fetched byte-for-byte by lib/vendor-skills.sh: brainstorming, writing-plans, subagent-driven-development, test-driven-development, requesting-code-review, using-git-worktrees, writing-skills; STEP 8e vendors, update-all refreshes at the pin, link.sh links, .gitignore ignores. (2) Plugin + marketplace uninstalled (one shot by hand after the fetch proved byte-identical), settings.json keys removed by hand, PROTECTED_PLUGINS = security-guidance only; `detect_superpowers` = `[ -f ~/.claude/skills/brainstorming/SKILL.md ]`, no plugin fallback; doctor/session-start no longer charge the injection. (3) doctor-vendored `always_on` class: third lock column, `_dv_check_link` 5th param — always-on externals are link-checked, never "parked". (4) Citers call the bare names; CLAUDE.global.md maps the four non-vendored skills the vendored text still references (executing-plans → SDD, finishing-a-development-branch → gitflow finish, systematic-debugging → bugfix, verification-before-completion → verifier gates). Vendored text never edited (BDR-104 rule).
- **Why**: 7 skills wired (ship-feature, init-project, writing-skills TDD), 8 duplicate personal flows; SessionStart injection 3.6 KB per start/clear/compact + a competing router ("1 % → MUST invoke", BDR-080 conflict); 15 descriptions → 7. Tier 2 of [[BDR-105]].
- **Alternatives rejected**: shared auth/detect helpers sourced at top level (break the fixture `cp` suites, [[LRN-178]]); installer-side uninstall (plugin gone before the fetch on a network failure; precedent = comment only, one-shot by hand); detect with plugin-cache fallback (the marketplace dir matches `*superpowers*` → "vendored" on a plugin-only machine, fail-open); rewriting vendored text to fix cross-refs; vendoring all 15; map text spelling the colon form or wrapping identifiers (criteria 3/7 grep line by line — both caught by challengers).
- **Caveats**: upstream cross-refs to the plugin prefix and the 8 dropped skills remain in the vendored text (a call on a dropped name fails, doctrine map applies); no upstream auto-update (bump the pin deliberately); the harness hot-loaded the 7 bare names in the running session after link.sh, the plugin names leave at restart; `superpowers-marketplace` cache dir may linger empty; other machines: `make plugin` (vendors) + `make link`, then uninstall the cached plugin by hand (CHANGELOG).
- **Reference**: 18f8c89 (wiring), ddea411 (citers/docs/settings); contract `2026-09-28-superpowers-vendored-1357` (12 criteria, oracles in `.oracles/`), plan r3 after 3 challengers (simplicity CONCERNS(2), robustness CONCERNS(3), correctness FATAL(5)) + confirmation CONCERNS(1); executors 2/2 DONE first pass; GATE 0 MET, verifier CONFORME 12/12, security PASS; catalog 82 skills, plugin passive cost 670 t (ui-ux-pro-max only). Links [[BDR-105]] [[BDR-102]] [[BDR-104]] [[BDR-065]] [[LRN-178]] [[EVAL-034]].
+1
View File
@@ -538,3 +538,4 @@ rules:
- Skill-catalog audit (user: "tour des skills, doublons, économiser tokens"): 5 analyzers over 150 skills / 53.5k chars desc; 78 listed name-only this session (listing budget ≈1 % ctx, least-invoked lose desc → gain = routing quality + no broken 100 KB body invoked, not listing chars). Found: frontend-design plugin byte-dup of managed copy; brightdata 21 skills keyless + hostile WebFetch routing; gstack ship trunk-based (origin/HEAD=main), land-and-deploy auto-merge+deploy, autoplan/make-pdf/diagram/careful/guard/freeze dead paths (only bin + browse/dist linked); security-guidance = Opus call per code turn + agentic commit review, 0 findings/6 days; doctor.sh undercount ×6. User go: tier 1, superpowers vendor-7 (tier 2 later), 21st trio parked (CLI `Not logged in`), rule "full ⊇ every profile, max = everything". Live: brightdata disabled, frontend-design plugin uninstalled, `set full` → 75 skills (was 89). - Skill-catalog audit (user: "tour des skills, doublons, économiser tokens"): 5 analyzers over 150 skills / 53.5k chars desc; 78 listed name-only this session (listing budget ≈1 % ctx, least-invoked lose desc → gain = routing quality + no broken 100 KB body invoked, not listing chars). Found: frontend-design plugin byte-dup of managed copy; brightdata 21 skills keyless + hostile WebFetch routing; gstack ship trunk-based (origin/HEAD=main), land-and-deploy auto-merge+deploy, autoplan/make-pdf/diagram/careful/guard/freeze dead paths (only bin + browse/dist linked); security-guidance = Opus call per code turn + agentic commit review, 0 findings/6 days; doctor.sh undercount ×6. User go: tier 1, superpowers vendor-7 (tier 2 later), 21st trio parked (CLI `Not logged in`), rule "full ⊇ every profile, max = everything". Live: brightdata disabled, frontend-design plugin uninstalled, `set full` → 75 skills (was 89).
- /feat by hand on feature/skill-catalog-prune: contract 18 criteria; plan r1→r4 (3 challengers, confirmation FATAL(4): nested SKILL.md in browser-skills/openclaw/node_modules, ./setup global symlink, update-all 3rd copy); 4 feater parallel DONE; GATE 0 UNMET(4) = MY heredoc CHECKs (gates.sh single-line) → oracles to `<contract>.oracles/*.py` → MET; verifier ECARTS(1) = floor-guard `xit(` false-positive on `sys.exit(` → restructure → CONFORME; security PASS. 41 suites green minus 2 pre-existing T16a, shellcheck clean. UNMERGED — human gate. Registries pending user approval. - /feat by hand on feature/skill-catalog-prune: contract 18 criteria; plan r1→r4 (3 challengers, confirmation FATAL(4): nested SKILL.md in browser-skills/openclaw/node_modules, ./setup global symlink, update-all 3rd copy); 4 feater parallel DONE; GATE 0 UNMET(4) = MY heredoc CHECKs (gates.sh single-line) → oracles to `<contract>.oracles/*.py` → MET; verifier ECARTS(1) = floor-guard `xit(` false-positive on `sys.exit(` → restructure → CONFORME; security PASS. 41 suites green minus 2 pre-existing T16a, shellcheck clean. UNMERGED — human gate. Registries pending user approval.
- User: "quand on détecte qu'on a besoin de 21st, on demande de log si c'est pas fait et on attend". /feat by hand on the same branch: design gate gains exit 12 `SIGN-IN REQUIRED` (three-state whoami probe, unknown → 11 with diagnostic, explicit "proceed without 21st" only skip); challenge round dropped my shared-helper idea (would break 4 fixture suites + change installer semantics) and my in-session `export TWENTYFIRST_TOKEN` remedy (env does not persist across tool calls). Executor DONE first pass, GATE 0 MET, verifier CONFORME 7/7, security PASS, 8/8 hermetic. Gate now exits 12 live here until `21st login`. - User: "quand on détecte qu'on a besoin de 21st, on demande de log si c'est pas fait et on attend". /feat by hand on the same branch: design gate gains exit 12 `SIGN-IN REQUIRED` (three-state whoami probe, unknown → 11 with diagnostic, explicit "proceed without 21st" only skip); challenge round dropped my shared-helper idea (would break 4 fixture suites + change installer semantics) and my in-session `export TWENTYFIRST_TOKEN` remedy (env does not persist across tool calls). Executor DONE first pass, GATE 0 MET, verifier CONFORME 7/7, security PASS, 8/8 hermetic. Gate now exits 12 live here until `21st login`.
- User go "merge le tout, écris les registres, fais le tier 2": tier 1 registries (BDR-105, LRN-175..178, BLK-023, EVAL-034) written, feature/skill-catalog-prune finished → develop c39c0e1. Tier 2 on feature/superpowers-vendored: 7 superpowers skills vendored at v6.4.1 through lib/vendor-skills.sh (`always_on` lock class for doctor-vendored), plugin + marketplace uninstalled, settings.json hand-edited, citers by bare name, doctrine map. Challenge round: correctness FATAL(5) caught my map text containing the forbidden `superpowers` colon form; confirmation caught an identifier wrapped across lines (grep is line-based). Executors 2/2 DONE, GATE 0 MET, verifier CONFORME 12/12, security PASS. Catalog 82 skills, passive plugin cost 670 t, injection gone; harness hot-loaded the bare names in-session. 18f8c89 ddea411. UNMERGED — human gate. [[BDR-106]]
+20
View File
@@ -1,5 +1,25 @@
# TODO # TODO
## 2026-09-28 — tier 2: vendor 7 superpowers skills, drop the plugin (feature/superpowers-vendored)
User go "fais le tier 2" (decision 2026-09-28, batch 1). Contract
`.claude/tasks/contracts/2026-09-28-superpowers-vendored-1357.md`.
- [x] V1 plugins.lock.json `superpowers` entry (obra/superpowers @ 5bf4e78 = v6.4.1,
path skills, dict of 7 file lists); install-plugins.sh STEP 5 stops installing
the plugin, STEP 8e vendors it; update-all.sh refresh; link.sh EXTERNAL_SKILLS;
.gitignore; profile.sh PROTECTED_PLUGINS; detect-plugins/session-start/doctor
read the vendored dir, injection cost gone.
- [x] V2 citers: `superpowers:<x>` → `<x>` in ship-feature, init-project, tour, deploy,
audit-delta, lib/analyze-before-plan, plugin-advisor; finishing-a-development-
branch prose in capitalize-commit/doc-commit/gitflow; CLAUDE.global.md routing
map for the 8 dropped skills; README/USAGE/plugin-advisor/profile SKILL.md;
CHANGELOG.
- [x] V3 plan r1→r3 (3 challengers + confirmation), 2 feater DONE, live vendor + link
(VENDORED_LINKED), settings.json hand-edited, plugin + marketplace uninstalled,
GATE 0 MET 10/10, verifier CONFORME 12/12, security PASS; 18f8c89 ddea411; BDR-106.
Catalog 82 skills, passive plugins 670 t. UNMERGED — human gate. Other machines:
`make plugin` + `make link`, uninstall the cached plugin by hand. User: remove
`/tmp/tmp.PKDTRyaCw8` `/tmp/tmp.99Fu0dm8ll` (executor fixtures, rm refused).
## 2026-09-28 — design gate asks for `21st login` and waits (feature/skill-catalog-prune) ## 2026-09-28 — design gate asks for `21st login` and waits (feature/skill-catalog-prune)
User: "si on veut l'utiliser, on demande à l'utilisateur de se log, plus simple que User: "si on veut l'utiliser, on demande à l'utilisateur de se log, plus simple que
dire c'est pas logged on utilise pas… on demande de log si c'est pas fait et on dire c'est pas logged on utilise pas… on demande de log si c'est pas fait et on
@@ -0,0 +1,69 @@
# CONTRACT — superpowers-vendored
- date: 2026-09-28 | flow: feat (ad-hoc dispatch, /feat gates replayed by the orchestrator, 2 parallel feater executors) | branch: feature/superpowers-vendored
- status: active
## REQUEST (verbatim — IMMUTABLE)
> ok merge le tout et écris les registres puis fais le tier 2
Tier 2 as decided 2026-09-28 (batch 1, option "Vendoriser 7, retirer le plugin (Recommended)"): vendor brainstorming, writing-plans, subagent-driven-development, test-driven-development, requesting-code-review, using-git-worktrees, writing-skills from obra/superpowers at the v6.4.1 commit via `lib/vendor-skills.sh`, drop the superpowers plugin (its 8 other skills and its session-start injection), rename the `superpowers:` citers.
## CLARIFICATIONS
- Pass A: none — request complete (the decision batch fixed scope and outcome).
- Pass B: no visible / public-name choice left open — the vendored skills keep their upstream names (bare, no `superpowers:` prefix; renaming would break their internal cross-references), the lock key is `superpowers`, the always-on status is inherited (not in MANAGED_EXTERNALS, like darwin-skill). Proceeds silently.
- Byte-for-byte upstream text (BDR-104 convention): the vendored files are never edited, so their internal `superpowers:<x>` mentions and references to the 8 dropped skills (executing-plans, finishing-a-development-branch, systematic-debugging, verification-before-completion, dispatching-parallel-agents, receiving-code-review, using-superpowers, diagnosing-superpowers) stay in the text; CLAUDE.global.md carries the routing map (bare names; executing-plans → subagent-driven-development; finishing-a-development-branch → `gitflow finish` on a human signal; systematic-debugging → bugfix; verification-before-completion → the verifier gates). Known residual, documented.
- Scripts inside the vendored skills are invoked as `bash scripts/<x>` upstream: no exec bit needed after curl.
- `docs/superpowers/{specs,plans}` stays the transient path (brainstorming/writing-plans still write there; gitflow purge unchanged, BDR-065).
- Live steps are the orchestrator's: criterion 2 runs the vendor helper (network) + link.sh; the plugin uninstall (`claude plugin uninstall superpowers@superpowers-marketplace`) runs AFTER the 7 skills are linked, then criterion 8 checks the catalog. Executors never run `claude plugin …`, the vendor helper against the network, link.sh, `profile.sh set`, never commit.
- [challenge 2026-09-28, 3 lenses: simplicity CONCERNS(2), robustness CONCERNS(3), correctness FATAL(5); every BLOCKER/MAJOR closed by a named plan change, r2] (a) CLAUDE.global.md map never spells the colon form; (b) `always_on` lock field + doctor-vendored always-on class, test case; (c) no uninstall code in the installer, one-shot by the orchestrator after criterion 2, marketplace removed too, rollback step; (d) settings.json hand-edited (enabledPlugins key + marketplace block) and committed; (e) detect_superpowers = file test on the linked skill, no fallback, negative control in criterion 5; (f) map trimmed, lock note trimmed, session-start line deleted plainly.
- [confirmation pass 2026-09-28, correctness CONCERNS(1), all closed by named changes, r3] map identifiers kept whole per line (grep is line-based); `always_on` mechanism pinned (third lock column, 5th `_dv_check_link` param, headers); settings.json edited by the orchestrator only after criterion 2 is green; stale installer edge case removed; doctor pass line worded on what it proves.
- Functions ≤ 25 logic lines, 80-char lines, shellcheck clean.
## ACCEPTANCE CRITERIA
1. plugins.lock.json carries the `superpowers` entry: obra/superpowers, commit 5bf4e78011075bcfc0dc295f0724994cd123ee71 (v6.4.1), path `skills`, dict of exactly the 7 skills with every upstream file listed (SKILL.md each; SDD scripts, code-reviewer.md, anthropic-best-practices.md included).
CHECK: python3 .claude/tasks/contracts/2026-09-28-superpowers-vendored-1357.oracles/c1.py
EXPECT: LOCK_OK
EVIDENCE: MET exit=0 marker-found :: LOCK_OK
2. Vendored + linked live: every listed file is under skills-external/<skill>/, byte-identical to the plugin cache copy, and the 7 symlinks resolve under ~/.claude/skills.
CHECK: bash -c 'source lib/vendor-skills.sh; vendor_pinned_skills superpowers' >/dev/null 2>&1; bash link.sh >/dev/null 2>&1; python3 .claude/tasks/contracts/2026-09-28-superpowers-vendored-1357.oracles/c2.py
EXPECT: VENDORED_LINKED
EVIDENCE: MET exit=0 marker-found :: VENDORED_LINKED
3. No `superpowers:` prefix remains in the personal catalog, agents, lib, hooks or doctrine (fixtures excluded; positive control first).
CHECK: echo 'x superpowers:brainstorming' | grep -q 'superpowers:' || exit 1; if git grep -n 'superpowers:' -- skills agents lib hooks CLAUDE.global.md ':!lib/tests/fixtures' | grep -v '^skills/synced'; then exit 1; fi; echo NO_PREFIX
EXPECT: NO_PREFIX
EVIDENCE: MET exit=0 marker-found :: NO_PREFIX
4. Installers and link wired: install-plugins.sh no longer installs/enables the plugin and vendors `superpowers` in STEP 8e; update-all.sh refreshes it; link.sh EXTERNAL_SKILLS lists the 7; .gitignore ignores the 7 skill symlinks and the 7 skills-external dirs.
CHECK: ! grep -qE 'install_plugin +"superpowers"|enable_plugin +"superpowers"' install-plugins.sh && grep -q 'vendor_pinned_skills superpowers' install-plugins.sh && grep -q 'vendor_pinned_skills superpowers refresh' update-all.sh && for s in brainstorming writing-plans subagent-driven-development test-driven-development requesting-code-review using-git-worktrees writing-skills; do grep -qE "^skills/$s\$" .gitignore || { echo "gitignore skills/$s"; exit 1; }; grep -qE "^skills-external/$s/\$" .gitignore || { echo "gitignore ext $s"; exit 1; }; sed -n '/^EXTERNAL_SKILLS=(/,/)/p' link.sh | grep -qw "$s" || { echo "link $s"; exit 1; }; done && echo WIRED
EXPECT: WIRED
EVIDENCE: MET exit=0 marker-found :: WIRED
5. profile.sh no longer protects the plugin; detect_superpowers is true on the linked vendored skill alone and false under an empty HOME (no plugin-cache glob, no claude call). [challenge r2]
CHECK: ! grep -q 'superpowers@superpowers-marketplace' lib/profile.sh && bash -c 'source lib/detect-plugins.sh; detect_superpowers' && E=$(mktemp -d) && ! HOME="$E" bash -c 'source lib/detect-plugins.sh; detect_superpowers' && rmdir "$E" && ! grep -qE 'compgen.*superpowers|plugin list.*superpowers' lib/detect-plugins.sh && echo DETECT_OK
EXPECT: DETECT_OK
EVIDENCE: MET exit=0 marker-found :: DETECT_OK
6. Suites and shellcheck: vendor-skills, doctor-vendored (with the new ALWAYS_ON_LINK_CHECKED case), doctrine-citers, skill-routing-census (live catalog with the 7), profile-default, profile-set-managed green; shellcheck clean on every touched shell file. [challenge r2]
CHECK: shellcheck install-plugins.sh update-all.sh link.sh lib/profile.sh lib/detect-plugins.sh hooks/session-start.sh doctor.sh lib/doctor-vendored.sh lib/vendor-skills.sh lib/tests/doctor-vendored.test.sh && out=$(make test suite=lib/tests/doctor-vendored.test.sh 2>&1) && echo "$out" | grep -q 'PASS ALWAYS_ON_LINK_CHECKED' && for s in vendor-skills doctor-vendored doctrine-citers skill-routing-census profile-default profile-set-managed; do out=$(make test suite=lib/tests/$s.test.sh 2>&1) || { echo "$s rc"; exit 1; }; echo "$out" | grep -qE 'FAIL=[1-9]|^FAIL ' && { echo "$s FAIL"; exit 1; }; done; echo SUITES_OK
EXPECT: SUITES_OK
EVIDENCE: MET exit=0 marker-found :: SUITES_OK
7. CLAUDE.global.md Skill routing carries the map for the dropped skills and says the seven are vendored, bare names.
CHECK: grep -q 'finishing-a-development-branch' CLAUDE.global.md && grep -q 'executing-plans' CLAUDE.global.md && grep -q 'systematic-debugging' CLAUDE.global.md && grep -qi 'vendored' CLAUDE.global.md && echo ROUTING_OK
EXPECT: ROUTING_OK
EVIDENCE: MET exit=0 marker-found :: ROUTING_OK
8. Live after the orchestrator's uninstall + marketplace removal: no superpowers plugin installed, no enabledPlugins key, no extraKnownMarketplaces block, the 7 skills still resolve, `make doctor` reports superpowers as vendored, not failed. [challenge r2]
CHECK: ! claude plugin list 2>/dev/null | grep -q 'superpowers@superpowers-marketplace' && python3 -c "import json,sys;d=json.load(open('settings.json'));assert 'superpowers@superpowers-marketplace' not in d['enabledPlugins'];assert 'superpowers-marketplace' not in d.get('extraKnownMarketplaces',{})" && for s in brainstorming writing-plans subagent-driven-development test-driven-development requesting-code-review using-git-worktrees writing-skills; do [ -f "$HOME/.claude/skills/$s/SKILL.md" ] || { echo "missing $s"; exit 1; }; done && bash doctor.sh 2>/dev/null | grep -qi 'superpowers.*vendored' && ! bash doctor.sh 2>/dev/null | grep -qi 'Superpowers not detected' && echo PLUGIN_GONE
EXPECT: PLUGIN_GONE
EVIDENCE: MET exit=0 marker-found :: PLUGIN_GONE
9. doctor.sh and session-start.sh stop charging the plugin injection (no `+ 1500` / `+ 800` superpowers constant; doctor message names the vendored skills).
CHECK: ! grep -qE 'detect_superpowers.*\+ ?(1500|800)' doctor.sh hooks/session-start.sh && grep -qi 'vendored' doctor.sh && echo DOCTOR_OK
EXPECT: DOCTOR_OK
EVIDENCE: MET exit=0 marker-found :: DOCTOR_OK
10. Docs: README component table row (vendored skills, pinned v6.4.1, lock entry), USAGE.md mentions of "superpowers" as a plugin or a passive cost reworded, agents/plugin-advisor.md compatibility/recommended-set rows and the "not active → install" remedy reworded, skills/profile/SKILL.md:59 always-on sentence updated, CHANGELOG `[Unreleased]` entry (Changed: superpowers plugin → 7 vendored skills; Removed: the 8 other skills + injection; Known residual: upstream cross-references).
11. lib/capitalize-commit.md, lib/doc-commit.md, lib/analyze-before-plan.md and skills/gitflow/SKILL.md describe finishing-a-development-branch as the upstream skill this config does not vendor (gitflow finish replaces it), not as an active skill.
12. doctor-vendored treats the 7 as always-on: `bash doctor.sh` prints a pass line for each of the 7 (linked) and never "parked" for them. [challenge r2]
CHECK: out=$(bash doctor.sh 2>/dev/null); for s in brainstorming writing-plans subagent-driven-development test-driven-development requesting-code-review using-git-worktrees writing-skills; do echo "$out" | grep -qE "✓.*\b$s\b" || { echo "no pass for $s"; exit 1; }; echo "$out" | grep -qE "$s.*parked" && { echo "parked $s"; exit 1; }; done; echo ALWAYS_ON_OK
EXPECT: ALWAYS_ON_OK
EVIDENCE: MET exit=0 marker-found :: ALWAYS_ON_OK
## FILE SCOPE
- plugins.lock.json, install-plugins.sh (STEP 5 superpowers block, STEP 8e, summary lines), update-all.sh (7.3), link.sh (EXTERNAL_SKILLS), .gitignore, lib/profile.sh (PROTECTED_PLUGINS + comments), lib/detect-plugins.sh, hooks/session-start.sh, doctor.sh, lib/doctor-vendored.sh, lib/tests/doctor-vendored.test.sh, lib/vendor-skills.sh (lock-shape header comment line)
- skills/{ship-feature,init-project,tour,deploy,audit-delta,gitflow,profile}/SKILL.md, lib/{analyze-before-plan,capitalize-commit,doc-commit}.md, agents/plugin-advisor.md, CLAUDE.global.md (Skill routing lines), README.md, USAGE.md, CHANGELOG.md
- Orchestrator-only, after criterion 2: settings.json (enabledPlugins key + extraKnownMarketplaces block, hand edit), `claude plugin uninstall` + `claude plugin marketplace remove` (cache), rollback if criterion 8 fails; skills-external/<7> (gitignored, curl) and ~/.claude/skills symlinks are written by criterion 2
- Orchestrator-only: .claude/tasks/**, .claude/memory/**
@@ -0,0 +1,16 @@
import json,re
d=json.load(open('plugins.lock.json'))
e=d['superpowers']
assert e['source']=='https://github.com/obra/superpowers', e['source']
assert e['commit']=='5bf4e78011075bcfc0dc295f0724994cd123ee71', e['commit']
assert e['path']=='skills', e.get('path')
assert e.get('managed_by')=='curl'
want={'brainstorming','writing-plans','subagent-driven-development','test-driven-development','requesting-code-review','using-git-worktrees','writing-skills'}
assert set(e['skills'])==want, set(e['skills'])^want
for k,files in e['skills'].items():
assert 'SKILL.md' in files, k
for f in files: assert re.fullmatch(r'[A-Za-z0-9._/-]+',f) and '..' not in f, f
assert 'scripts/sdd-workspace' in e['skills']['subagent-driven-development']
assert 'code-reviewer.md' in e['skills']['requesting-code-review']
assert 'anthropic-best-practices.md' in e['skills']['writing-skills']
print('LOCK_OK')
@@ -0,0 +1,17 @@
import json,os,hashlib,glob
H=os.path.expanduser('~')
e=json.load(open('plugins.lock.json'))['superpowers']
cache=glob.glob(H+'/.claude/plugins/cache/superpowers-marketplace/superpowers/6.4.1/skills')
missing=[];mism=[]
for k,files in e['skills'].items():
for f in files:
p=f'skills-external/{k}/{f}'
if not os.path.isfile(p): missing.append(p); continue
if cache:
c=f'{cache[0]}/{k}/{f}'
if os.path.isfile(c) and hashlib.md5(open(p,'rb').read()).hexdigest()!=hashlib.md5(open(c,'rb').read()).hexdigest(): mism.append(p)
link=f'{H}/.claude/skills/{k}'
if not (os.path.islink(link) and os.path.isfile(link+'/SKILL.md')): missing.append(link)
assert not missing, missing
assert not mism, ('byte mismatch vs plugin cache',mism)
print('VENDORED_LINKED')
@@ -0,0 +1,271 @@
# PLAN — superpowers-vendored (feat, ad-hoc dispatch) — r3 (after confirmation pass)
- r3 closes the confirmation pass (correctness CONCERNS(1)): MAJOR 1 — the
CLAUDE.global.md map keeps every skill identifier whole on one line (grep
is line-based); MINOR 2 — `always_on` mechanism pinned: the python lock
reader emits a third column, `_dv_check_link` gets a 5th param, headers
updated, a helper extracted if `check_vendored_skills` would exceed 5
locals; MINOR 3 — stale "uninstall || true" edge case deleted; MINOR 4 —
settings.json edit moves to the orchestrator, AFTER criterion 2 is green
(a disabled plugin + a failed fetch must never coincide); MINOR 5 —
profile.sh comments located by grep, doctor pass line worded on what is
proven.
- r2 closes: correctness BLOCKER 1 (the CLAUDE.global.md map never spells the
colon form — criterion 3 greps it), MAJOR 2 (doctor-vendored gains an
always-on class driven by a lock field `always_on`, so the 7 are
link-checked instead of "parked"), MAJOR 3 + robustness MAJOR 1 (NO
uninstall code in the installer — comment only, one-shot by the
orchestrator after criterion 2 is green), MAJOR 4 + robustness MAJOR 3
(settings.json hand-edited: enabledPlugins key and
extraKnownMarketplaces.superpowers-marketplace block removed, committed),
MAJOR 5 + robustness MAJOR 2 + simplicity MAJOR 1 (detect_superpowers =
one file test on the linked skill, no plugin fallback, no new global),
simplicity MAJOR 2 (same: no installer uninstall), MINORs: session-start
line deleted plainly, map trimmed to the four referenced skills, lock note
kept to maintainer facts, summary line placement pinned, rollback step,
mixed-version rollback note.
- date: 2026-09-28 | contract: contracts/2026-09-28-superpowers-vendored-1357.md
- branch: feature/superpowers-vendored
- executors: 2 feater (sonnet-pinned), parallel, disjoint file sets
## Ground truth (verified 2026-09-28)
- Plugin superpowers 6.4.1 installed at
`~/.claude/plugins/cache/superpowers-marketplace/superpowers/6.4.1/`
(gitCommitSha 5bf4e78011075bcfc0dc295f0724994cd123ee71 = upstream tag
v6.4.1 on obra/superpowers; raw files served at
`https://raw.githubusercontent.com/obra/superpowers/<sha>/skills/<skill>/<file>`,
brainstorming/SKILL.md md5 identical local vs raw). Enabled in settings.json
(`superpowers@superpowers-marketplace: true`), PROTECTED in lib/profile.sh,
installed + enabled by install-plugins.sh STEP 5 (marketplace add,
install_plugin, enable_plugin), summary line "ALWAYS ON … superpowers".
Its hooks.json SessionStart (startup|clear|compact) injects
using-superpowers (~3.6 KB) every start.
- The 7 skills to vendor and their files (upstream layout `skills/<name>/`):
brainstorming: SKILL.md, spec-document-reviewer-prompt.md, visual-companion.md,
scripts/frame-template.html, scripts/helper.js, scripts/server.cjs,
scripts/start-server.sh, scripts/stop-server.sh
writing-plans: SKILL.md, plan-document-reviewer-prompt.md
subagent-driven-development: SKILL.md, implementer-prompt.md,
re-review-prompt.md, task-reviewer-prompt.md, scripts/review-package,
scripts/sdd-workspace, scripts/task-brief
test-driven-development: SKILL.md, writing-good-tests.md
requesting-code-review: SKILL.md, code-reviewer.md
using-git-worktrees: SKILL.md
writing-skills: SKILL.md, anthropic-best-practices.md,
examples/CLAUDE_MD_TESTING.md, graphviz-conventions.dot,
persuasion-principles.md, render-graphs.js, testing-skills-with-subagents.md
Scripts are invoked upstream as `bash scripts/<x>` (SDD lines 137, 252,
290…; brainstorming visual-companion.md) → no exec bit needed.
- Internal cross-references that will dangle (byte-for-byte text):
writing-plans → superpowers:subagent-driven-development, superpowers:executing-plans (dropped), superpowers:using-git-worktrees;
SDD → superpowers:finishing-a-development-branch ×4 (dropped), superpowers:using-git-worktrees, superpowers:requesting-code-review, executing-plans ×2;
TDD → superpowers:writing-skills; writing-skills → superpowers:test-driven-development ×4, superpowers:systematic-debugging (dropped), using-superpowers, verification-before-completion.
- `lib/vendor-skills.sh` `vendor_pinned_skills <lock-key> [refresh]`: lock
entry `{source, commit (40 hex), path, skills: {name: [files]}, managed_by}`;
files must match `[A-Za-z0-9._/-]+`, no `..`; tmp+mv; skips existing files
unless `refresh`. install-plugins.sh STEP 8e calls it for agent-skills and
mengto-skills with `EXT_SKILL_NAMES` symlink check; update-all.sh 7.3 calls
it with `refresh`. link.sh `EXTERNAL_SKILLS=(…)` symlinks
`skills-external/<name>` into `~/.claude/skills/<name>`; .gitignore lists
`skills/<name>` (symlink) and `skills-external/<name>/` (vendored text) per
external. lib/doctor-vendored.sh reads the lock + EXTERNAL_SKILLS generically.
- lib/profile.sh: `PROTECTED_PLUGINS=("security-guidance@claude-code-plugins"
"superpowers@superpowers-marketplace")`; MANAGED_EXTERNALS is the allowlist
`set` parks — the 7 are NOT added (always on, like darwin-skill).
- lib/detect-plugins.sh `detect_superpowers`: plugin cache glob then `claude
plugin list`. Consumers: hooks/session-start.sh:122 (`+ 800` passive),
doctor.sh:225-228 (pass/fail "Superpowers plugin detected / not detected —
orchestrators will fail") and :423 (`+ 1500`).
- `superpowers:` citers (personal): skills/ship-feature:103,117,176,237;
skills/init-project:71,182,215,259; skills/tour:318; skills/deploy:515;
skills/audit-delta:321; lib/analyze-before-plan.md:106;
lib/capitalize-commit.md:20 (finishing-a-development-branch);
agents/plugin-advisor.md:182. Prose mentions of
finishing-a-development-branch: lib/capitalize-commit.md:68,
lib/doc-commit.md:84, lib/analyze-before-plan.md:108, skills/gitflow:16,110.
Docs: README.md:121 (component table), USAGE.md ×19 (plugin/cost
narrative), agents/plugin-advisor.md ×19 (matrix, recommended sets, remedy
:324), skills/profile/SKILL.md:59, install-plugins.sh:1210 summary.
`docs/superpowers/` paths (CLAUDE.md, gitflow, onboard) stay: brainstorming
and writing-plans still write there.
- lib/tests: gitflow-test.sh mentions superpowers only through the purge
path (unchanged). No suite asserts PROTECTED_PLUGINS content.
## Approach
### E1 — wiring (lock, installers, link, gitignore, profile, detect, doctor)
Files: plugins.lock.json, install-plugins.sh, update-all.sh, link.sh,
.gitignore, lib/profile.sh, lib/detect-plugins.sh, hooks/session-start.sh,
doctor.sh, lib/doctor-vendored.sh, lib/tests/doctor-vendored.test.sh,
lib/vendor-skills.sh (header comment line only).
1. plugins.lock.json: new entry `"superpowers"` after `"mengto-skills"`:
source `https://github.com/obra/superpowers`, commit
`5bf4e78011075bcfc0dc295f0724994cd123ee71`, path `skills`, `skills` = the
dict above (exact file lists), managed_by `curl`, `"always_on": true`,
note (maintainer facts only, history lives in CHANGELOG/BDR-106): "Seven
superpowers skills vendored byte-for-byte at the v6.4.1 tag commit
(obra/superpowers), always on (no profile lists them). Bump the commit
deliberately. Scripts inside run as `bash scripts/<x>`, no exec bit
needed. Upstream cross-references to the plugin prefix and to the 8
non-vendored skills stay in the text; CLAUDE.global.md Skill routing maps
them."
2. install-plugins.sh STEP 5: delete the three superpowers lines (marketplace
add, install_plugin, enable_plugin) and replace with a 3-line comment
"Superpowers plugin removed 2026-09-28 (tier 2 of the skill-catalog prune):
its 7 wired skills are vendored in Step 8e (plugins.lock.json
'superpowers'); a still-cached plugin is uninstalled by hand once
(claude plugin uninstall superpowers@superpowers-marketplace), never here".
NO uninstall code in the installer (precedent: frontend-design, caveman).
Update the `enable_plugin` comment (:490) to name only security-guidance.
STEP 8e: heading/comment mention superpowers; `EXT_SKILL_NAMES` += the 7;
`vendor_pinned_skills superpowers` after mengto. Summary: replace line
~1210 ("✅ superpowers — brainstorm/plan/implement/debug workflow", ALWAYS
ON block) by "✅ superpowers skills — 7 vendored (brainstorming,
writing-plans, subagent-driven-development, test-driven-development,
requesting-code-review, using-git-worktrees, writing-skills), pinned
v6.4.1, curl → symlink, no plugin, no session injection"; add one "at:"
line right after the mengto "at:" line (~1234): "Superpowers skills at:
~/.claude/skills/{brainstorming,…}/ (symlink → skills-external)".
3. update-all.sh 7.3: `echo "── Updating superpowers skills (obra/superpowers)..."`
+ `vendor_pinned_skills superpowers refresh`; comment names it.
4. link.sh EXTERNAL_SKILLS += the 7 (keep the array multi-line ≤ 80 chars).
5. .gitignore: 7 `skills/<name>` lines next to the other external symlinks
(:65-68 block) and 7 `skills-external/<name>/` lines next to the mengto
block (:203-207), each block with a one-line comment "superpowers, vendored
(plugins.lock.json 'superpowers')".
6. lib/profile.sh: PROTECTED_PLUGINS keeps only security-guidance; every
comment naming superpowers as an always-on plugin (`grep -n superpowers
lib/profile.sh`, currently ~:22 and ~:65) reworded ("superpowers is
vendored skills now, not a plugin").
7. lib/detect-plugins.sh `detect_superpowers`: exactly
`[ -f "$HOME/.claude/skills/brainstorming/SKILL.md" ]` (the linked
vendored skill: proves vendored AND linked; no plugin cache glob, no
`claude plugin list`, no new global, no fallback). Comment: "superpowers
= 7 vendored skills since 2026-09-28; the plugin is gone". A negative
control (empty HOME) must return 1.
7b. lib/doctor-vendored.sh: lock entries may carry `"always_on": true`
(the `superpowers` entry does). Skills of such an entry are expected
LINKED whatever the active profile says (today every EXTERNAL_SKILLS name
absent from the profile is reported `parked`, link unchecked — the 7 are
in no profile by design). Mechanism: `_dv_lock_expectations` (python)
prints a THIRD column `name\tfile\t1` for skills of an `always_on` entry
(awk `$1==n {print $2}` in `_dv_check_files` keeps working unchanged);
`check_vendored_skills` reads the flag and passes it as a 5th parameter to
`_dv_check_link`, which treats `1` as "expected linked whatever the
profile says". If `check_vendored_skills` would exceed 5 locals, extract
the per-name dispatch into a helper (≤ 25 logic lines each). Update the
file header ("A name absent from the profile is reported parked" → "…
unless its lock entry is always_on") and the test header. Message
unchanged for the linked case, fail "<name>: symlink missing/wrong — run:
make link" when absent. Add a case
`ALWAYS_ON_LINK_CHECKED` to lib/tests/doctor-vendored.test.sh (fixture
entry with always_on true, name absent from the profile, link missing →
fail line, never `parked`). Document the field in lib/vendor-skills.sh's
lock-shape header comment (one line: ignored by the vendor helper, read
by doctor-vendored).
8. hooks/session-start.sh: delete line 122 (`detect_superpowers … + 800`)
outright — the banner's ALWAYS_ON list comes from detect_rtk + settings
enabledPlugins (lines ~147-160), not from this call. doctor.sh :225-228:
pass "superpowers: 7 skills vendored + linked (plugins.lock.json, v6.4.1)"
/ fail "superpowers skills not linked — run: make plugin && make link";
the pass line is worded on what `detect_superpowers` proves
("superpowers skills linked (brainstorming found); per-skill check under
Vendored skills"); :423 delete the `+ 1500` line (comment: counted by the
skill catalog stats).
9. settings.json: NOT an executor file any more — the orchestrator edits it
after criterion 2 is green (see Orchestrator steps), so a disabled plugin
never coincides with a failed fetch.
### E2 — citers, routing map, docs
Files: skills/{ship-feature,init-project,tour,deploy,audit-delta,gitflow,profile}/SKILL.md,
lib/{analyze-before-plan,capitalize-commit,doc-commit}.md,
agents/plugin-advisor.md, CLAUDE.global.md, README.md, USAGE.md, CHANGELOG.md.
1. `superpowers:<x>` → `<x>` (bare) in ship-feature ×4, init-project ×4,
tour:318, deploy:515, audit-delta:321, lib/analyze-before-plan.md:106,
agents/plugin-advisor.md:182. Wording around them: "Invoke `brainstorming`
(vendored superpowers skill)" on first mention per file, bare afterwards.
2. finishing-a-development-branch prose: lib/capitalize-commit.md:20 → "Orchestrators
that integrate via `gitflow finish` (the upstream
finishing-a-development-branch is not vendored)"; :68, lib/doc-commit.md:84,
lib/analyze-before-plan.md:108, skills/gitflow:16,110 → say "upstream
superpowers skill, not vendored here; `gitflow finish` is the only
integration path" where they present it as available.
3. CLAUDE.global.md § Skill routing, after the "Before /clear or /compact"
line, ≤ 80 chars per line, about 4 lines, and NEVER the literal
"superpowers" followed by a colon (criterion 3 greps that string):
"- superpowers skills are vendored, called by bare name; an upstream
`superpowers` prefix means the bare skill. Not vendored:
executing-plans → subagent-driven-development;
finishing-a-development-branch → `gitflow finish` (human signal);
systematic-debugging → bugfix; verification-before-completion → the
verifier gates."
Every skill identifier stays WHOLE on its line (criterion 7 greps
`finishing-a-development-branch`, `executing-plans`, `systematic-debugging`
line by line); wrap at spaces only.
4. README.md:121 row → "**Superpowers skills** | Vendored (7, always on) |
brainstorming, writing-plans, subagent-driven development, TDD, code
review request, git worktrees, writing-skills — pinned v6.4.1 in
plugins.lock.json, no plugin, no session injection | obra/superpowers".
README:208 unchanged.
5. USAGE.md: every line presenting superpowers as a plugin to keep ON/OFF or
as ~800 t passive (184-185, 589, 650, 751, 864, 959-965, 971, 995, 1018)
→ "skills superpowers (vendorisés, toujours actifs, 0 t passif)" or the
equivalent in the sentence's French; keep the narrative otherwise.
6. agents/plugin-advisor.md: rows 177-182 (compat matrix) → "superpowers
skills (vendored)" wording, drop the plugin-dev overlap row's "plugin"
framing; recommended-set table 190-198: replace "superpowers" by
"(superpowers skills always on)" in the ON column and subtract ~800 t from
each cost; :80, :146, :242, :254, :298 reword; :324 remedy → "Superpowers
skills missing → `make plugin` (vendors them) then `make link`".
7. skills/profile/SKILL.md:59: "Always-on plugins (`security-guidance`) and
the vendored superpowers skills are never toggled by a profile".
8. CHANGELOG `[Unreleased]`: Changed (superpowers plugin → 7 vendored skills,
pinned, always on; `superpowers:` citers renamed), Removed (plugin, its 8
duplicate skills, the SessionStart injection), Known residual (upstream
cross-references inside the vendored text; CLAUDE.global.md map).
## Orchestrator steps
- Criterion 2 vendors + links live (network fetch of 30 files); only when
every file is present and byte-identical (c2.py) does the next step run.
- Then the orchestrator edits settings.json by hand: remove the
`"superpowers@superpowers-marketplace": true` key from `enabledPlugins` and
the whole `extraKnownMarketplaces."superpowers-marketplace"` block, nothing
else; validate with `python3 -c 'import json;json.load(open("settings.json"))'`.
- Then, one shot by hand: `claude plugin uninstall superpowers@superpowers-marketplace`
and `claude plugin marketplace remove superpowers-marketplace`; re-check
`git diff settings.json` afterwards (the CLI must not have re-added
anything), then criterion 8.
- Rollback if criterion 8 fails: `claude plugin marketplace add
obra/superpowers-marketplace && claude plugin install superpowers@superpowers-marketplace`,
`git checkout -- settings.json`, stop and report.
- Verifier; security; commit; BDR-106 + journal.
## Edge cases
- Mid-migration machine (plugin cached, skills not yet vendored): doctor
fails "not vendored or linked — run make plugin && make link"; the user
uninstalls the plugin by hand (CHANGELOG says so). No fallback that could
print "vendored" for a plugin-only machine.
- Mixed-version rollback (an older checkout re-installs the plugin while the
7 symlinks are still linked → duplicate descriptions): CHANGELOG note
"after a rollback, delete skills/<7> symlinks or re-run the new make plugin".
- The running session keeps the plugin's `superpowers` skills until restart;
the bare names appear after `make link` + a new session.
- Fresh clone: link.sh symlinks a non-existent skills-external dir only if
present (existing `[ -d ]` guard).
- skill-routing-census live run gains 7 descriptions: brainstorming's "You
MUST use this before any creative work" vs personal descriptions — the
suite's live FAIL threshold must not trip (check by running it).
## Tests
- make test suite= vendor-skills, doctor-vendored (with the new
ALWAYS_ON_LINK_CHECKED case), doctrine-citers, skill-routing-census,
profile-default, profile-set-managed.
- shellcheck on every touched shell file.
## Disposition (RELATED MEMORY)
- honors BDR-102 / BDR-104 — vendor over plugin, shared helper, pinned commit,
byte-for-byte text.
- honors BDR-105 — tier 2 of the prune decision.
- honors BDR-065 — docs/superpowers transient path unchanged.
- honors LRN-178 — no new top-level `source`; detect-plugins reads a path.
- honors BDR-077 — requesting-code-review's reviewer dispatch keeps the
model-routing note in ship-feature/init-project.
+23
View File
@@ -74,6 +74,15 @@ skills/scroll-scrubbed-visual-sequence
skills/scroll-scrubbed-word-reveal skills/scroll-scrubbed-word-reveal
skills/scroll-progress-timeline skills/scroll-progress-timeline
# superpowers, vendored (plugins.lock.json 'superpowers')
skills/brainstorming
skills/writing-plans
skills/subagent-driven-development
skills/test-driven-development
skills/requesting-code-review
skills/using-git-worktrees
skills/writing-skills
# Impeccable — NOT a symlink: `impeccable skills install --scope=global` # Impeccable — NOT a symlink: `impeccable skills install --scope=global`
# writes the skill dir (and its ~15 MB engine binary) straight in through the # writes the skill dir (and its ~15 MB engine binary) straight in through the
# ~/.claude/skills symlink. Machine-owned, regenerated by make plugin/update. # ~/.claude/skills symlink. Machine-owned, regenerated by make plugin/update.
@@ -206,6 +215,20 @@ skills-external/scroll-scrubbed-visual-sequence/
skills-external/scroll-scrubbed-word-reveal/ skills-external/scroll-scrubbed-word-reveal/
skills-external/scroll-progress-timeline/ skills-external/scroll-progress-timeline/
# superpowers, vendored (plugins.lock.json 'superpowers') — machine-owned,
# curl'd at the commit pinned in plugins.lock.json by install-plugins.sh
# Step 8e (when absent) and re-fetched at the SAME commit by update-all.sh,
# through the shared lib/vendor-skills.sh helper. Not vendored: this is a
# pin, not a tracked snapshot — bump the commit deliberately to pick up an
# upstream edit.
skills-external/brainstorming/
skills-external/writing-plans/
skills-external/subagent-driven-development/
skills-external/test-driven-development/
skills-external/requesting-code-review/
skills-external/using-git-worktrees/
skills-external/writing-skills/
# 21st.dev skill pack — machine-owned: `21st skills install` output, staged by # 21st.dev skill pack — machine-owned: `21st skills install` output, staged by
# install-plugins.sh Step 8.7 (the installer refuses to write through the # install-plugins.sh Step 8.7 (the installer refuses to write through the
# ~/.claude/skills symlink, so it runs under a throwaway HOME and the skills # ~/.claude/skills symlink, so it runs under a throwaway HOME and the skills
+32
View File
@@ -379,6 +379,21 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
`plugins.lock.json` pin 3.2.0 → 4.1.0 (the CLI only: the skill dist and `plugins.lock.json` pin 3.2.0 → 4.1.0 (the CLI only: the skill dist and
the engine binary have their own release tracks). `link.sh` drops the engine binary have their own release tracks). `link.sh` drops
impeccable from `EXTERNAL_SKILLS`; `skills-external/impeccable/` is gone. impeccable from `EXTERNAL_SKILLS`; `skills-external/impeccable/` is gone.
- **Superpowers plugin replaced by 7 vendored skills** (tier 2 of the
skill-catalog prune, BDR-105/106). `brainstorming`, `writing-plans`,
`subagent-driven-development`, `test-driven-development`,
`requesting-code-review`, `using-git-worktrees` and `writing-skills` are
curled byte-for-byte from `obra/superpowers` at the v6.4.1 commit
(`5bf4e78011075bcfc0dc295f0724994cd123ee71`) via `lib/vendor-skills.sh`
(new `superpowers` entry in `plugins.lock.json`, `always_on: true`),
linked by `link.sh` like the other externals: always on, no profile lists
them, same as `darwin-skill`. Every `superpowers:<skill>` citer across
`skills/`, `agents/` and `lib/` is renamed to the bare skill name.
`CLAUDE.global.md` Skill routing gains a map for the 4 dropped skills this
config used to reference: `executing-plans` to
`subagent-driven-development`, `finishing-a-development-branch` to
`gitflow finish`, `systematic-debugging` to `/bugfix`,
`verification-before-completion` to the verifier gates.
### Security ### Security
- **Ten secret-reader deny rules added**: `sed`, `awk`, `cut`, `tr`, - **Ten secret-reader deny rules added**: `sed`, `awk`, `cut`, `tr`,
@@ -433,6 +448,15 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
with it: the 4 `mcp__magic__*` `permissions.ask` entries (BDR-059), the with it: the 4 `mcp__magic__*` `permissions.ask` entries (BDR-059), the
`MAGIC_API_KEY` block in `.env.example`, `link.sh`'s missing-key warning, `MAGIC_API_KEY` block in `.env.example`, `link.sh`'s missing-key warning,
and the dead `MAGIC_API_KEY=abc123` gitleaks allowlist regex. and the dead `MAGIC_API_KEY=abc123` gitleaks allowlist regex.
- **Superpowers plugin uninstalled**: its 8 other skills
(`executing-plans`, `finishing-a-development-branch`,
`systematic-debugging`, `verification-before-completion`,
`dispatching-parallel-agents`, `receiving-code-review`,
`using-superpowers`, `diagnosing-superpowers`) and its SessionStart
injection (`using-superpowers`, ~3.6 KB every session start) are gone
with it. `lib/profile.sh` no longer protects it; `lib/detect-plugins.sh`
`detect_superpowers` now checks the linked vendored skill instead of the
plugin cache or `claude plugin list`.
### Fixed ### Fixed
- **gstack's shared helper tree was mostly unreachable.** gstack skills - **gstack's shared helper tree was mostly unreachable.** gstack skills
@@ -505,6 +529,14 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
`21st-ui-build` and `21st-cli-use` still point at the now-`max`-only `21st-ui-build` and `21st-cli-use` still point at the now-`max`-only
21st trio. A Skill call on a parked name fails, and the doctrine 21st trio. A Skill call on a parked name fails, and the doctrine
routing in `CLAUDE.global.md` applies instead. routing in `CLAUDE.global.md` applies instead.
- The 7 vendored superpowers skills are byte-for-byte upstream text, never
edited: their internal `superpowers:<x>` mentions and references to the
8 non-vendored skills stay in the prose (their own text, not ours to
patch). `CLAUDE.global.md` Skill routing carries the map for the 4 of
those this config used to reference. After a rollback that re-installs
the plugin while the 7 symlinks are still linked, delete the
`skills/<7>` symlinks or re-run `make plugin` to avoid duplicate skill
descriptions.
## [1.5.0] — 2026-09-13 ## [1.5.0] — 2026-09-13
+6
View File
@@ -258,6 +258,12 @@ cryptic names.
- Design / UI (build, system, audit, polish) → "Design work" below - Design / UI (build, system, audit, polish) → "Design work" below
- Architecture review → plan-eng-review - Architecture review → plan-eng-review
- Before /clear or /compact → capitalize; end-of-session ritual → close - Before /clear or /compact → capitalize; end-of-session ritual → close
- superpowers skills are vendored, called by bare name; an upstream
`superpowers` prefix names the same skill. Not vendored here:
executing-plans → subagent-driven-development
finishing-a-development-branch → `gitflow finish` (human signal)
systematic-debugging → bugfix
verification-before-completion → the verifier gates
- SEO+GEO → seo (GEO only → geo); W3C + WCAG a11y → web-validate; - SEO+GEO → seo (GEO only → geo); W3C + WCAG a11y → web-validate;
security audit (secrets, CVE, OWASP) → cso security audit (secrets, CVE, OWASP) → cso
gstack OFF → its skills (investigate, qa, review, health, retro, gstack OFF → its skills (investigate, qa, review, health, retro,
+1 -1
View File
@@ -118,7 +118,7 @@ ctx7 login # optional: OAuth / API key for higher rate limits
| Component | Type | Description | Docs | | Component | Type | Description | Docs |
|---|---|---|---| |---|---|---|---|
| **Superpowers** | Plugin (required) | Brainstorming, planning, subagent-driven dev, code review, branch finishing. Required by `/init-project` and `/ship-feature`. | [obra/superpowers-marketplace](https://github.com/obra/superpowers-marketplace) | | **Superpowers skills** | Vendored (7, always on) | brainstorming, writing-plans, subagent-driven development, TDD, code review request, git worktrees, writing-skills — pinned v6.4.1 in plugins.lock.json, no plugin, no session injection | [obra/superpowers](https://github.com/obra/superpowers) |
| **GStack** | Plugin (toggle) | Full-product workflow: UI + design + deploy + browser QA. Skip for backend/CLI projects. | [garrytan/gstack](https://github.com/garrytan/gstack) | | **GStack** | Plugin (toggle) | Full-product workflow: UI + design + deploy + browser QA. Skip for backend/CLI projects. | [garrytan/gstack](https://github.com/garrytan/gstack) |
| **GSD v2** | External CLI | Multi-session orchestration: crash recovery, cost tracking, parallel workers, context-fresh execution. | [gsd-build/gsd-2](https://github.com/gsd-build/gsd-2) | | **GSD v2** | External CLI | Multi-session orchestration: crash recovery, cost tracking, parallel workers, context-fresh execution. | [gsd-build/gsd-2](https://github.com/gsd-build/gsd-2) |
| **RTK** | Plugin (always on) | Code rewrite hook. Zero passive cost. | [rtk-ai/rtk](https://github.com/rtk-ai/rtk) | | **RTK** | Plugin (always on) | Code rewrite hook. Zero passive cost. | [rtk-ai/rtk](https://github.com/rtk-ai/rtk) |
+16 -15
View File
@@ -181,8 +181,8 @@ Deploy + QA browser → gstack ON
Next.js/React/Prisma → context7 ON (WARN si absent, pas BLOCK) Next.js/React/Prisma → context7 ON (WARN si absent, pas BLOCK)
Multi-session (>1 jour) → gsd v2 CLI (gsd dans terminal) Multi-session (>1 jour) → gsd v2 CLI (gsd dans terminal)
Backend/CLI seulement → tout OFF sauf superpowers Backend/CLI seulement → tout OFF (skills superpowers vendorisés, toujours actifs, 0 t passif)
Hotfix/quick fix → tout OFF sauf superpowers Hotfix/quick fix → tout OFF (skills superpowers vendorisés, toujours actifs, 0 t passif)
``` ```
**GSD v2** n'est pas un plugin Claude Code — c'est un CLI externe. Il ne consomme pas de tokens passifs. Tu le lances dans un terminal séparé avec `gsd`, puis `/gsd auto` pour le mode autonome. **GSD v2** n'est pas un plugin Claude Code — c'est un CLI externe. Il ne consomme pas de tokens passifs. Tu le lances dans un terminal séparé avec `gsd`, puis `/gsd auto` pour le mode autonome.
@@ -586,7 +586,7 @@ ONBOARD COMPLETE: mycli
→ SIGNALS: none (CLI pur) → SIGNALS: none (CLI pur)
→ DISABLE: ui-ux-pro-max, gstack, context7 → DISABLE: ui-ux-pro-max, gstack, context7
→ KEEP: superpowers → (skills superpowers vendorisés, toujours actifs, 0 t passif)
→ COST: ~800t (minimal) → COST: ~800t (minimal)
→ ACTION REQUIRED? NO → ACTION REQUIRED? NO
``` ```
@@ -647,7 +647,7 @@ DO NOT TOUCH:
/plugin-check "CLI Rust, convertisseur de fichiers JSON/CSV/TOML, pas de réseau, pas de frontend" /plugin-check "CLI Rust, convertisseur de fichiers JSON/CSV/TOML, pas de réseau, pas de frontend"
→ SIGNALS: none (CLI pur, pas de deploy, pas de frontend) → SIGNALS: none (CLI pur, pas de deploy, pas de frontend)
→ KEEP: superpowers → (skills superpowers vendorisés, toujours actifs, 0 t passif)
→ DISABLE: ui-ux-pro-max, gstack, context7 → DISABLE: ui-ux-pro-max, gstack, context7
→ COST: ~800t (base seulement) → COST: ~800t (base seulement)
→ ACTION REQUIRED? NO → ACTION REQUIRED? NO
@@ -748,7 +748,7 @@ Simple à valider. L'architecture proposée est plate, pas de surprise.
**Contexte :** module `services/payment_service.py` dans un projet FastAPI existant. Écrit il y a 2 ans, jamais refactorisé. Violations connues : fonctions de 80 lignes, global state, pas de tests unitaires, logique métier mélangée avec appels HTTP. **Contexte :** module `services/payment_service.py` dans un projet FastAPI existant. Écrit il y a 2 ans, jamais refactorisé. Violations connues : fonctions de 80 lignes, global state, pas de tests unitaires, logique métier mélangée avec appels HTTP.
**Setup :** projet déjà onboardé (CLAUDE.md présent), superpowers actif, plugins inutiles désactivés. **Setup :** projet déjà onboardé (CLAUDE.md présent), skills superpowers vendorisés (toujours actifs, 0 t passif), plugins inutiles désactivés.
#### Étape 1 — Analyse avant toute modification #### Étape 1 — Analyse avant toute modification
@@ -861,7 +861,7 @@ PROJECT STATUS
CONFIG CONFIG
Version : v2.5.0 Version : v2.5.0
Plugins ON: superpowers, context7 (~1000t) Plugins ON: context7 (~200t), skills superpowers vendorisés (toujours actifs, 0 t passif)
GSD v2 : installed (2.64.0) GSD v2 : installed (2.64.0)
PROJECT PROJECT
@@ -956,19 +956,20 @@ GSD v2 met à jour le plan dans `.gsd/ROADMAP.md` sans perdre le travail déjà
/plugin-check "Firmware C STM32, bare-metal, pas de réseau, pas de frontend, pas de Docker" /plugin-check "Firmware C STM32, bare-metal, pas de réseau, pas de frontend, pas de Docker"
SIGNALS: simple, CLI/embedded SIGNALS: simple, CLI/embedded
COST: ~800t (superpowers seul) COST: ~0t (skills superpowers vendorisés, toujours actifs, 0 t passif)
RECOMMENDATIONS: RECOMMENDATIONS:
OK KEEP : superpowers (peut être utile pour brainstorm initial)
DISABLE : ui-ux-pro-max, gstack, context7 DISABLE : ui-ux-pro-max, gstack, context7
NOTE : Pour un firmware vraiment simple (hotfix, modification ciblée), NOTE : skills superpowers (brainstorming, writing-plans...) restent
même superpowers peut être désactivé → ~0t passif disponibles par nom bare sans coût passif, même pour un
firmware minimal.
``` ```
**Workflow minimaliste — modification d'un driver existant :** **Workflow minimaliste — modification d'un driver existant :**
``` ```
# Pas de /init-project, pas de GSD, pas de superpowers # Pas de /init-project, pas de GSD ; skills superpowers vendorisés
# (toujours actifs, 0 t passif) mais non invoqués ici
# 1. Comprendre avant de modifier # 1. Comprendre avant de modifier
/analyze src/drivers/uart.c /analyze src/drivers/uart.c
@@ -992,7 +993,7 @@ OUTPUT:
/ship-feature "Corriger l'accès non-atomique au ring_buffer_head dans l'ISR" /ship-feature "Corriger l'accès non-atomique au ring_buffer_head dans l'ISR"
STEP 0b — CLAUDE.md found STEP 0b — CLAUDE.md found
STEP 0 — plugin check: superpowers OK (ou désactivé si YOLO mode) STEP 0 — plugin check: skills superpowers vendorisés (toujours actifs, 0 t passif)
STEP 1 — BRAINSTORM (rapide, contexte déjà clair depuis /analyze): STEP 1 — BRAINSTORM (rapide, contexte déjà clair depuis /analyze):
Design: protéger ring_buffer_head avec __disable_irq()/__enable_irq() Design: protéger ring_buffer_head avec __disable_irq()/__enable_irq()
@@ -1015,7 +1016,7 @@ STEP 4 — IMPLEMENT (subagents légers, modifications chirurgicales)
``` ```
**Points clés :** **Points clés :**
- `/plugin-check` confirme "superpowers seulement" → aucun plugin inutile actif. - `/plugin-check` confirme qu'aucun plugin inutile n'est actif (skills superpowers vendorisés, toujours actifs, 0 t passif).
- `/analyze` est particulièrement utile sur du code C bas-niveau : l'analyzer identifie les accès non-atomiques, les race conditions, les violations de normes, **sans proposer de fix**. - `/analyze` est particulièrement utile sur du code C bas-niveau : l'analyzer identifie les accès non-atomiques, les race conditions, les violations de normes, **sans proposer de fix**.
- Pour un firmware, le workflow `analyze → ship-feature` peut se réduire à `analyze → edit direct` si la modification est triviale. - Pour un firmware, le workflow `analyze → ship-feature` peut se réduire à `analyze → edit direct` si la modification est triviale.
- GSD v2 n'est jamais pertinent pour du firmware : les sessions sont courtes et les tâches atomiques. - GSD v2 n'est jamais pertinent pour du firmware : les sessions sont courtes et les tâches atomiques.
@@ -1031,7 +1032,7 @@ Prisma / Supabase → context7 ON
"design élaboré" / tokens → ui-ux-pro-max ON "design élaboré" / tokens → ui-ux-pro-max ON
Docker + QA browser → gstack ON Docker + QA browser → gstack ON
"plusieurs semaines" → gsd v2 CLI "plusieurs semaines" → gsd v2 CLI
Rust / Python / Go / C → tout OFF sauf superpowers Rust / Python / Go / C → tout OFF (skills superpowers vendorisés, 0t)
Mobile / Flutter / RN → gstack OFF Mobile / Flutter / RN → gstack OFF
Hotfix / script rapide → tout OFF sauf superpowers Hotfix / script rapide → tout OFF (skills superpowers vendorisés, 0t)
``` ```
+23 -21
View File
@@ -77,7 +77,7 @@ Factors (weighted):
| Infra/deploy | 15% | Local only | Single deploy target | Multi-env, CI/CD, containers, monitoring | | Infra/deploy | 15% | Local only | Single deploy target | Multi-env, CI/CD, containers, monitoring |
**Score thresholds:** **Score thresholds:**
- **0-30% (simple)**: superpowers only. No gstack, no gsd, no ctx7, no graphify. - **0-30% (simple)**: superpowers skills only (vendored, always on). No gstack, no gsd, no ctx7, no graphify.
_Examples: site vitrine, landing page, script CLI, simple CRUD._ _Examples: site vitrine, landing page, script CLI, simple CRUD._
- **30-60% (moderate)**: + context7 if fast-libs. graphify only once the codebase passes 200 tracked code files (session-start banner informs, the user decides — BDR-097), never at scaffold. - **30-60% (moderate)**: + context7 if fast-libs. graphify only once the codebase passes 200 tracked code files (session-start banner informs, the user decides — BDR-097), never at scaffold.
_Examples: blog with auth, dashboard with charts, API with validation._ _Examples: blog with auth, dashboard with charts, API with validation._
@@ -143,7 +143,7 @@ ACTION REQUIRED? YES / NO
| `fast-libs` | context7 | — | Doc freshness critical | | `fast-libs` | context7 | — | Doc freshness critical |
| `multi-agent` + `complex-arch` | gsd v2 CLI | — | GSD v2 preferred for multi-session coordination | | `multi-agent` + `complex-arch` | gsd v2 CLI | — | GSD v2 preferred for multi-session coordination |
| `simple` / single-session | — | gsd, gstack, ui-ux-pro-max | Saves ~3000-5000t | | `simple` / single-session | — | gsd, gstack, ui-ux-pro-max | Saves ~3000-5000t |
| `embedded` / firmware | — | all toggles; superpowers optional | workflow: /analyze → /hotfix or /bugfix or /ship-feature | | `embedded` / firmware | — | all toggles (superpowers skills vendored, always on) | workflow: /analyze → /hotfix or /bugfix or /ship-feature |
| backend/lib/CLI only | — | ui-ux-pro-max, gstack | ~3100t saved | | backend/lib/CLI only | — | ui-ux-pro-max, gstack | ~3100t saved |
| small project / hotfix | — | gstack, gsd | Use /hotfix, /bugfix, or /feat | | small project / hotfix | — | gstack, gsd | Use /hotfix, /bugfix, or /feat |
@@ -174,12 +174,12 @@ When the plugin-advisor detects a `simple` or `hotfix` signal, suggest the appro
| Pair | Relation | Verdict | | Pair | Relation | Verdict |
|---|---|---| |---|---|---|
| gstack ↔ gsd v2 | ✅ Complementary | GStack = full-product CC workflow. GSD v2 = multi-session CLI. Different scopes, no conflict. | | gstack ↔ gsd v2 | ✅ Complementary | GStack = full-product CC workflow. GSD v2 = multi-session CLI. Different scopes, no conflict. |
| superpowers ↔ gsd v2 | ✅ Complementary | Superpowers = single-session execution. GSD v2 = multi-session CLI orchestration. No conflict. | | superpowers ↔ gsd v2 | ✅ Complementary | superpowers skills (vendored) = single-session execution. GSD v2 = multi-session CLI orchestration. No conflict. |
| superpowers ↔ gstack | ✅ Complementary | Used together in /init-project and /ship-feature. Superpowers = engine, GStack = full-product skills. | | superpowers ↔ gstack | ✅ Complementary | Used together in /init-project and /ship-feature. superpowers skills (vendored) = engine, GStack = full-product skills. |
| context7 ↔ any | ✅ Independent | Doc lookup CLI (ctx7), no workflow overlap. Always safe to combine. | | context7 ↔ any | ✅ Independent | Doc lookup CLI (ctx7), no workflow overlap. Always safe to combine. |
| plugin-dev ↔ superpowers | ⚠️ Minor overlap | Superpowers can create skills too. Keep plugin-dev only when actively building new plugins/skills. | | plugin-dev ↔ superpowers | ⚠️ Minor overlap | superpowers skills (vendored) can create skills too (writing-skills). Keep plugin-dev only when actively building new plugins. |
| ui-ux-pro-max ↔ gstack | ✅ Complementary | GStack = deploy/QA layer; ui-ux-pro-max = UI quality layer. Different concerns. | | ui-ux-pro-max ↔ gstack | ✅ Complementary | GStack = deploy/QA layer; ui-ux-pro-max = UI quality layer. Different concerns. |
| pr-review-toolkit ↔ superpowers | ✅ Complementary | superpowers:requesting-code-review and /pr-review-toolkit:review-pr cover different review styles. | | pr-review-toolkit ↔ superpowers | ✅ Complementary | `requesting-code-review` (vendored superpowers skill) and /pr-review-toolkit:review-pr cover different review styles. |
| rtk ↔ any | ✅ Independent | Hook-only token compression. Zero interaction with any plugin. | | rtk ↔ any | ✅ Independent | Hook-only token compression. Zero interaction with any plugin. |
| security-guidance ↔ any | ✅ Independent | Hooks + out-of-band LLM reviews (agentic review on commit/push; Stop diff review disabled by ENABLE_STOP_REVIEW=0). No context injection unless a regex hits. | | security-guidance ↔ any | ✅ Independent | Hooks + out-of-band LLM reviews (agentic review on commit/push; Stop diff review disabled by ENABLE_STOP_REVIEW=0). No context injection unless a regex hits. |
@@ -187,15 +187,15 @@ When the plugin-advisor detects a `simple` or `hotfix` signal, suggest the appro
| Project type | Plugins ON | OFF | Passive cost | | Project type | Plugins ON | OFF | Passive cost |
|---|---|---|---| |---|---|---|---|
| Backend API / microservice | superpowers, context7 (if fast libs) | ui-ux-pro-max, gstack | ~800t | | Backend API / microservice | (superpowers skills always on), context7 (if fast libs) | ui-ux-pro-max, gstack | ~0t |
| Frontend SPA / SSR | superpowers, ui-ux-pro-max, frontend-design, design-motion-principles, context7 | gstack | ~1400t | | Frontend SPA / SSR | (superpowers skills always on), ui-ux-pro-max, frontend-design, design-motion-principles, context7 | gstack | ~600t |
| Full-stack SaaS | superpowers, gstack, ui-ux-pro-max, frontend-design, design-motion-principles, context7 | — | ~4200t | | Full-stack SaaS | (superpowers skills always on), gstack, ui-ux-pro-max, frontend-design, design-motion-principles, context7 | — | ~3400t |
| CLI tool / library | superpowers | all toggles | ~800t | | CLI tool / library | (superpowers skills always on) | all toggles | ~0t |
| Multi-session large feature | superpowers + gsd v2 CLI (external) | — | ~800t CC | | Multi-session large feature | (superpowers skills always on) + gsd v2 CLI (external) | — | ~0t CC |
| Quick fix / hotfix | superpowers | all toggles | ~800t | | Quick fix / hotfix | (superpowers skills always on) | all toggles | ~0t |
| Design system / component lib | superpowers, ui-ux-pro-max, frontend-design, design-motion-principles | gstack, gsd | ~1200t | | Design system / component lib | (superpowers skills always on), ui-ux-pro-max, frontend-design, design-motion-principles | gstack, gsd | ~400t |
| Fast-evolving libs (Next.js etc.) | superpowers, context7 | — | ~1000t | | Fast-evolving libs (Next.js etc.) | (superpowers skills always on), context7 | — | ~200t |
| Enterprise multi-agent orchestration | superpowers + gsd v2 (external) | plugin-dev | ~800t CC | | Enterprise multi-agent orchestration | (superpowers skills always on) + gsd v2 (external) | plugin-dev | ~0t CC |
> rtk is always on at 0 context tokens; security-guidance is always on and > rtk is always on at 0 context tokens; security-guidance is always on and
> costs quota out of band (LLM reviews), not context — both omitted from > costs quota out of band (LLM reviews), not context — both omitted from
@@ -239,8 +239,9 @@ RULE: IF "simple" OR "hotfix":
RULE: IF "embedded" signal (firmware, bare-metal, microcontroller, or Makefile+C without Node/Rust/Go): RULE: IF "embedded" signal (firmware, bare-metal, microcontroller, or Makefile+C without Node/Rust/Go):
→ Disable ALL toggles including gstack, context7, plugin-dev → Disable ALL toggles including gstack, context7, plugin-dev
→ superpowers OPTIONAL: useful for initial design brainstorm on complex drivers, → superpowers skills stay on (vendored, no toggle): useful for initial
but unnecessary for single-function patches — user decides design brainstorm on complex drivers, unnecessary for single-function
patches; just don't invoke them, no disable needed
→ GSD v2 CLI: not recommended (sessions are short, tasks are atomic) → GSD v2 CLI: not recommended (sessions are short, tasks are atomic)
→ Recommend workflow: /analyze <file> → /hotfix (patch) or /bugfix (investigation) or /ship-feature (multi-file) → Recommend workflow: /analyze <file> → /hotfix (patch) or /bugfix (investigation) or /ship-feature (multi-file)
→ NOTE: print "embedded project detected — minimal plugin footprint recommended" → NOTE: print "embedded project detected — minimal plugin footprint recommended"
@@ -251,7 +252,7 @@ RULE: IF plugin-dev ON AND no `skill-creation` signal detected:
RULE: IF `skill-creation` signal: RULE: IF `skill-creation` signal:
→ plugin-dev ON (~100t) → plugin-dev ON (~100t)
→ superpowers ON — required for skill scaffolding → superpowers skills (vendored, always on): used for skill scaffolding (writing-skills)
RULE: IF `browser-qa` signal (e2e tests, Playwright/Cypress/Puppeteer in deps): RULE: IF `browser-qa` signal (e2e tests, Playwright/Cypress/Puppeteer in deps):
→ gstack ON — browser automation and QA → gstack ON — browser automation and QA
@@ -295,8 +296,9 @@ gstack + managed plugins — sessions stay focused and passive token cost drops.
`profile set <name>` actually toggles plugins (`claude plugin enable|disable`) `profile set <name>` actually toggles plugins (`claude plugin enable|disable`)
and external skill packs (delegates to `lib/toggle-external.sh`) — not just and external skill packs (delegates to `lib/toggle-external.sh`) — not just
advisory. No MCP server is auto-toggled today. Always-on plugins (`security-guidance`, `superpowers`) advisory. No MCP server is auto-toggled today. Always-on plugins (`security-guidance`)
are protected. Managed plugins that `set` may toggle: and the vendored superpowers skills are never toggled by a profile. Managed
plugins that `set` may toggle:
`ui-ux-pro-max@ui-ux-pro-max-skill`, `plugin-dev@claude-code-plugins`, `ui-ux-pro-max@ui-ux-pro-max-skill`, `plugin-dev@claude-code-plugins`,
`pr-review-toolkit@claude-code-plugins`. Other plugins are never auto-toggled. `pr-review-toolkit@claude-code-plugins`. Other plugins are never auto-toggled.
@@ -321,7 +323,7 @@ toggles the managed plugins like any `set`).
## BLOCK if ## BLOCK if
- Superpowers not active → install: `claude plugin marketplace add obra/superpowers-marketplace && claude plugin install --scope user superpowers@superpowers-marketplace` - Superpowers skills missing → `make plugin` (vendors them) then `make link`
- Full-product (UI+deploy+QA) + gstack not installed - Full-product (UI+deploy+QA) + gstack not installed
## WARN (no block) ## WARN (no block)
+5 -5
View File
@@ -223,9 +223,9 @@ else
fi fi
if detect_superpowers; then if detect_superpowers; then
pass "Superpowers plugin detected" pass "superpowers skills linked (brainstorming found); per-skill check under Vendored skills"
else else
fail "Superpowers not detected — orchestrators (/init-project, /ship-feature) will fail" fail "superpowers skills not linked — run: make plugin && make link"
fi fi
if detect_context7; then if detect_context7; then
@@ -417,10 +417,10 @@ SKILL_DESC_TOKENS=$((SKILL_DESC_CHARS / 4))
# Plugin passive cost estimates (tokens) — session-start injections and # Plugin passive cost estimates (tokens) — session-start injections and
# hook prompts that never show up as a skill description above. gstack, # hook prompts that never show up as a skill description above. gstack,
# context7 (find-docs) and graphifyy dropped 2026-09-28 (skill-catalog # context7 (find-docs) and graphifyy dropped 2026-09-28 (skill-catalog
# prune): their skills sit under ~/.claude/skills and are already counted # prune); superpowers dropped the same day (tier 2, vendored instead):
# by the stats above — a separate constant here double-counted them. # their skills sit under ~/.claude/skills and are already counted by the
# stats above — a separate constant here double-counted them.
PLUGIN_TOKENS=0 PLUGIN_TOKENS=0
if detect_superpowers 2>/dev/null; then PLUGIN_TOKENS=$((PLUGIN_TOKENS + 1500)); fi
if detect_uiux_pro_max 2>/dev/null; then PLUGIN_TOKENS=$((PLUGIN_TOKENS + 670)); fi if detect_uiux_pro_max 2>/dev/null; then PLUGIN_TOKENS=$((PLUGIN_TOKENS + 670)); fi
TOTAL_TOKENS=$((CLAUDE_MD_TOKENS + SKILL_DESC_TOKENS + PLUGIN_TOKENS)) TOTAL_TOKENS=$((CLAUDE_MD_TOKENS + SKILL_DESC_TOKENS + PLUGIN_TOKENS))
+2 -1
View File
@@ -118,8 +118,9 @@ esac
# Quick passive token cost estimate # Quick passive token cost estimate
# Only count plugins that are ACTIVE (detected as ON), not just installed # Only count plugins that are ACTIVE (detected as ON), not just installed
# superpowers dropped 2026-09-28 (tier 2 of the skill-catalog prune): its
# 7 vendored skills are counted by the skill catalog, not a plugin cost.
_passive_t=0 _passive_t=0
detect_superpowers 2>/dev/null && _passive_t=$((_passive_t + 800))
# Token costs for toggle plugins — map display name to cost # Token costs for toggle plugins — map display name to cost
declare -A _plugin_costs=( declare -A _plugin_costs=(
+19 -17
View File
@@ -487,8 +487,8 @@ install_plugin() {
# copies the plugin into ~/.claude/plugins/cache — it does NOT register # copies the plugin into ~/.claude/plugins/cache — it does NOT register
# it in settings.json's enabledPlugins map. Without an explicit enable, # it in settings.json's enabledPlugins map. Without an explicit enable,
# the plugin sits dormant. Use this for plugins that should be ALWAYS ON # the plugin sits dormant. Use this for plugins that should be ALWAYS ON
# (security-guidance, superpowers). Idempotent: skips if already # (security-guidance). Idempotent: skips if already present in
# present in enabledPlugins. # enabledPlugins.
enable_plugin() { enable_plugin() {
local name="$1" local name="$1"
local source="$2" local source="$2"
@@ -531,13 +531,10 @@ install_plugin "pr-review-toolkit" "claude-code-plugins"
echo "" echo ""
# Superpowers (always on) # Superpowers plugin removed 2026-09-28 (tier 2 of the skill-catalog prune):
info "Adding Superpowers marketplace..." # its 7 wired skills are vendored in Step 8e (plugins.lock.json
claude plugin marketplace add obra/superpowers-marketplace 2>/dev/null || true # 'superpowers'); a still-cached plugin is uninstalled by hand once
install_plugin "superpowers" "superpowers-marketplace" # (claude plugin uninstall superpowers@superpowers-marketplace), never here
enable_plugin "superpowers" "superpowers-marketplace"
echo ""
# UI/UX Pro Max (toggle) # UI/UX Pro Max (toggle)
info "Adding UI/UX Pro Max marketplace..." info "Adding UI/UX Pro Max marketplace..."
@@ -909,21 +906,25 @@ fi
echo "" echo ""
# ── Step 8e: Agent Skills (addyosmani/agent-skills) + Mengto scroll # ── Step 8e: Agent Skills (addyosmani/agent-skills) + Mengto scroll
# skills (MengTo/Skills) — both commit-pinned, vendored the emil-design-eng # skills (MengTo/Skills) + superpowers (obra/superpowers) — all
# way (curl → skills-external/<name>/, symlinked by link.sh) through the # commit-pinned, vendored the emil-design-eng way (curl →
# shared lib/vendor-skills.sh helper. Shas/paths/file-lists live in # skills-external/<name>/, symlinked by link.sh) through the shared
# plugins.lock.json ("agent-skills" / "mengto-skills" entries), never # lib/vendor-skills.sh helper. Shas/paths/file-lists live in
# hardcoded here. # plugins.lock.json ("agent-skills" / "mengto-skills" / "superpowers"
echo "── Step 8e: Agent Skills + Mengto scroll skills (pinned commit) ──" # entries), never hardcoded here.
echo "── Step 8e: Agent Skills + Mengto scroll skills + superpowers (pinned commit) ──"
echo "" echo ""
# shellcheck source=lib/vendor-skills.sh disable=SC1091 # shellcheck source=lib/vendor-skills.sh disable=SC1091
source "$REPO/lib/vendor-skills.sh" source "$REPO/lib/vendor-skills.sh"
EXT_SKILL_NAMES=(observability-and-instrumentation deprecation-and-migration EXT_SKILL_NAMES=(observability-and-instrumentation deprecation-and-migration
ci-cd-and-automation scroll-world-storytelling build-threejs-scroll-worlds ci-cd-and-automation scroll-world-storytelling build-threejs-scroll-worlds
scroll-scrubbed-visual-sequence scroll-scrubbed-word-reveal scroll-scrubbed-visual-sequence scroll-scrubbed-word-reveal
scroll-progress-timeline) scroll-progress-timeline brainstorming writing-plans
subagent-driven-development test-driven-development
requesting-code-review using-git-worktrees writing-skills)
vendor_pinned_skills agent-skills vendor_pinned_skills agent-skills
vendor_pinned_skills mengto-skills vendor_pinned_skills mengto-skills
vendor_pinned_skills superpowers
for _ext_skill in "${EXT_SKILL_NAMES[@]}"; do for _ext_skill in "${EXT_SKILL_NAMES[@]}"; do
if [ -L "$HOME/.claude/skills/$_ext_skill" ]; then if [ -L "$HOME/.claude/skills/$_ext_skill" ]; then
ok "$_ext_skill symlink OK" ok "$_ext_skill symlink OK"
@@ -1207,7 +1208,7 @@ echo ""
echo " ALWAYS ON (installed at user scope):" echo " ALWAYS ON (installed at user scope):"
echo " ✅ security-guidance — regex hints on Edit/Write + out-of-band LLM reviews on commit/push (Stop review off via ENABLE_STOP_REVIEW=0; quota, not context) [claude-code-plugins]" echo " ✅ security-guidance — regex hints on Edit/Write + out-of-band LLM reviews on commit/push (Stop review off via ENABLE_STOP_REVIEW=0; quota, not context) [claude-code-plugins]"
echo " ✅ rtk — token compression hook (0 tokens)" echo " ✅ rtk — token compression hook (0 tokens)"
echo " ✅ superpowers — brainstorm/plan/implement/debug workflow" echo " ✅ superpowers skills — 7 vendored (brainstorming, writing-plans, subagent-driven-development, test-driven-development, requesting-code-review, using-git-worktrees, writing-skills), pinned v6.4.1, curl → symlink, no plugin, no session injection"
echo "" echo ""
echo " TOGGLE (plugin state = settings.json enabledPlugins; skills/CLIs = profiles):" echo " TOGGLE (plugin state = settings.json enabledPlugins; skills/CLIs = profiles):"
echo " 🔄 gstack — disabled by default (toggle: lib/toggle-external.sh enable gstack)" echo " 🔄 gstack — disabled by default (toggle: lib/toggle-external.sh enable gstack)"
@@ -1232,6 +1233,7 @@ echo " Frontend Design at: ~/.claude/skills/frontend-design/ (symlink → skill
echo " Design Motion Principles at: ~/.claude/skills/design-motion-principles/ (symlink → skills-external)" echo " Design Motion Principles at: ~/.claude/skills/design-motion-principles/ (symlink → skills-external)"
echo " Agent Skills trio at: ~/.claude/skills/{observability-and-instrumentation,deprecation-and-migration,ci-cd-and-automation}/ (symlink → skills-external)" echo " Agent Skills trio at: ~/.claude/skills/{observability-and-instrumentation,deprecation-and-migration,ci-cd-and-automation}/ (symlink → skills-external)"
echo " Mengto scroll skills at: ~/.claude/skills/{scroll-world-storytelling,build-threejs-scroll-worlds,scroll-scrubbed-visual-sequence,scroll-scrubbed-word-reveal,scroll-progress-timeline}/ (symlink → skills-external)" echo " Mengto scroll skills at: ~/.claude/skills/{scroll-world-storytelling,build-threejs-scroll-worlds,scroll-scrubbed-visual-sequence,scroll-scrubbed-word-reveal,scroll-progress-timeline}/ (symlink → skills-external)"
echo " Superpowers skills at: ~/.claude/skills/{brainstorming,writing-plans,subagent-driven-development,test-driven-development,requesting-code-review,using-git-worktrees,writing-skills}/ (symlink → skills-external)"
echo " npx skills at: ~/.agents/skills/ (symlinked into ~/.claude/skills/)" echo " npx skills at: ~/.agents/skills/ (symlinked into ~/.claude/skills/)"
echo "" echo ""
echo " → Restart Claude Code — plugins load automatically" echo " → Restart Claude Code — plugins load automatically"
+4 -3
View File
@@ -103,9 +103,10 @@ backfill, if ever wanted, is `/prune-memory` passe D — never this snippet.
## ORDERING (orchestrators only) ## ORDERING (orchestrators only)
`superpowers:brainstorming` / `writing-plans` are external skills — we cannot make them `brainstorming` / `writing-plans` (vendored superpowers skills) are external skills — we
read our registries. So this runs BEFORE them, pre-loading the disposition into the plan cannot make them read our registries. So this runs BEFORE them, pre-loading the
they form. Mirror of capitalize-commit running BEFORE finishing-a-development-branch: there disposition into the plan they form. Mirror of capitalize-commit running BEFORE
`gitflow finish` (the upstream finishing-a-development-branch is not vendored): there
the memory commit must precede integration; here the memory read must precede planning. the memory commit must precede integration; here the memory read must precede planning.
## NO-OP / IDEMPOTENT ## NO-OP / IDEMPOTENT
+10 -8
View File
@@ -17,9 +17,10 @@ code already committed.
- Inline-commit flows (feat / hotfix / bugfix / commit-change): run it right - Inline-commit flows (feat / hotfix / bugfix / commit-change): run it right
after writing the entries, on the current branch. after writing the entries, on the current branch.
- Orchestrators that integrate via `superpowers:finishing-a-development-branch` - Orchestrators that integrate via `gitflow finish` (the upstream
(ship-feature / init-project): run it BEFORE the FINISH step — otherwise the finishing-a-development-branch is not vendored; ship-feature / init-project):
memory commit strands outside the merge/PR. See ORDERING. run it BEFORE the FINISH step — otherwise the memory commit strands outside
the merge/PR. See ORDERING.
This snippet commits whatever is PENDING under `.claude/memory` + `.claude/tasks`; This snippet commits whatever is PENDING under `.claude/memory` + `.claude/tasks`;
it does NOT decide content. A flow whose gate wrote only a journal line yields a it does NOT decide content. A flow whose gate wrote only a journal line yields a
@@ -65,11 +66,12 @@ no-match pathspec is filtered, not fatal).
## ORDERING (orchestrators only) ## ORDERING (orchestrators only)
`finishing-a-development-branch` may merge-and-delete the branch or push a PR. A `finishing-a-development-branch` (upstream superpowers skill, not vendored
memory commit created AFTER it lands outside the integrated history — stranded here; `gitflow finish` is the only integration path) may merge-and-delete the
on the PR path. So in ship-feature / init-project this snippet runs BEFORE branch or push a PR. A memory commit created AFTER it lands outside the
FINISH. The code commits already exist (implementation step), so the entries' integrated history — stranded on the PR path. So in ship-feature / init-project
hash references are valid at this point. this snippet runs BEFORE FINISH. The code commits already exist (implementation
step), so the entries' hash references are valid at this point.
## WHAT THIS DOES NOT DO ## WHAT THIS DOES NOT DO
+4 -8
View File
@@ -16,14 +16,10 @@ detect_rtk() {
} }
detect_superpowers() { detect_superpowers() {
# Fast check: filesystem (plugin cache) # superpowers = 7 vendored skills since 2026-09-28; the plugin is gone.
local cache_dir="$HOME/.claude/plugins/cache" # One file test on the linked vendored skill: proves vendored AND
if [ -d "$cache_dir" ]; then # linked in one shot — no plugin cache glob, no `claude plugin list`.
compgen -G "$cache_dir"/*superpowers* &>/dev/null && return 0 [ -f "$HOME/.claude/skills/brainstorming/SKILL.md" ]
fi
# Slow fallback: CLI (only if fast check fails)
claude plugin list 2>/dev/null | grep -qi "superpowers" && return 0
return 1
} }
+5 -4
View File
@@ -81,10 +81,11 @@ do NOT bypass them:
## ORDERING (orchestrators) ## ORDERING (orchestrators)
`finishing-a-development-branch` merges/pushes COMMITTED history only — it never commits `finishing-a-development-branch` (upstream superpowers skill, not vendored here;
working-tree changes. A doc patch left uncommitted (or committed AFTER it) never reaches `gitflow finish` is the only integration path) merges/pushes COMMITTED history only — it
the merge/PR. So this snippet runs BEFORE FINISH: the doc commit lands on the branch FINISH never commits working-tree changes. A doc patch left uncommitted (or committed AFTER it)
integrates. Consumption is MECHANICAL (LRN-057 case a, like the memory commit) — production never reaches the merge/PR. So this snippet runs BEFORE FINISH: the doc commit lands on
the branch FINISH integrates. Consumption is MECHANICAL (LRN-057 case a, like the memory commit) — production
on the branch = consumption by the merge, automatic. on the branch = consumption by the merge, automatic.
## ACKNOWLEDGMENTS (conscious, not glossed) ## ACKNOWLEDGMENTS (conscious, not glossed)
+53 -20
View File
@@ -5,8 +5,8 @@
# EXTERNAL_SKILLS array). doctor.sh's "GStack submodule" section only # EXTERNAL_SKILLS array). doctor.sh's "GStack submodule" section only
# covers the gstack submodule — this covers the OTHER external skill # covers the gstack submodule — this covers the OTHER external skill
# packs (emil-design-eng, the agent-skills trio, the five Mengto scroll # packs (emil-design-eng, the agent-skills trio, the five Mengto scroll
# skills, and any name link.sh links with no lock entry at all, e.g. # skills, the seven superpowers skills, and any name link.sh links with
# frontend-design, design-motion-principles). # no lock entry at all, e.g. frontend-design, design-motion-principles).
# #
# One entry point, `check_vendored_skills <repo> <claude_home> # One entry point, `check_vendored_skills <repo> <claude_home>
# [profile_file]`, sourced and called by doctor.sh. Two things checked # [profile_file]`, sourced and called by doctor.sh. Two things checked
@@ -21,7 +21,9 @@
# is passed — the "could not resolve the active profile" case), # is passed — the "could not resolve the active profile" case),
# the <claude_home>/skills/<name> symlink points at # the <claude_home>/skills/<name> symlink points at
# <repo>/skills-external/<name>. A name absent from the profile is # <repo>/skills-external/<name>. A name absent from the profile is
# reported parked, not failed. # reported parked, not failed — unless its lock entry is
# "always_on": true (the superpowers entry is), in which case the
# symlink is checked regardless of the profile (see _dv_check_link).
# #
# Lock parsing via python3 argv (never string-spliced) — same pattern as # Lock parsing via python3 argv (never string-spliced) — same pattern as
# lib/vendor-skills.sh's _vendor_read_lock. link.sh's EXTERNAL_SKILLS # lib/vendor-skills.sh's _vendor_read_lock. link.sh's EXTERNAL_SKILLS
@@ -61,11 +63,14 @@ fi
# _dv_lock_expectations <lockfile> — prints "<name>\t<file>" for every # _dv_lock_expectations <lockfile> — prints "<name>\t<file>" for every
# skill named under a plugins.lock.json entry whose "managed_by" is # skill named under a plugins.lock.json entry whose "managed_by" is
# "curl": a bare list defaults each name to ["SKILL.md"]; a dict names # "curl", plus a THIRD column "\t1" when that entry is "always_on": true
# its own per-skill file list; an entry with neither (the # (the superpowers entry is) — read by _dv_is_always_on, ignored by the
# emil-design-eng single-file "path" shape) is itself the skill name, # $1==n {print $2} awk in _dv_check_files: a bare list defaults each name
# file "SKILL.md" (the literal "path" value is upstream layout, not the # to ["SKILL.md"]; a dict names its own per-skill file list; an entry
# local dest — never used here). Reads the lockfile via argv only. # with neither (the emil-design-eng single-file "path" shape) is itself
# the skill name, file "SKILL.md" (the literal "path" value is upstream
# layout, not the local dest — never used here). Reads the lockfile via
# argv only.
# Every curl-managed entry's shape is validated ("skills" null, a list # Every curl-managed entry's shape is validated ("skills" null, a list
# of str, or a dict of str -> list of str; "path" a str when present) # of str, or a dict of str -> list of str; "path" a str when present)
# BEFORE it is used, so a malformed entry is the same clean failure as # BEFORE it is used, so a malformed entry is the same clean failure as
@@ -118,12 +123,13 @@ for key, entry in data.items():
sys.exit(1) sys.exit(1)
if not valid_skills(skills): if not valid_skills(skills):
sys.exit(1) sys.exit(1)
suffix = "\t1" if entry.get("always_on") is True else ""
if skills is None: if skills is None:
print(f"{key}\tSKILL.md") print(f"{key}\tSKILL.md{suffix}")
continue continue
for name, files in skill_files(skills).items(): for name, files in skill_files(skills).items():
for file in files: for file in files:
print(f"{name}\t{file}") print(f"{name}\t{file}{suffix}")
PY PY
} }
@@ -196,16 +202,30 @@ allowlist — skipped"
[ "$all_ok" -eq 1 ] [ "$all_ok" -eq 1 ]
} }
# _dv_check_link <claude_home> <repo> <name> <profile_file> — when # _dv_is_always_on <name> <lock_out> — true when <lock_out> (the
# <profile_file> is non-empty and does not list <name>, reports it # "<name>\t<file>[\t1]" lines from _dv_lock_expectations) carries the
# parked (info), not failed. Otherwise (listed, or no <profile_file> was # always_on third column for <name>'s lock entry.
# passed — active profile could not be resolved, every external is then _dv_is_always_on() {
# expected linked) checks the <claude_home>/skills/<name> symlink points local name="$1" lock_out="$2"
# at <repo>/skills-external/<name>. awk -F'\t' -v n="$name" '$1 == n && $3 == 1 { found=1 } \
END { exit !found }' <<< "$lock_out"
}
# _dv_check_link <claude_home> <repo> <name> <profile_file> <always_on> —
# when <always_on> is "1" (the name's lock entry is "always_on": true),
# the symlink is checked whatever <profile_file> says — never parked.
# Otherwise, when <profile_file> is non-empty and does not list <name>,
# reports it parked (info), not failed. Otherwise (listed, always_on, or
# no <profile_file> was passed — active profile could not be resolved,
# every external is then expected linked) checks the
# <claude_home>/skills/<name> symlink points at
# <repo>/skills-external/<name>.
_dv_check_link() { _dv_check_link() {
local claude_home="$1" repo="$2" name="$3" profile_file="$4" local claude_home="$1" repo="$2" name="$3" profile_file="$4" \
always_on="$5"
local link target label local link target label
if [ -n "$profile_file" ] && ! _dv_profile_has "$profile_file" "$name"; then if [ "$always_on" != "1" ] && [ -n "$profile_file" ] \
&& ! _dv_profile_has "$profile_file" "$name"; then
label="$(basename "$profile_file" .profile)" label="$(basename "$profile_file" .profile)"
info "$name: parked by profile $label" info "$name: parked by profile $label"
return return
@@ -220,6 +240,20 @@ lib/profile.sh apply <profile>)"
fi fi
} }
# _dv_check_name <repo> <claude_home> <name> <profile_file> <lock_out> —
# per-name dispatch for check_vendored_skills's loop: files first (the
# link check runs only when every expected file is present, same as
# before), then the symlink, passing _dv_is_always_on's verdict as
# _dv_check_link's 5th param.
_dv_check_name() {
local repo="$1" claude_home="$2" name="$3" profile_file="$4" lock_out="$5"
local always_on=""
_dv_is_always_on "$name" "$lock_out" && always_on=1
_dv_check_files "$repo" "$name" "$lock_out" \
&& _dv_check_link "$claude_home" "$repo" "$name" "$profile_file" \
"$always_on"
}
# check_vendored_skills <repo> <claude_home> [profile_file] — see the # check_vendored_skills <repo> <claude_home> [profile_file] — see the
# file header. Either the lock or link.sh being unreadable (or a # file header. Either the lock or link.sh being unreadable (or a
# malformed lock entry — _dv_lock_expectations rc 1) is a warn, never a # malformed lock entry — _dv_lock_expectations rc 1) is a warn, never a
@@ -251,7 +285,6 @@ check skipped"
item-name allowlist — skipped" item-name allowlist — skipped"
continue continue
fi fi
_dv_check_files "$repo" "$name" "$lock_out" \ _dv_check_name "$repo" "$claude_home" "$name" "$profile_file" "$lock_out"
&& _dv_check_link "$claude_home" "$repo" "$name" "$profile_file"
done <<< "$names" done <<< "$names"
} }
+8 -6
View File
@@ -18,8 +18,10 @@
# and MCPs in the MANAGED_* allowlists are disabled when the profile # and MCPs in the MANAGED_* allowlists are disabled when the profile
# does not list them — nothing outside those lists is ever auto-toggled. # does not list them — nothing outside those lists is ever auto-toggled.
# #
# Always-on plugins (never toggled by `set`): security-guidance, # Always-on plugins (never toggled by `set`): security-guidance + rtk
# superpowers + rtk hook + .claude internal. The script refuses to disable # hook + .claude internal. superpowers is vendored skills now, not a
# plugin (never in PROTECTED_PLUGINS, never in MANAGED_EXTERNALS — same
# always-on class as darwin-skill). The script refuses to disable
# anything in PROTECTED_PLUGINS. # anything in PROTECTED_PLUGINS.
# #
# Usage: # Usage:
@@ -61,9 +63,10 @@ DEFAULT_PROFILE="full" # profile in force when none is selected (cache absent,
source "$(dirname "${BASH_SOURCE[0]}")/gstack-removed.sh" source "$(dirname "${BASH_SOURCE[0]}")/gstack-removed.sh"
# Plugins that are toggle-managed by `set`. Anything NOT in this list is # Plugins that are toggle-managed by `set`. Anything NOT in this list is
# never auto-disabled — protects always-on plugins (security-guidance, # never auto-disabled — protects always-on plugins (security-guidance;
# superpowers) and unrelated user plugins. Add a plugin here only when its # superpowers is vendored skills now, not a plugin) and unrelated user
# enabled state is meaningfully driven by task type. # plugins. Add a plugin here only when its enabled state is meaningfully
# driven by task type.
MANAGED_PLUGINS=( MANAGED_PLUGINS=(
"ui-ux-pro-max@ui-ux-pro-max-skill" "ui-ux-pro-max@ui-ux-pro-max-skill"
"plugin-dev@claude-code-plugins" "plugin-dev@claude-code-plugins"
@@ -106,7 +109,6 @@ MANAGED_MCPS=()
# MANAGED_PLUGINS allowlist.) # MANAGED_PLUGINS allowlist.)
PROTECTED_PLUGINS=( PROTECTED_PLUGINS=(
"security-guidance@claude-code-plugins" "security-guidance@claude-code-plugins"
"superpowers@superpowers-marketplace"
) )
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BLUE='\033[0;34m'; NC='\033[0m' GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BLUE='\033[0;34m'; NC='\033[0m'
+26 -7
View File
@@ -17,9 +17,11 @@
# "skills" is neither null/list/dict degrading the same way with no # "skills" is neither null/list/dict degrading the same way with no
# Python traceback leaking (LOCK_MALFORMED_ENTRY, rc 0), the # Python traceback leaking (LOCK_MALFORMED_ENTRY, rc 0), the
# profile-name allowlist rejecting a path-traversal value # profile-name allowlist rejecting a path-traversal value
# (REJECTS_BAD_PROFILE_NAME), and the item-name allowlist rejecting a # (REJECTS_BAD_PROFILE_NAME), the item-name allowlist rejecting a
# link.sh entry with a ".." segment — warned and skipped, not failed # link.sh entry with a ".." segment — warned and skipped, not failed
# (REJECTS_BAD_NAME). # (REJECTS_BAD_NAME), and an "always_on": true lock entry's name, absent
# from the profile and with no symlink, checked (and failed) instead of
# reported parked (ALWAYS_ON_LINK_CHECKED).
set -u set -u
ROOT="$(cd "$(dirname "$0")/../.." && pwd)" ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
LIB="$ROOT/lib/doctor-vendored.sh" LIB="$ROOT/lib/doctor-vendored.sh"
@@ -57,6 +59,11 @@ cat > "$REPO/plugins.lock.json" <<'JSON'
"dict-entry": { "dict-entry": {
"managed_by": "curl", "managed_by": "curl",
"skills": {"dict-skill": ["SKILL.md", "references/notes.md"]} "skills": {"dict-skill": ["SKILL.md", "references/notes.md"]}
},
"always-on-entry": {
"managed_by": "curl",
"always_on": true,
"skills": ["always-on-skill"]
} }
} }
JSON JSON
@@ -66,25 +73,27 @@ cat > "$REPO/link.sh" <<'SH'
#!/usr/bin/env bash #!/usr/bin/env bash
EXTERNAL_SKILLS=(ok-skill missing-skill dict-skill EXTERNAL_SKILLS=(ok-skill missing-skill dict-skill
active-nolink-skill active-wronglink-skill active-nolink-skill active-wronglink-skill
parked-skill noprofile-skill) parked-skill noprofile-skill always-on-skill)
SH SH
# ── skills-external/ tree: every name's SKILL.md present, except # ── skills-external/ tree: every name's SKILL.md present, except
# missing-skill (nothing at all) and dict-skill's references/notes.md. # missing-skill (nothing at all) and dict-skill's references/notes.md.
# always-on-skill has its SKILL.md too — only its symlink is missing.
for n in ok-skill dict-skill active-nolink-skill active-wronglink-skill \ for n in ok-skill dict-skill active-nolink-skill active-wronglink-skill \
parked-skill noprofile-skill; do parked-skill noprofile-skill always-on-skill; do
mkdir -p "$REPO/skills-external/$n" mkdir -p "$REPO/skills-external/$n"
echo "v1" > "$REPO/skills-external/$n/SKILL.md" echo "v1" > "$REPO/skills-external/$n/SKILL.md"
done done
# ── claude_home symlinks: ok-skill correct, active-wronglink-skill # ── claude_home symlinks: ok-skill correct, active-wronglink-skill
# points elsewhere, active-nolink-skill and noprofile-skill have none. # points elsewhere, active-nolink-skill, noprofile-skill and
# always-on-skill have none.
ln -sf "$REPO/skills-external/ok-skill" "$CLAUDE_HOME/skills/ok-skill" ln -sf "$REPO/skills-external/ok-skill" "$CLAUDE_HOME/skills/ok-skill"
mkdir -p "$WORK/elsewhere" mkdir -p "$WORK/elsewhere"
ln -sf "$WORK/elsewhere" "$CLAUDE_HOME/skills/active-wronglink-skill" ln -sf "$WORK/elsewhere" "$CLAUDE_HOME/skills/active-wronglink-skill"
# ── active.profile: lists everything EXCEPT parked-skill and # ── active.profile: lists everything EXCEPT parked-skill,
# noprofile-skill (both proven absent from it). # noprofile-skill and always-on-skill (all three proven absent from it).
cat > "$REPO/active.profile" <<'PROF' cat > "$REPO/active.profile" <<'PROF'
# DESC: fixture profile # DESC: fixture profile
ok-skill external ok-skill external
@@ -132,6 +141,16 @@ check_bool SYMLINK_PARKED \
grep -qF 'parked-skill: symlink missing/wrong' \ grep -qF 'parked-skill: symlink missing/wrong' \
&& echo 1 || echo 0)" && echo 1 || echo 0)"
# ── always-on-skill: absent from active.profile (same as parked-skill)
# but its lock entry is "always_on": true — checked (and failed, no
# symlink) instead of reported parked.
check_bool ALWAYS_ON_LINK_CHECKED \
"$(printf '%s' "$out1" | \
grep -qF 'always-on-skill: symlink missing/wrong' \
&& ! printf '%s' "$out1" | \
grep -qF 'always-on-skill: parked by profile' \
&& echo 1 || echo 0)"
# ── No profile file passed at all: noprofile-skill (absent from # ── No profile file passed at all: noprofile-skill (absent from
# active.profile, parked above) must now be treated as expected-linked. # active.profile, parked above) must now be treated as expected-linked.
out2="$(check_vendored_skills "$REPO" "$CLAUDE_HOME" 2>&1)" out2="$(check_vendored_skills "$REPO" "$CLAUDE_HOME" 2>&1)"
+3
View File
@@ -18,6 +18,9 @@
# `skills` as a bare list defaults every named skill to `["SKILL.md"]` and # `skills` as a bare list defaults every named skill to `["SKILL.md"]` and
# `path` to "skills" (the agent-skills shape); `skills` as a dict carries an # `path` to "skills" (the agent-skills shape); `skills` as a dict carries an
# explicit per-skill file list (references/*, etc.) and `path` is required. # explicit per-skill file list (references/*, etc.) and `path` is required.
# `"always_on": true` (optional) is ignored by this helper (fetch is the
# same either way) — lib/doctor-vendored.sh reads it to expect the
# entry's skills linked regardless of the active profile.
# #
# Raw URL: https://raw.githubusercontent.com/<owner>/<repo>/<sha>/<path>/ # Raw URL: https://raw.githubusercontent.com/<owner>/<repo>/<sha>/<path>/
# <skill>/<file>. VENDOR_BASE_URL overrides the "https://…/<repo>" prefix # <skill>/<file>. VENDOR_BASE_URL overrides the "https://…/<repo>" prefix
+3 -1
View File
@@ -79,7 +79,9 @@ EXTERNAL_SKILLS=(emil-design-eng frontend-design design-motion-principles
observability-and-instrumentation deprecation-and-migration ci-cd-and-automation observability-and-instrumentation deprecation-and-migration ci-cd-and-automation
scroll-world-storytelling build-threejs-scroll-worlds scroll-world-storytelling build-threejs-scroll-worlds
scroll-scrubbed-visual-sequence scroll-scrubbed-word-reveal scroll-scrubbed-visual-sequence scroll-scrubbed-word-reveal
scroll-progress-timeline) scroll-progress-timeline brainstorming writing-plans
subagent-driven-development test-driven-development
requesting-code-review using-git-worktrees writing-skills)
for _ext_skill in "${EXTERNAL_SKILLS[@]}"; do for _ext_skill in "${EXTERNAL_SKILLS[@]}"; do
if [ -d "$REPO/skills-external/$_ext_skill" ]; then if [ -d "$REPO/skills-external/$_ext_skill" ]; then
if [ -L "$CLAUDE/skills/$_ext_skill" ] && [ "$(readlink "$CLAUDE/skills/$_ext_skill")" = "$REPO/skills-external/$_ext_skill" ]; then if [ -L "$CLAUDE/skills/$_ext_skill" ] && [ "$(readlink "$CLAUDE/skills/$_ext_skill")" = "$REPO/skills-external/$_ext_skill" ]; then
+17
View File
@@ -64,6 +64,23 @@
"managed_by": "curl", "managed_by": "curl",
"note": "Five scroll-choreography skills from MengTo/Skills (agent-skills/web-design), vendored the agent-skills way but with an explicit per-skill file list (SKILL.md + REFERENCES.md, or references/*.md + references/scroll-conductor.js for build-threejs-scroll-worlds) instead of the SKILL.md-only default. Never vendored: demo/, agents/, or any binary asset upstream ships alongside each skill. Text-only, byte-for-byte copies (Codex-isms in the source text stay). Bump the commit deliberately to pick up an upstream edit; install-plugins.sh Step 8e and update-all.sh 7.3 both read it from here via lib/vendor-skills.sh's vendor_pinned_skills(), never hardcoded." "note": "Five scroll-choreography skills from MengTo/Skills (agent-skills/web-design), vendored the agent-skills way but with an explicit per-skill file list (SKILL.md + REFERENCES.md, or references/*.md + references/scroll-conductor.js for build-threejs-scroll-worlds) instead of the SKILL.md-only default. Never vendored: demo/, agents/, or any binary asset upstream ships alongside each skill. Text-only, byte-for-byte copies (Codex-isms in the source text stay). Bump the commit deliberately to pick up an upstream edit; install-plugins.sh Step 8e and update-all.sh 7.3 both read it from here via lib/vendor-skills.sh's vendor_pinned_skills(), never hardcoded."
}, },
"superpowers": {
"source": "https://github.com/obra/superpowers",
"commit": "5bf4e78011075bcfc0dc295f0724994cd123ee71",
"path": "skills",
"skills": {
"brainstorming": ["SKILL.md", "spec-document-reviewer-prompt.md", "visual-companion.md", "scripts/frame-template.html", "scripts/helper.js", "scripts/server.cjs", "scripts/start-server.sh", "scripts/stop-server.sh"],
"writing-plans": ["SKILL.md", "plan-document-reviewer-prompt.md"],
"subagent-driven-development": ["SKILL.md", "implementer-prompt.md", "re-review-prompt.md", "task-reviewer-prompt.md", "scripts/review-package", "scripts/sdd-workspace", "scripts/task-brief"],
"test-driven-development": ["SKILL.md", "writing-good-tests.md"],
"requesting-code-review": ["SKILL.md", "code-reviewer.md"],
"using-git-worktrees": ["SKILL.md"],
"writing-skills": ["SKILL.md", "anthropic-best-practices.md", "examples/CLAUDE_MD_TESTING.md", "graphviz-conventions.dot", "persuasion-principles.md", "render-graphs.js", "testing-skills-with-subagents.md"]
},
"managed_by": "curl",
"always_on": true,
"note": "Seven superpowers skills vendored byte-for-byte at the v6.4.1 tag commit (obra/superpowers), always on (no profile lists them). Bump the commit deliberately. Scripts inside run as `bash scripts/<x>`, no exec bit needed. Upstream cross-references to the plugin prefix and to the 8 non-vendored skills stay in the text; CLAUDE.global.md Skill routing maps them."
},
"impeccable": { "impeccable": {
"source": "npm:impeccable", "source": "npm:impeccable",
"version": "4.1.0", "version": "4.1.0",
-7
View File
@@ -420,7 +420,6 @@
"example-skills@anthropic-agent-skills": false, "example-skills@anthropic-agent-skills": false,
"ui-ux-pro-max@ui-ux-pro-max-skill": true, "ui-ux-pro-max@ui-ux-pro-max-skill": true,
"security-guidance@claude-code-plugins": true, "security-guidance@claude-code-plugins": true,
"superpowers@superpowers-marketplace": true,
"pr-review-toolkit@claude-code-plugins": false, "pr-review-toolkit@claude-code-plugins": false,
"brightdata-plugin@synced": false "brightdata-plugin@synced": false
}, },
@@ -431,12 +430,6 @@
"repo": "anthropics/claude-code" "repo": "anthropics/claude-code"
} }
}, },
"superpowers-marketplace": {
"source": {
"source": "github",
"repo": "obra/superpowers-marketplace"
}
},
"ui-ux-pro-max-skill": { "ui-ux-pro-max-skill": {
"source": { "source": {
"source": "github", "source": "github",
+2 -1
View File
@@ -318,7 +318,8 @@ Then offer to capitalize (per CLAUDE.md): recurring finding patterns →
## TDD note (skill itself) ## TDD note (skill itself)
Baseline-tested per superpowers:writing-skills (2026-06-11, isolated Baseline-tested per writing-skills (vendored superpowers skill;
2026-06-11, isolated
worktree, no skill): the agent (1) guessed the boundary from the most worktree, no skill): the agent (1) guessed the boundary from the most
recent file date in `.claude/audits/` — wrong file, date-based; (2) wrote recent file date in `.claude/audits/` — wrong file, date-based; (2) wrote
its checkpoint as prose in a dated report — unparseable next run; (3) kept its checkpoint as prose in a dated report — unparseable next run; (3) kept
+1 -1
View File
@@ -512,7 +512,7 @@ The deploy succeeded. Lay the oracle and close out.
## Note on this skill (authoring) ## Note on this skill (authoring)
Shaped via `superpowers:writing-skills`. The **cold cross-session resume** is the Shaped via `writing-skills` (vendored superpowers skill). The **cold cross-session resume** is the
novel form (design §10): the disk alone must carry the deploy across the novel form (design §10): the disk alone must carry the deploy across the
out-of-band gap, so `PENDING.json`'s presence marks the wait and STEP 0 resumes out-of-band gap, so `PENDING.json`'s presence marks the wait and STEP 0 resumes
from it without conversation memory — the `audit-delta` "state file is the only from it without conversation memory — the `audit-delta` "state file is the only
+5 -3
View File
@@ -13,8 +13,10 @@ fan-out, init, `.gitignore` reconcile, the protected-base predicate — are in
and bulletproofs the single judgment call: **`finish` merges only on an explicit and bulletproofs the single judgment call: **`finish` merges only on an explicit
human signal.** human signal.**
Replaces `finishing-a-development-branch` for gitflow flows — that skill is Replaces `finishing-a-development-branch` (upstream superpowers skill, not
single-target and cannot do the directed / fan-out merges below. vendored here; `gitflow finish` is the only integration path) for gitflow
flows — that skill is single-target and cannot do the directed / fan-out
merges below.
## When to Use ## When to Use
@@ -107,7 +109,7 @@ stays human-gated.
## Common Mistakes ## Common Mistakes
- Using `finishing-a-development-branch` for a gitflow merge → it can't do directed/fan-out merges. Use `gitflow finish`. - Using `finishing-a-development-branch` (upstream superpowers skill, not vendored here) for a gitflow merge → it can't do directed/fan-out merges anyway. Use `gitflow finish`, the only integration path.
- Hand-writing `git merge` instead of `gitflow finish` → loses fan-out, branch delete, base sync. - Hand-writing `git merge` instead of `gitflow finish` → loses fan-out, branch delete, base sync.
- Calling `finish` because the work *looks* done → see the gate. - Calling `finish` because the work *looks* done → see the gate.
- `git branch -d`/`-D` by hand → denied; a branch the lib refuses to delete still holds work. Keep it, say so. - `git branch -d`/`-D` by hand → denied; a branch the lib refuses to delete still holds work. Keep it, say so.
+4 -4
View File
@@ -68,7 +68,7 @@ contract.
Load `$HOME/.claude/agents/analyzer.md`. Analyze BRIEF: existing code, stack constraints, infra risks, open decisions. Produce ANALYSIS REPORT. Load `$HOME/.claude/agents/analyzer.md`. Analyze BRIEF: existing code, stack constraints, infra risks, open decisions. Produce ANALYSIS REPORT.
## STEP 3 — DESIGN ## STEP 3 — DESIGN
Invoke `superpowers:brainstorming` with BRIEF + ANALYSIS REPORT. Invoke `brainstorming` (vendored superpowers skill) with BRIEF + ANALYSIS REPORT.
Produce DESIGN: stack+versions, full folder tree, module responsibilities, data flow, interfaces (signatures only), config+tooling, test strategy, resolved decisions, prereqs list. Produce DESIGN: stack+versions, full folder tree, module responsibilities, data flow, interfaces (signatures only), config+tooling, test strategy, resolved decisions, prereqs list.
Then run pass B of `$HOME/.claude/lib/contract-interview.md` against the DESIGN Then run pass B of `$HOME/.claude/lib/contract-interview.md` against the DESIGN
(minus what the BRIEF and the brainstorm settled): one batch before STEP 4; (minus what the BRIEF and the brainstorm settled): one batch before STEP 4;
@@ -179,7 +179,7 @@ This is the deterministic scaffold commit owner (closes BLK-010). The MVP is
implemented on a `feature/*` branch off `develop` (STEP 8). implemented on a `feature/*` branch off `develop` (STEP 8).
## STEP 6 — PLAN ## STEP 6 — PLAN
Invoke `superpowers:writing-plans` with BRIEF + skeleton. Invoke `writing-plans` (vendored superpowers skill) with BRIEF + skeleton.
Granular tasks (2-5 min each), exact file paths, TDD: tests before code. Granular tasks (2-5 min each), exact file paths, TDD: tests before code.
## STEP 6b — CHALLENGE THE PLAN (before the gate) ## STEP 6b — CHALLENGE THE PLAN (before the gate)
@@ -212,7 +212,7 @@ Start the MVP feature branch off develop, then implement on it:
```bash ```bash
bash "$HOME/.claude/lib/gitflow.sh" start feature mvp bash "$HOME/.claude/lib/gitflow.sh" start feature mvp
``` ```
Invoke `superpowers:subagent-driven-development` for the per-task implement loop Invoke `subagent-driven-development` (vendored superpowers skill) for the per-task implement loop
**and** the final whole-branch review **only**. Do NOT run its terminal **and** the final whole-branch review **only**. Do NOT run its terminal
`finishing-a-development-branch` step — this orchestrator owns integration via `finishing-a-development-branch` step — this orchestrator owns integration via
`gitflow finish` (STEP 11). When SDD's flow reaches "Use `gitflow finish` (STEP 11). When SDD's flow reaches "Use
@@ -256,7 +256,7 @@ against the founding contract. Distinct axis from STEP 10 code review
([[LRN-095]]) — both run. ([[LRN-095]]) — both run.
## STEP 10 — CODE REVIEW ## STEP 10 — CODE REVIEW
Invoke `superpowers:requesting-code-review`. **Model routing (BDR-077):** the Invoke `requesting-code-review` (vendored superpowers skill). **Model routing (BDR-077):** the
review subagent it dispatches MUST carry `model: "opus"` in the Agent call — review subagent it dispatches MUST carry `model: "opus"` in the Agent call —
craft review is dispatched judgment, never inherited from the session. Fix craft review is dispatched judgment, never inherited from the session. Fix
all CRITICAL before proceeding. all CRITICAL before proceeding.
+4 -2
View File
@@ -56,8 +56,10 @@ lists items + types:
| `mcp` | advisory — prints manual `claude mcp add …` command (no server is managed today: `MANAGED_MCPS` is empty since 21st.dev moved to a CLI) | | `mcp` | advisory — prints manual `claude mcp add …` command (no server is managed today: `MANAGED_MCPS` is empty since 21st.dev moved to a CLI) |
| `cli` | advisory only — reports installed/not-installed | | `cli` | advisory only — reports installed/not-installed |
**Always-on plugins** (`security-guidance`, `superpowers`) are **Always-on plugins** (`security-guidance`) and the vendored superpowers
protected — `set` will refuse to disable them even if the profile omits them. skills are never toggled by a profile — `set` will refuse to disable the
plugin even if the profile omits it, and the 7 superpowers skills are
linked outside any profile.
**Managed plugins** that `set` may disable when not in profile: **Managed plugins** that `set` may disable when not in profile:
`ui-ux-pro-max@ui-ux-pro-max-skill`, `plugin-dev@claude-code-plugins`, `ui-ux-pro-max@ui-ux-pro-max-skill`, `plugin-dev@claude-code-plugins`,
`pr-review-toolkit@claude-code-plugins`. Other plugins are never auto-toggled. `pr-review-toolkit@claude-code-plugins`. Other plugins are never auto-toggled.
+4 -4
View File
@@ -100,7 +100,7 @@ approved at STEP 3 ENRICHES it, and STEP 5's verifier judges the diff against
the ENRICHED contract. This is the only flow where the contract grows mid-run. the ENRICHED contract. This is the only flow where the contract grows mid-run.
## STEP 1 — BRAINSTORM ## STEP 1 — BRAINSTORM
Invoke `superpowers:brainstorming` — but FEED it the STEP 0d digest as binding context, Invoke `brainstorming` (vendored superpowers skill) — but FEED it the STEP 0d digest as binding context,
not the raw request alone: not the raw request alone:
"Feature request: <$ARGUMENTS>. "Feature request: <$ARGUMENTS>.
In-force constraints (must hold): <only the IN-FORCE + ALREADY-SEEN items from 0d's In-force constraints (must hold): <only the IN-FORCE + ALREADY-SEEN items from 0d's
@@ -114,7 +114,7 @@ Consumption = INPUT INJECTION (we can't modify the external skill; we control it
Refine request into validated design via Socratic questioning. Don't proceed until design approved. Refine request into validated design via Socratic questioning. Don't proceed until design approved.
## STEP 2 — PLAN ## STEP 2 — PLAN
Invoke `superpowers:writing-plans` with the validated design AND the 0d digest: every task Invoke `writing-plans` (vendored superpowers skill) with the validated design AND the 0d digest: every task
must be consistent with the in-force constraints; where a task implements or affects one, must be consistent with the in-force constraints; where a task implements or affects one,
note the ID inline. Break design into tasks (2-5 min each). Each task: exact file paths, full code, verification steps. note the ID inline. Break design into tasks (2-5 min each). Each task: exact file paths, full code, verification steps.
Then run pass B of `$HOME/.claude/lib/contract-interview.md` against the plan: Then run pass B of `$HOME/.claude/lib/contract-interview.md` against the plan:
@@ -173,7 +173,7 @@ Start the feature branch off develop, then implement on it:
```bash ```bash
bash "$HOME/.claude/lib/gitflow.sh" start feature <name> bash "$HOME/.claude/lib/gitflow.sh" start feature <name>
``` ```
Invoke `superpowers:subagent-driven-development` for the per-task implement loop Invoke `subagent-driven-development` (vendored superpowers skill) for the per-task implement loop
**and** the final whole-branch review **only**. Do NOT run its terminal **and** the final whole-branch review **only**. Do NOT run its terminal
`finishing-a-development-branch` step — this orchestrator owns integration via `finishing-a-development-branch` step — this orchestrator owns integration via
`gitflow finish` (STEP 9). When SDD's flow reaches "Use `gitflow finish` (STEP 9). When SDD's flow reaches "Use
@@ -234,7 +234,7 @@ conformity + security vs. craft/design) — both run, neither subsumes the
other ([[LRN-095]]). other ([[LRN-095]]).
## STEP 6 — CODE REVIEW ## STEP 6 — CODE REVIEW
Invoke `superpowers:requesting-code-review`. **Model routing (BDR-077):** the Invoke `requesting-code-review` (vendored superpowers skill). **Model routing (BDR-077):** the
review subagent it dispatches MUST carry `model: "opus"` in the Agent call — review subagent it dispatches MUST carry `model: "opus"` in the Agent call —
craft review is dispatched judgment, never inherited from the session. Fix craft review is dispatched judgment, never inherited from the session. Fix
all CRITICAL before proceeding. all CRITICAL before proceeding.
+4 -3
View File
@@ -315,9 +315,10 @@ without that approval — neither this repo's nor any target project's.
## TDD note (skill itself) ## TDD note (skill itself)
Baseline-tested per superpowers:writing-skills (2026-07-04, seeded Baseline-tested per writing-skills (vendored superpowers skill;
fixture, no skill): the agent branched correctly via gitflow and did not 2026-07-04, seeded fixture, no skill): the agent branched correctly via
merge, BUT (1) silently rewrote the target TODO (checked boxes, gitflow and did not merge, BUT (1) silently rewrote the target TODO (checked
boxes,
restructured) during "reconcile"; (2) authored BDR/journal registry restructured) during "reconcile"; (2) authored BDR/journal registry
entries autonomously; (3) ran security as ad-hoc grep + ruff — no entries autonomously; (3) ran security as ad-hoc grep + ruff — no
semgrep, no pinned rulesets; (4) left findings only in its final chat semgrep, no pinned rulesets; (4) left findings only in its final chat
+7 -3
View File
@@ -377,9 +377,10 @@ else
info "design-motion-principles not installed — skipping" info "design-motion-principles not installed — skipping"
fi fi
# ── 7.3. Update Agent Skills + Mengto scroll skills (pinned commit) ── # ── 7.3. Update Agent Skills + Mengto scroll skills + superpowers
# Both re-fetched at the SAME pinned commit (never advances the pin) via # (pinned commit) — all three re-fetched at the SAME pinned commit
# the shared lib/vendor-skills.sh helper — see install-plugins.sh Step 8e. # (never advances the pin) via the shared lib/vendor-skills.sh helper —
# see install-plugins.sh Step 8e.
echo "" echo ""
echo "── Updating Agent Skills (addyosmani/agent-skills)..." echo "── Updating Agent Skills (addyosmani/agent-skills)..."
# shellcheck source=lib/vendor-skills.sh disable=SC1091 # shellcheck source=lib/vendor-skills.sh disable=SC1091
@@ -388,6 +389,9 @@ vendor_pinned_skills agent-skills refresh
echo "" echo ""
echo "── Updating Mengto scroll skills (MengTo/Skills)..." echo "── Updating Mengto scroll skills (MengTo/Skills)..."
vendor_pinned_skills mengto-skills refresh vendor_pinned_skills mengto-skills refresh
echo ""
echo "── Updating superpowers skills (obra/superpowers)..."
vendor_pinned_skills superpowers refresh
# ── Impeccable (design detector + skill + subagents) ── # ── Impeccable (design detector + skill + subagents) ──
# Global scope: the installer writes through the ~/.claude/{skills,agents} # Global scope: the installer writes through the ~/.claude/{skills,agents}