Problem
The naming doctrine reasons about invocation namespacing and model-side auto-invocation ambiguity, but never about display — what a human reads in the / slash-command picker.
docs/PLUGIN-PHILOSOPHY.md:69-72 states plugin skills "are namespaced and cannot collide with other levels." That claim is correct for resolution, and Claude Code implements exactly it. It is easy to carry over to presentation, where it does not hold.
Empirical finding (Claude Code 2.1.215)
Read from the shipping bundle. The picker's name column is pp(t) — the short name. When the internal name differs and contains :, the namespaced form is registered as a hidden alias:
function W6e(e){ return e.filter(kur).map((t)=>{
let r=pp(t),
n=t.name!==r&&t.name.includes(":")?t.name:void 0,
o=n&&!t.aliases?.includes(n)?[...t.aliases??[],n]:t.aliases;
return {name:r, description:j6e(t), argumentHint:t.argumentHint||"", aliases:o?.length?o:void 0}
})}
Origin is carried in the description column instead:
if(e.source==="plugin"){
let t=e.pluginInfo?.pluginManifest;
if(t) return `(${wE(t)}) ${e.description}`;
return `${e.description} (plugin)`
}
if(e.source==="builtin"||e.source==="mcp"||e.source==="bundled") return e.description;
return `${e.description} (${d5(e.source)})`
Confirmed visually: two /clean rows render with (repo-hygiene) / (disk-hygiene) in parens ahead of the description.
Consequence
- Every locked decision stands. D19's "all shadow-dodge names kept on merit" survives intact — the names are unambiguously invocable; the built-in keeps the bare token; the plugin skill is reachable at its namespaced alias, exactly as
PLUGIN-PHILOSOPHY.md:71-72 says.
- 143 skills across 51 plugins share 8 short names (
setup x33, audit x6, check/clean/diagnose/plan/workflow/write x2). All collapse in the name column and are disambiguated only by the description prefix.
- The Deferred questions entry in
docs/topics/plugin-organization/PLAN.md — "Empirical check: typeahead prefix filtering on plugin-skill leaf names" — is now answerable and should be resolved in-place.
Scope
Documentation only. No renames.
docs/PLUGIN-PHILOSOPHY.md — separate the invocation guarantee from the display behavior.
docs/MIGRATION-PLAYBOOK.md — same distinction where built-in collisions are discussed.
docs/topics/plugin-organization/PLAN.md — resolve the deferred typeahead question; add an upstream trigger row.
Upstream
Problem
The naming doctrine reasons about invocation namespacing and model-side auto-invocation ambiguity, but never about display — what a human reads in the
/slash-command picker.docs/PLUGIN-PHILOSOPHY.md:69-72states plugin skills "are namespaced and cannot collide with other levels." That claim is correct for resolution, and Claude Code implements exactly it. It is easy to carry over to presentation, where it does not hold.Empirical finding (Claude Code 2.1.215)
Read from the shipping bundle. The picker's name column is
pp(t)— the short name. When the internal name differs and contains:, the namespaced form is registered as a hidden alias:Origin is carried in the description column instead:
Confirmed visually: two
/cleanrows render with(repo-hygiene)/(disk-hygiene)in parens ahead of the description.Consequence
PLUGIN-PHILOSOPHY.md:71-72says.setupx33,auditx6,check/clean/diagnose/plan/workflow/writex2). All collapse in the name column and are disambiguated only by the description prefix.docs/topics/plugin-organization/PLAN.md— "Empirical check: typeahead prefix filtering on plugin-skill leaf names" — is now answerable and should be resolved in-place.Scope
Documentation only. No renames.
docs/PLUGIN-PHILOSOPHY.md— separate the invocation guarantee from the display behavior.docs/MIGRATION-PLAYBOOK.md— same distinction where built-in collisions are discussed.docs/topics/plugin-organization/PLAN.md— resolve the deferred typeahead question; add an upstream trigger row.Upstream