chore(memory): BDR-106 superpowers vendored — contract, plan r3, oracles, TODO, journal

This commit is contained in:
bastien
2026-09-28 14:54:53 +02:00
parent ddea411491
commit 7177258f3d
7 changed files with 404 additions and 0 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.