-
Notifications
You must be signed in to change notification settings - Fork 2
feat(naming): add name-it-better plugin #250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
ea5d007
feat(naming): add name-it-better plugin
kyle-sexton 5790430
build(naming): exclude bot-blocked method-source URLs from lychee
kyle-sexton 9c4eb2b
fix(naming): restore model invocation, disqualify rejected incumbent
kyle-sexton b2bd63c
fix(naming): preserve reject and collision filters in tournament mode
kyle-sexton 6c6f2bb
fix(naming): route already-decided renames away from name generation
kyle-sexton 1162aac
build(naming): cite bot-blocked sources as code spans, not lychee exc…
kyle-sexton File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", | ||
| "name": "naming", | ||
| "version": "0.1.0", | ||
| "description": "Generates and evaluates fresh name candidates for anything — an identifier, file, module, skill, repo, or domain term — by fanning out blind, fresh-context generators from distinct lenses (responsibility-literal, moment-of-use, domain-lore), then scoring a shortlist against the consuming org's naming criteria. The human always picks; it never auto-locks a name. An optional tournament mode adds elimination rounds with independent judges for high-stakes, hard-to-refactor names.", | ||
| "author": { | ||
| "name": "Melodic Software", | ||
| "email": "info@melodicsoftware.com" | ||
| }, | ||
| "license": "MIT", | ||
| "keywords": ["naming", "name", "rename", "identifier", "candidates", "anti-anchoring", "skill"] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # Changelog | ||
|
|
||
| All notable changes to the `naming` plugin are documented here. Format follows | ||
| [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. | ||
|
|
||
| ## [0.1.0] | ||
|
|
||
| ### Added | ||
|
|
||
| - **Initial release.** `/naming:name-it-better` — generate fresh name | ||
| candidates by fanning out blind, fresh-context generators from distinct lenses | ||
| (responsibility-literal, moment-of-use, domain-lore), score a shortlist against | ||
| the consuming org's naming criteria, and recommend — the human always picks, | ||
| never an auto-locked name. Optional `tournament` action adds elimination rounds | ||
| with independent judges for high-stakes, hard-to-refactor names. | ||
| - Repo-agnostic: scores against the consuming project's declared naming | ||
| conventions when present, degrading to the general criteria grounded in the | ||
| skill's `context/sources.md` when none is declared. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # naming | ||
|
|
||
| A Claude Code plugin for generating and evaluating name candidates. One | ||
| skill, one job: when a name was just rejected — or none exists yet — break | ||
| the anchor by fanning out blind, fresh-context generators from distinct | ||
| lenses, then hand the human a scored shortlist to choose from. | ||
|
|
||
| | Skill | What it does | | ||
| |---|---| | ||
| | `/naming:name-it-better` | Generate fresh name candidates from blind lenses, score them, recommend a shortlist — the human picks | | ||
|
|
||
| ## Why blind generators | ||
|
|
||
| The dominant trigger is a reactive retry: a name was suggested and | ||
| rejected, and the same context that produced it will only produce more of | ||
| the same. So the generators run BLIND to the conversation, seeded only with | ||
| a distilled context brief, each working a distinct lens | ||
| (responsibility-literal, moment-of-use, domain-lore). Diverge widely from | ||
| independent perspectives, then converge once — and keep the first-seen | ||
| suggestion from anchoring the choice. The method grounding is in the | ||
| skill's `context/sources.md`. | ||
|
|
||
| **The human always picks.** The skill narrows and recommends; it never | ||
| auto-locks a name. | ||
|
|
||
| ```shell | ||
| /naming:name-it-better # blind lenses → scored shortlist → human picks | ||
| /naming:name-it-better tournament # ~5 generators + elimination rounds for high-stakes names | ||
| ``` | ||
|
|
||
| `tournament` is an honest adaptation of elimination brackets plus pairwise | ||
| social-choice scoring — not a documented naming technique; the skill | ||
| presents it as such. | ||
|
|
||
| ## Consumer conventions | ||
|
|
||
| - **Criteria source of truth.** The skill scores against the consuming | ||
| organization's naming and domain-language conventions when the project | ||
| declares them (its `CLAUDE.md` / `.claude/rules/` or a standards source | ||
| it points to). When none is declared, it falls back to the general | ||
| naming criteria grounded in the skill's `context/sources.md`. A criterion | ||
| the user wants that is missing from their conventions flows UP into those | ||
| conventions, not into the skill. | ||
| - **Adjacent capabilities.** Resolving what a domain concept IS routes to a | ||
| domain-modelling capability; propagating a chosen name across call sites | ||
| routes to a rename-references capability — each invoked through its slash | ||
| command when present, degrading to prose guidance when absent. | ||
|
|
||
| ## Install | ||
|
|
||
| ```shell | ||
| /plugin marketplace add melodic-software/claude-code-plugins | ||
| /plugin install naming@melodic-software | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| No `userConfig`. No persistent state. Network: the generators are | ||
| subagents; `context/sources.md` carries external reference links for the | ||
| method, not fetched at runtime. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| --- | ||
| name: name-it-better | ||
| description: "Generate and evaluate fresh name candidates for anything — a variable, function, file, module, skill, repo, or domain term — then let the human pick. Use when the target name is still UNDECIDED: 'name it better', 'better name', 'that name is wrong', 'suggest names', 'what should I call this', 'need a name for', 'come up with a name', 'help me rename this to something better'. Not for an already-decided rename ('rename X to Y', 'I renamed X') — that routes to the rename-references sweep. Spawns blind fresh-context generators from distinct lenses; never auto-locks a name. Optional 'tournament' arg for high-stakes, hard-to-refactor names." | ||
| argument-hint: "[tournament]" | ||
| user-invocable: true | ||
| --- | ||
|
|
||
| # Name it better | ||
|
|
||
| ## Purpose | ||
|
|
||
| Produce better name candidates for anything that needs one — an | ||
| identifier, file, module, skill, repo, or domain term — and hand the | ||
| human a scored shortlist to choose from. The dominant trigger is a | ||
| reactive retry: a name was just suggested and rejected, and the same | ||
| context that produced it will only produce more of the same. So the | ||
| generators run BLIND to the conversation, from distinct lenses, to break | ||
| the anchor. A blank-slate naming request is the same machinery without a | ||
| rejected incumbent. | ||
|
|
||
| **The human always picks.** This skill narrows and recommends; it never | ||
| auto-locks a name. | ||
|
|
||
| ## Criteria — cite the source of truth, do not copy it | ||
|
|
||
| Score against the consuming organization's naming criteria, resolved from | ||
| its own context, never from a baked-in path: | ||
|
|
||
| 1. **Declared conventions win.** When the consuming project names where its | ||
| naming and domain-language conventions live — its `CLAUDE.md`, | ||
| `.claude/rules/`, a shared standards source it points to — score against | ||
| THAT. Read the criteria there; do not restate them here. A criterion the | ||
| user wants that is missing from those conventions flows UP into them | ||
| (their standards change), not hardcoded into this skill. | ||
| 2. **None declared → the general criteria** grounded in | ||
| [`context/sources.md`](context/sources.md): intention-revealing and | ||
| semantically accurate to the responsibility, evolution-safe (the name | ||
| sets scope and bounds), context-sensitive, free of overloaded or | ||
| disinformative terms, and drawn from the domain's ubiquitous language. | ||
|
|
||
| ## Default pass | ||
|
|
||
| 1. **Distill a context brief.** Capture, in a few lines: the | ||
| responsibility of the thing, its scope and lifetime, hard constraints | ||
| (language casing rules, length, collisions to avoid), the existing | ||
| surrounding vocabulary, and a blocklist of overloaded terms to avoid. | ||
| This brief — NOT the conversation — is all the generators receive. | ||
| 2. **Fan out blind generators.** Spawn ~3 fresh-context subagents, each | ||
| seeded ONLY with the brief (blind to this conversation and to each | ||
| other), each working a distinct lens: | ||
| - **responsibility-literal** — name exactly what it does; | ||
| - **moment-of-use** — name for how it reads at the call site; | ||
| - **domain-lore** — name from the domain's ubiquitous language. | ||
|
|
||
| Running them blind and independent is deliberate anti-anchoring; the | ||
| method grounding is in [`context/sources.md`](context/sources.md). | ||
| 3. **Merge and score.** Pool the candidates, dedupe, and disqualify any | ||
| candidate that matches the rejected incumbent (if any) — carried by the | ||
| main thread as an explicit reject list, never shared with the | ||
| generators — or that collides with the existing vocabulary. Score every | ||
| surviving candidate against the criteria resolved above. | ||
| 4. **Shortlist + recommend.** Present a short ranked list with a | ||
| one-line rationale per candidate and a single RECOMMENDED pick, marked | ||
| and listed first. | ||
| 5. **Human picks.** Stop and let the user choose. Do not apply the name. | ||
|
|
||
| ## `tournament` action | ||
|
|
||
| When `$ARGUMENTS` contains `tournament`, run this in place of the default | ||
| pass. | ||
|
|
||
| `/naming:name-it-better tournament` — for a high-stakes name that will be | ||
| hard to refactor later. Widen to ~5 generators (optionally different | ||
| models), then run elimination rounds with independent scoring judges until | ||
| one candidate remains, and present it plus the runners-up for the human | ||
| choice. | ||
|
|
||
| The reject-list and collision disqualification from the default pass's | ||
| merge step still apply: pool the widened candidates and disqualify any that | ||
| match the rejected incumbent or collide with the existing vocabulary BEFORE | ||
| the elimination rounds begin — a rejected or colliding name must never enter | ||
| the bracket, let alone reach the finalist. | ||
|
|
||
| HONEST FRAMING: a "naming tournament / bracket" is NOT a documented | ||
| software-naming technique. This mode ADAPTS elimination brackets plus | ||
| pairwise social-choice scoring as a convergence mechanism — see | ||
| [`context/sources.md`](context/sources.md). Present it as such, not as an | ||
| established standard. | ||
|
|
||
| ## Adjacent skills — hand off, do not overlap | ||
|
|
||
| - Resolving what a domain concept IS (not just its label) → a | ||
| domain-modelling capability. Hand a settled domain term there. | ||
| - Sweeping references after a rename is decided → a rename-references | ||
| capability. This skill picks the name; that one propagates it. | ||
|
|
||
| Invoke an adjacent capability through its slash command when present; | ||
| degrade to prose guidance when it is absent. | ||
|
|
||
| ## What this skill does NOT do | ||
|
|
||
| - **Never auto-locks a name.** It always ends at a human choice. | ||
| - **Does not apply the rename.** Propagating a chosen name across call | ||
| sites is a rename-references capability's job. | ||
| - **Does not copy or invent criteria.** It scores against the resolved | ||
| source of truth; missing criteria route upstream, not into the skill. | ||
| - **Does not claim tournament mode is a documented technique** — it is an | ||
| adaptation, flagged as one. | ||
|
|
||
| ## Gotchas | ||
|
|
||
| - If the generators are fed the conversation instead of just the brief, | ||
| the anti-anchoring purpose is defeated — they will re-derive the | ||
| rejected name. Seed them with the brief ONLY. | ||
| - A blind generator can still independently re-derive the rejected | ||
| incumbent (common for generic labels like `Manager` or `Context`). That | ||
| is not a blinding failure — the main thread's reject list disqualifies | ||
| it at merge time regardless of how a candidate was produced. | ||
| - A candidate that scores well but collides with existing vocabulary is | ||
| disqualified, not shortlisted — collision-check before scoring. | ||
| - `tournament` costs several generators plus judges; reserve it for names | ||
| that are genuinely expensive to change, not routine locals. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| # Method sources — name-it-better | ||
|
|
||
| The naming CRITERIA are owned elsewhere (the consuming org's conventions — | ||
| see the skill body). This file grounds the skill's METHOD: how candidates | ||
| are generated, why generators run blind, and what the `tournament` mode is | ||
| actually adapted from. Read it only when judging a method question or | ||
| extending the skill. Tiers: PRIMARY = author's own words / official | ||
| spec; AUTHORITATIVE = faithful canonical write-up by the originators or | ||
| their collaborators; SECONDARY = derivative. | ||
|
|
||
| ## Naming as a process (staged refinement) | ||
|
|
||
| The backbone of the default pass's distinct lenses. A name is refined | ||
| through stages rather than guessed in one shot: from missing/misleading, | ||
| to obvious-nonsense, to honest, to completely-honest, to | ||
| does-the-right-thing, to intent-revealing, to domain-abstraction. The | ||
| "responsibility-literal → moment-of-use → domain-lore" lenses map onto | ||
| the honest → intent → domain-abstraction progression. | ||
|
|
||
| - Origin, Arlo Belshee ("Read by Refactoring"): | ||
| `https://arlobelshee.com/good-naming-is-a-process-not-a-single-step/` — | ||
| PRIMARY. Flag: this host was DNS-unreachable during research, so Belshee's exact | ||
| per-stage prose is corroborated by the Deep Roots rewrite below rather | ||
| than quoted from the origin. | ||
| - Canonical rewrite, Tim Ottinger + Llewellyn Falco: [deeproots-series] | ||
| and [deeproots-path] — AUTHORITATIVE. Confirm the ordered stages and the | ||
| three-phase structure. | ||
|
|
||
| ## Naming criteria lineage (Ottinger / Clean Code) | ||
|
|
||
| Backs the scoring rubric's shape (the authoritative criteria source of | ||
| truth is the consuming org's conventions). | ||
|
|
||
| - Ottinger's Rules: [ottinger-rules] — AUTHORITATIVE. Intention-revealing, | ||
| avoid disinformation, pronounceable, no encodings, one word per concept, | ||
| meaningful in context. | ||
| - Clean Code, ch. 2 "Meaningful Names" (Martin, with Ottinger): | ||
| `https://www.oreilly.com/library/view/clean-code-a/9780136083238/chapter02.xhtml` | ||
| — PRIMARY. | ||
|
|
||
| ## Domain language | ||
|
|
||
| Backs the domain-lore lens and the "name from the shared domain | ||
| vocabulary" criterion. | ||
|
|
||
| - DDD Reference (Eric Evans): [ddd-reference] — PRIMARY. | ||
| - Ubiquitous Language (Fowler): [fowler-ubiquitous] — AUTHORITATIVE. | ||
|
|
||
| ## Blind generation → human convergence (anti-anchoring) | ||
|
|
||
| Why generators run BLIND to the conversation and the human always makes | ||
| the final pick: diverge widely from independent perspectives, then | ||
| converge once — and keep the first-seen suggestion from anchoring the | ||
| choice. | ||
|
|
||
| - Double Diamond (diverge/converge), UK Design Council: [double-diamond] | ||
| — AUTHORITATIVE. | ||
| - Anchoring bias, Tversky & Kahneman (1974), "Judgment under Uncertainty": | ||
| `https://www.science.org/doi/10.1126/science.185.4157.1124` | ||
| (open PDF: [tk-1974-pdf]) — PRIMARY. First value seen biases | ||
| the final judgment; independent-before-shared review reduces it. | ||
|
|
||
| ## `tournament` mode — adapted, NOT a documented naming technique | ||
|
|
||
| HONEST FLAG: there is no primary source describing a "naming tournament" | ||
| or "naming bracket" method for choosing identifiers. The mode is an | ||
| ADAPTATION, presented as a local convergence mechanism, not an | ||
| established naming standard. It borrows two documented, unrelated things: | ||
|
|
||
| - Elimination brackets (single/double elimination): [elim-bracket] — | ||
| SECONDARY (generic, not naming). | ||
| - Pairwise social-choice aggregation (Condorcet / Copeland / Minimax) for | ||
| turning head-to-head judgements into a ranking: [condorcet] — the | ||
| rigorous basis if judges score candidates pairwise. | ||
|
|
||
| ## Framework / style-guide naming (supporting) | ||
|
|
||
| - .NET naming guidelines (Microsoft): [dotnet-naming] — PRIMARY. | ||
| - Kevlin Henney, "Seven Ineffective Coding Habits" (naming): [henney] — | ||
| PRIMARY. Meaning over word-count; "adding words is not adding meaning". | ||
| - Google style guides (per-language naming): [google-style] — PRIMARY. | ||
|
|
||
| [deeproots-series]: https://www.digdeeproots.com/articles/naming-process/naming-as-a-process/ | ||
| [deeproots-path]: https://www.digdeeproots.com/articles/naming-process/naming-as-a-process-learning-path/ | ||
| [ottinger-rules]: https://exelearning.org/wiki/OttingersNaming/ | ||
| [ddd-reference]: https://www.domainlanguage.com/wp-content/uploads/2016/05/DDD_Reference_2015-03.pdf | ||
| [fowler-ubiquitous]: https://martinfowler.com/bliki/UbiquitousLanguage.html | ||
| [double-diamond]: https://en.wikipedia.org/wiki/Double_Diamond_(design_process_model) | ||
| [tk-1974-pdf]: https://www.cs.tufts.edu/comp/150AIH/pdf/TverskyKa74.pdf | ||
| [elim-bracket]: https://en.wikipedia.org/wiki/Double-elimination_tournament | ||
| [condorcet]: https://en.wikipedia.org/wiki/Condorcet_method | ||
| [dotnet-naming]: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/naming-guidelines | ||
| [henney]: https://www.infoq.com/presentations/7-ineffective-coding-habits/ | ||
| [google-style]: https://google.github.io/styleguide/ |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.