diff --git a/README.md b/README.md index bed9664de..5340ab99e 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ user opts in with `/plugin enable`; an existing install is never flipped by cata - [`prototype`](plugins/prototype) — Builds throwaway code to answer a design question before committing to architecture — a logic facet (an interactive terminal app over a portable state model) and a UI facet (radically different visual variants on one route). - [`planning`](plugins/planning) — Pre-implementation planning pipeline: chart a too-big, foggy effort as a decision map, diverge on candidate approaches, lock product intent and the engineering contract, route resolved domain language to the domain-driven-design glossary steward, explore the design space, stress-test adversarially, and produce a structured implementation plan with an approval gate. - [`domain-driven-design`](plugins/domain-driven-design) — Domain-driven-design practice skills. Today: actively maintains a consuming project's ubiquitous-language glossary — resolves ambiguous or overloaded terms, records canonical language and rejected synonyms, sharpens what-it-IS definitions, and routes entries to already-known bounded contexts without discovering boundaries. -- [`naming`](plugins/naming) — 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. +- [`naming`](plugins/naming) — Generates and evaluates fresh name candidates for anything — an identifier, file, module, skill, repo, or domain term — by distilling a structured context brief, fanning out blind, fresh-context generators from distinct lenses (responsibility-literal, moment-of-use, domain-lore), then scoring a shortlist against a research-ordered criteria priority resolved from 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. - [`event-storming`](plugins/event-storming) — EventStorming for domain discovery — a methodology skill (Big Picture / Process Modeling / Design-Level facilitation reference, notation, patterns) and a simulation skill (agentic multi-persona workshops that produce a structured-markdown model by default; a live Miro-board rendering path is available when the first-party miro plugin is enabled). - [`miro`](plugins/miro) — Miro board management over the Model Context Protocol: create and manage boards, sticky notes, shapes, frames, connectors, and tags for EventStorming, brainstorming, and diagramming. Bundles a local stdio MCP server (single self-contained Node artifact); installs disabled — opt in and supply a Miro API token. diff --git a/plugins/naming/.claude-plugin/plugin.json b/plugins/naming/.claude-plugin/plugin.json index a2c2b28ae..23e931be4 100644 --- a/plugins/naming/.claude-plugin/plugin.json +++ b/plugins/naming/.claude-plugin/plugin.json @@ -1,8 +1,8 @@ { "$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.", + "version": "0.2.0", + "description": "Generates and evaluates fresh name candidates for anything — an identifier, file, module, skill, repo, or domain term — by distilling a structured context brief, fanning out blind, fresh-context generators from distinct lenses (responsibility-literal, moment-of-use, domain-lore), then scoring a shortlist against a research-ordered criteria priority resolved from 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" diff --git a/plugins/naming/CHANGELOG.md b/plugins/naming/CHANGELOG.md index 51c4dc471..d1f15c076 100644 --- a/plugins/naming/CHANGELOG.md +++ b/plugins/naming/CHANGELOG.md @@ -3,6 +3,44 @@ 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.2.0] + +### Changed + +- **Structured context brief.** The loose "distill a brief" step is now a + brief with named fields — responsibility, firing/usage context, scope + boundaries (what it is NOT), collision vocabulary, and word-level + blocklist (with reasons) — mirroring the replicated concept → word → + structure naming model. The generators receive this brief, and only this + brief; rejected incumbent NAMES stay on the main-thread reject list and + never enter it. +- **Declared criteria priority.** The fallback general criteria are now + research-ordered — semantic accuracy (anti-misleading) > scope fit > + comprehensibility > trigger/evocative utility — and this ordering governs + scoring and judging. A consuming project's declared conventions still + override it. + +### Added + +- **Rejection-reason iteration protocol.** A rejected candidate's REASON is + captured as an explicit new brief constraint (a word-level blocklist + entry, a scope-boundary correction, or a criteria reweight) and fed into + the next blind round; rejected names and words never re-enter. +- **Modality layer.** Criteria split into a universal semantic layer and a + modality/vendor-specific syntactic layer; documented style conflicts + (abbreviation policy, acronym casing, casing style) route to the + consuming ecosystem's own style guide rather than a house verdict. For + Claude Code skills, the description — not the name — drives discovery, so + the name optimises for human semantic accuracy. +- **Strengthened domain-concept pointer.** When the target is a domain + concept, route to a domain-modelling capability to settle what it IS + before naming it (pointer only). +- **Research grounding.** `context/sources.md` adds the primary empirical + sources behind the criteria priority (Feitelson TSE 2022, Alpern 2024 + reproduction, Avidan & Feitelson 2017, Hofmeister 2017) and the modality + layer (clig.dev, Claude Code skills docs, the conflicting style guides), + and honestly marks paywalled book sources as Tier-2-for-verification. + ## [0.1.0] ### Added diff --git a/plugins/naming/README.md b/plugins/naming/README.md index 8460d8f54..2d40402e4 100644 --- a/plugins/naming/README.md +++ b/plugins/naming/README.md @@ -14,8 +14,11 @@ lenses, then hand the human a scored shortlist to choose from. 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 +a structured context brief (responsibility, firing context, scope +boundaries, collision vocabulary, word-level blocklist — rejected NAMES +stay on the main thread's reject list, never in the 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`. @@ -37,9 +40,10 @@ presents it as such. - **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 + it points to). When none is declared, it falls back to a research-ordered + general criteria priority — semantic accuracy first, trigger utility last + — 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 diff --git a/plugins/naming/skills/name-it-better/SKILL.md b/plugins/naming/skills/name-it-better/SKILL.md index 731e61d79..155ca1a39 100644 --- a/plugins/naming/skills/name-it-better/SKILL.md +++ b/plugins/naming/skills/name-it-better/SKILL.md @@ -33,18 +33,81 @@ its own context, never from a baked-in path: 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. + [`context/sources.md`](context/sources.md), applied in this + research-ordered priority — a higher tier breaks ties over every tier + below it: + 1. **Semantic accuracy (anti-misleading).** The name must not lie about + what the thing does. A misleading name is empirically worse than a + vague or meaningless one, so this outranks everything below. + 2. **Scope fit.** Length and detail scale with the thing's scope and + lifetime; never repeat information the surrounding context (package, + type, module) already supplies. + 3. **Comprehensibility.** Prefer full, intention-revealing words over + abbreviations — bounded: established idioms and conventionally short + names (loop `i`, a receiver) are not penalised. + 4. **Trigger / evocative utility.** How well the name cues recall at the + moment of use — a genuine tiebreaker, but the lowest-priority one. + + This ordering governs the scoring and judging steps. It is the fallback + only: a consuming project's declared criteria (rule 1) override it + wherever the two differ. + +## Semantic vs syntactic — the modality layer + +Naming criteria split in two. The **semantic layer** — accuracy, scope +fit, no collisions, noun-for-a-thing / verb-for-an-action — carries across +every modality, and is what the generators and judges optimise. The +**syntactic layer** — casing, length budgets, separator and affix +conventions — is modality- and vendor-specific; apply it as a final +shaping pass over the semantic winners, never as a scoring axis that +overrides meaning. Shaping can change the string, so RE-RUN the full +merge-step filter set — dedupe, collision, reject-list, word-blocklist — +on the shaped forms: two distinct candidates can normalize to one string +(`SessionStore` and `session-store` → `session_store`), a normalization +can recreate an existing sibling or a rejected incumbent, and a required +affix can introduce a blocked word (`Order` → `OrderManager`) that the +pre-scoring filters could not match. + +- **Route documented conflicts out; do not pick a side.** Where authorities + genuinely disagree — abbreviation policy, acronym casing, camelCase vs + snake_case — this skill takes no house position. Defer to the consuming + ecosystem's own style guide (rule 1's declared conventions); the + conflicting primaries are catalogued in + [`context/sources.md`](context/sources.md). +- **Claude Code skills are the sharp special case.** For a skill, the + DESCRIPTION — not the name — is what drives model-side discovery. So + optimise the name for human semantic accuracy, and put the trigger + phrases and example requests in the description, not the name. ## 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. +1. **Build the structured context brief.** This brief — NOT the + conversation — is all the generators receive, so it must carry every + field they need, each captured by name: + - **Target modality** — what KIND of thing is being named (function, + type, module, file, CLI command, skill, domain term): it fixes + noun-for-a-thing vs verb-for-an-action and tells the final shaping + pass which syntactic conventions apply. + - **Responsibility** — what the thing DOES, in one line. + - **Firing / usage context** — when it is reached for, and how it reads + at the call site. + - **Scope boundaries** — what it is NOT: the adjacent things it must not + be confused with or blur into. + - **Collision vocabulary** — the existing sibling names it must not + duplicate. + - **Word-level blocklist** — individual words ruled out, each WITH its + reason (overloaded, misleading, collides, already rejected). + + Rejected incumbent NAMES deliberately stay out of the brief — the main + thread holds them as its reject list and disqualifies matches at merge + time (anti-anchoring: a generator shown a rejected name re-derives it). + Only the abstracted REASON a name failed enters the brief, as a + blocklist entry or scope-boundary correction. + + The brief mirrors the replicated concept → word → structure naming model + (grounded in [`context/sources.md`](context/sources.md)): the named + fields fix the concepts and constraints; the generators then choose the + words per concept and arrange the structure. 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: @@ -57,13 +120,37 @@ its own context, never from a baked-in path: 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. + generators — that contains a word-level blocklist entry (a generator + can miss the brief's constraint; the merge step enforces it), or that + collides with the existing vocabulary. Score every + surviving candidate against the criteria resolved above, breaking ties + by their declared priority order. 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. +## Iterate on the rejection reason + +If the human rejects the shortlist or a specific candidate, the rejection +is data, not a dead end. Capture the REASON as an explicit new constraint +and fold it into the next round's brief before regenerating: + +- a word that drew the objection becomes a **word-level blocklist** entry, + carrying that reason; +- a "wrong scope / wrong thing" objection becomes a **scope-boundary** + correction; +- a "these all miss what matters" objection **reweights the criteria** for + the next round — but only within the space the consuming project's + declared conventions leave open. Declared conventions still win: a + rejection that contradicts them routes upstream as a proposed convention + change, never a silent local reweighting. + +Rejected names and rejected words never re-enter — the reject list and the +word-level blocklist only grow across rounds. Each new round is a fresh +blind fan-out seeded with the corrected brief, never a patch of the last +round's candidates. + ## `tournament` action When `$ARGUMENTS` contains `tournament`, run this in place of the default @@ -75,10 +162,11 @@ 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 reject-list, word-level-blocklist, and collision disqualification from +the default pass's merge step still apply: pool the widened candidates and +disqualify any that match the rejected incumbent, contain a blocklisted +word, or collide with the existing vocabulary BEFORE the elimination +rounds begin — a rejected, blocklisted, or colliding name must never enter the bracket, let alone reach the finalist. HONEST FRAMING: a "naming tournament / bracket" is NOT a documented @@ -89,10 +177,13 @@ 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. +- **The target is a domain concept.** Naming a domain term well depends on + first settling what the concept IS, not just its label. Route that to a + domain-modelling capability, then name the settled concept once it + returns. Pointer only — this skill does not do the domain modelling. +- **A rename is already decided.** Sweeping references after the fact → + 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. @@ -106,6 +197,9 @@ degrade to prose guidance when it is absent. 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. +- **Does not pick a house side on documented style conflicts** — + abbreviation policy, acronym casing, and casing style route to the + consuming ecosystem's own style guide, never a baked-in verdict. ## Gotchas @@ -118,5 +212,8 @@ degrade to prose guidance when it is absent. 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. +- A rejected candidate's REASON must become a brief constraint (a blocklist + word, a scope correction, a criteria reweight) before the next round, or + the blind fan-out re-derives the same reject. - `tournament` costs several generators plus judges; reserve it for names that are genuinely expensive to change, not routine locals. diff --git a/plugins/naming/skills/name-it-better/context/sources.md b/plugins/naming/skills/name-it-better/context/sources.md index 55874738a..831abc845 100644 --- a/plugins/naming/skills/name-it-better/context/sources.md +++ b/plugins/naming/skills/name-it-better/context/sources.md @@ -1,12 +1,17 @@ # 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 +see the skill body). This file grounds the skill's METHOD — how candidates +are generated, why generators run blind, what the `tournament` mode is +adapted from — and the RESEARCH ORDERING behind the fallback general +criteria (semantic accuracy → scope fit → comprehensibility → trigger +utility) the skill applies only when no convention is declared. Read it +when judging a method question, weighing the fallback criteria, 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. +their collaborators; SECONDARY = derivative. A source whose full text was +paywalled this pass is flagged Tier-2-for-verification regardless of its +nominal tier. ## Naming as a process (staged refinement) @@ -26,6 +31,34 @@ the honest → intent → domain-abstraction progression. and [deeproots-path] — AUTHORITATIVE. Confirm the ordered stages and the three-phase structure. +## Empirical naming studies — criteria-priority backbone + +Backs the declared criteria priority (semantic accuracy → scope fit → +comprehensibility → trigger utility) and the structured brief's +concept → word → structure shape. Peer-reviewed, primary-fetched. + +- Feitelson et al., "How Developers Choose Names," IEEE TSE 48(1), 2022 + (arXiv:2103.07487): [feitelson-tse] — PRIMARY. Two load-bearing findings: + (a) median ~6.9% agreement between any two developers naming the same + thing — no single namer converges, which validates blind multi-generator + fan-out; (b) an explicit three-step model (select concepts → choose words + → arrange structure) produced names judged better ~2:1, which the + structured brief mirrors. +- Alpern et al., "Reproducing, Extending, and Analyzing Naming + Experiments," arXiv:2402.10022, 2024: [alpern-repro] — PRIMARY. + Independent reproduction (~6% agreement); instructing "longer names are + better" alone produced NO improvement — the three-step process, not + length, drives the gain. +- Avidan & Feitelson, "Effects of Variable Names on Comprehension," ICPC + 2017: [avidan-feitelson] — PRIMARY. Misleading names measured as bad as + or worse than meaningless single letters — the evidence for ranking + semantic accuracy above every other criterion. +- Hofmeister, Siegmund & Holt, "Shorter Identifier Names Take Longer to + Comprehend," SANER 2017: [hofmeister] — PRIMARY. Full-word identifiers + ~19% faster to comprehend than abbreviations/letters — bounds the + comprehensibility tier: prefer full words, but the effect is an average, + moderated by experience, not absolute. + ## Naming criteria lineage (Ottinger / Clean Code) Backs the scoring rubric's shape (the authoritative criteria source of @@ -33,10 +66,12 @@ 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. + meaningful in context. The fetchable stand-in for the Clean Code chapter. - Clean Code, ch. 2 "Meaningful Names" (Martin, with Ottinger): `https://www.oreilly.com/library/view/clean-code-a/9780136083238/chapter02.xhtml` - — PRIMARY. + — nominally PRIMARY (the authors' own chapter), but the full text is + paywalled and was NOT obtained this pass; its specific rules rest on + secondary write-ups, so treat it as Tier-2-for-verification. ## Domain language @@ -73,9 +108,35 @@ established naming standard. It borrows two documented, unrelated things: turning head-to-head judgements into a ranking: [condorcet] — the rigorous basis if judges score candidates pairwise. +## Modality layer — semantic vs syntactic + +Backs the skill's semantic/syntactic split and the rule that documented +style conflicts route to the consuming ecosystem, not a house verdict. + +- CLI naming conventions, clig.dev: [clig] — PRIMARY (community standard). + Lowercase-dash names, noun-verb subcommands, a full `--flag` for every + short flag — syntactic conventions that do not transfer to other + modalities. +- Claude Code skills, official docs: [cc-skills] — PRIMARY. The + `description`, not the `name`, is what Claude uses to decide when to load + a skill (combined description text truncated at 1,536 chars in the skill + listing). So the name serves the human; the trigger phrases live in the + description. HIGH confidence — falsification survived in the research pass. +- Documented, unresolved style conflicts — route to the consuming + ecosystem's guide, do not pick a side: + - abbreviation policy — .NET forbids ([dotnet-naming]) vs Go endorses + short scope-local names ([effective-go]); + - acronym casing — Go `URL`/`appID` ([go-initialisms]) vs .NET/Java + `Xml`/`Html` ([dotnet-naming], [google-style]); + - camelCase vs snake_case — no settled comprehension verdict; PEP 8 + ([pep8]) and each ecosystem's guide decide it locally. + ## Framework / style-guide naming (supporting) -- .NET naming guidelines (Microsoft): [dotnet-naming] — PRIMARY. +- .NET naming guidelines (Microsoft): [dotnet-naming] — PRIMARY. Reproduces + the 2008 2nd-edition text (self-flagged); the 3rd edition (2020) is not + freely available, so treat the specific DO/DO NOT rules as Tier-2 pending + the current edition. - 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. @@ -92,3 +153,12 @@ established naming standard. It borrows two documented, unrelated things: [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/ +[feitelson-tse]: https://www.cs.huji.ac.il/~feit/papers/Names22TSE.pdf +[alpern-repro]: https://arxiv.org/abs/2402.10022 +[avidan-feitelson]: https://www.cs.huji.ac.il/~feit/papers/Names17ICPC.pdf +[hofmeister]: https://brains-on-code.github.io/shorter-identifier-names.pdf +[clig]: https://clig.dev/ +[cc-skills]: https://code.claude.com/docs/en/skills +[effective-go]: https://go.dev/doc/effective_go#names +[go-initialisms]: https://go.dev/wiki/CodeReviewComments +[pep8]: https://peps.python.org/pep-0008/ diff --git a/plugins/naming/skills/name-it-better/evals/evals.json b/plugins/naming/skills/name-it-better/evals/evals.json index 2a5782184..7bae575e4 100644 --- a/plugins/naming/skills/name-it-better/evals/evals.json +++ b/plugins/naming/skills/name-it-better/evals/evals.json @@ -5,10 +5,10 @@ "id": 1, "name": "rejected-name-blind-retry-to-human-pick", "prompt": "name it better — you suggested `DataManager` for the class that validates and persists orders and I don't like it.", - "expected_output": "The skill distills a context brief (responsibility, scope, constraints, surrounding vocabulary, overloaded-term blocklist), fans out ~3 fresh-context generators seeded ONLY with the brief (blind to this conversation) across the three lenses, merges and collision-checks, scores against the resolved criteria, and presents a ranked shortlist with a single marked RECOMMENDED pick — then stops for the human to choose.", + "expected_output": "The skill builds a structured context brief with named fields (responsibility, firing/usage context, scope boundaries, collision vocabulary, word-level blocklist with reasons — the rejected NAME itself stays out of the brief, held on the main-thread reject list, with only its abstracted rejection reason entering as a constraint), fans out ~3 fresh-context generators seeded ONLY with the brief (blind to this conversation) across the three lenses, merges and collision-checks, scores against the resolved criteria priority, and presents a ranked shortlist with a single marked RECOMMENDED pick — then stops for the human to choose.", "files": [], "expectations": [ - "Distills a context brief and seeds the generators with the brief ONLY (blind to the conversation), not the rejected name", + "Builds a structured context brief with named fields (responsibility, firing/usage context, scope boundaries, collision vocabulary, word-level blocklist carrying the abstracted rejection reason) and seeds the generators with the brief ONLY (blind to the conversation) — the rejected name itself never appears in the brief", "Fans out ~3 fresh-context generators across distinct lenses (responsibility-literal, moment-of-use, domain-lore)", "Carries `DataManager` as a main-thread reject list and disqualifies it at merge time, even if a generator independently re-derives it", "The rejected incumbent (`DataManager`) does not appear in the final shortlist", @@ -64,6 +64,19 @@ "Neither the rejected incumbent nor a colliding candidate appears as the finalist or among the runners-up", "Still widens to ~5 generators, runs elimination rounds with independent judges, and ends at a human pick" ] + }, + { + "id": 6, + "name": "rejection-reason-becomes-next-round-constraint", + "prompt": "name it better for this cache wrapper. [after a first shortlist] no — `Store` is wrong, it's read-through only and never owns the data, and stop giving me `Manager` names.", + "expected_output": "The skill treats the rejection as data: it captures the REASON as explicit new brief constraints — a scope-boundary correction (read-through only, does not own the data) and word-level blocklist entries (`Store`, `Manager`) with their reasons — then runs a fresh blind fan-out seeded with the corrected brief. Rejected names and words never re-enter, and it ends at a human pick over the new shortlist.", + "files": [], + "expectations": [ + "Captures the rejection reason as explicit new brief constraints (a scope-boundary correction plus word-level blocklist entries), not a one-off filter", + "Blocklists `Store` and `Manager` with their reasons so neither re-enters any later round", + "Runs a fresh blind fan-out on the corrected brief rather than patching the previous round's candidates", + "Ends at a human pick over the new shortlist" + ] } ] }