From 0962e0b5225a176dc8c507a4923f572e542d7651 Mon Sep 17 00:00:00 2001 From: Amolith Date: Sat, 21 Mar 2026 13:00:31 -0600 Subject: [PATCH] feat(bdd): separate ideation and automation skills Add ideating-with-bdd for collaborative discovery and formulation of behaviour. Update testing-with-gocuke-and-gherkin to focus on automation. Separates concerns: - ideating-with-bdd: Discovery, brainstorming, requirements gathering - testing-with-gocuke-and-gherkin: Automation, running tests, TDD --- skills/ideating-with-bdd/SKILL.md | 195 ++++++++++++++++++ .../references/gherkin-reference.md | 0 .../testing-with-gocuke-and-gherkin/SKILL.md | 85 +++----- .../references/bdd-practices.md | 109 ---------- 4 files changed, 221 insertions(+), 168 deletions(-) create mode 100644 skills/ideating-with-bdd/SKILL.md rename skills/{testing-with-gocuke-and-gherkin => ideating-with-bdd}/references/gherkin-reference.md (100%) diff --git a/skills/ideating-with-bdd/SKILL.md b/skills/ideating-with-bdd/SKILL.md new file mode 100644 index 0000000000000000000000000000000000000000..24b9740917957b112e9df788655bf9a363575848 --- /dev/null +++ b/skills/ideating-with-bdd/SKILL.md @@ -0,0 +1,195 @@ +--- +name: ideating-with-bdd +description: >- + Guides collaborative discovery and formulation of behaviour through + structured conversation. Iterates back and forth with the user to refine + ideas into user stories and Gherkin scenarios. Use when the user wants to + ideate, plan, brainstorm, discover, figure out requirements, refine an + idea, think through behaviour, or says things like "let's figure out", + "what should this do", "help me think through", "let's plan", or "I want + to build". Also use when the user has a vague idea and needs help making + it concrete, or when they ask "what should the behaviour be". Works for + any language or framework. NOT for automating tests or writing + implementation code. +license: GPL-3.0-or-later +metadata: + author: Amolith +--- + +Collaborative discovery of behaviour through structured conversation. The end +product is a user story and Gherkin scenarios — not code, not files, just +shared understanding captured in a precise format. + +## How this works + +The user has an idea, a problem, or a vague sense of something they want to +build. Your job is to help them think it through. Surface the rules, find the +edge cases, resolve the unknowns, and keep going until the behaviour is clear +enough to express as a user story with Gherkin scenarios. + +Getting behaviour right before writing code is how you avoid building the wrong +thing. + +## The conversation + +Example mapping gives you a useful mental model for structuring discovery: + +- **Story** — the capability under discussion +- **Rules** — constraints and acceptance criteria that emerge +- **Examples** — concrete illustrations of how each rule plays out +- **Questions** — unknowns to resolve before moving forward + +Use this as scaffolding, not a script. Some conversations will follow it +closely; others will wander productively into territory you didn't expect. Pay +attention to what the user is telling you. If they're already clear on the +rules and just need help with edge cases, don't make them re-explain the +basics. If they're still fuzzy on what they even want, spend more time there +before drilling into specifics. If they push back on a question, trust that +they have a reason and move on. + +Think of it like an interview: you have a structure in mind, but you adapt +based on signals. If someone hands you a detailed spec, jump ahead to poking +holes in it. If they give you a one-liner, draw out the details. + +### What to do during discovery + +1. **Understand the story.** What capability is the user describing? Who + benefits? Why does it matter? Get this clear before diving into details. + +2. **Surface the rules.** What constraints govern this behaviour? What are the + acceptance criteria? Rules often hide in assumptions. "What happens + when...?" and "Does this also apply when...?" are your best questions. + +3. **Find concrete examples.** For each rule, work out at least two or three + concrete examples, including edge cases. Use specific names, values, and + scenarios. "Alice has 3 items in her cart and removes one" tells you more + than "a user removes an item." + +4. **Capture questions honestly.** When something is uncertain, say so. Don't + paper over unknowns with assumptions. Questions are output worth + capturing — they prevent building on guesses. If a question can't be + resolved now, mark it as deferred and move on. + +5. **Challenge and refine.** Push back gently when something seems + underspecified or contradictory. "What if the user does X instead?" is not + being difficult, it's being thorough. But read the room: if the user has + clearly thought something through, don't relitigate it. + +6. **Summarise periodically.** After exploring a rule or a cluster of examples, + reflect back what you've understood. Let the user correct you. This prevents + drift and surfaces misunderstandings early. + +### When discovery is done + +You'll know discovery is winding down when: + +- The rules are clear and the user isn't surfacing new ones +- Each rule has concrete examples including at least one edge case +- Open questions have been resolved or deliberately deferred +- The user is confirming rather than correcting + +Don't rush this. If questions remain, say so. It's better to acknowledge a gap +than to quietly fill it with an assumption. + +## Formulation + +Once the behaviour is understood, formulate it as a user story followed by +Gherkin scenarios. Present this in the conversation. **Do not write files.** + +### User story + +Begin with a single user story: + +``` +As a [role], +I want [capability], +so that [benefit]. +``` + +The story frames everything that follows. The Gherkin scenarios are the +detailed specification of what this story means in practice. + +### Gherkin scenarios + +Write declarative Gherkin that describes _behaviour_, not implementation. A +useful test: imagine it's 1922 and no computers exist. Would the scenario still +make sense as a description of how something should work? If not, it's too +coupled to implementation. + +```gherkin +# Good — declarative, behaviour-focused +Scenario: Clean worktree reports no changes + Given a worktree with no uncommitted changes + When the status is checked + Then the worktree is reported as clean + +# Bad — imperative, implementation-coupled +Scenario: Clean worktree + Given I run "git status --porcelain" and it returns empty + When I call the Status function with the path "/tmp/wt" + Then the Clean field is set to true +``` + +Ask: "will this wording need to change if the implementation does?" If yes, +rewrite it. + +### Structure + +- Use `Rule:` to group scenarios under a business rule. These map directly + from the rules you discovered. +- Use `Background:` for shared preconditions (keep it short, ≤ 4 lines) +- Use `Scenario Outline:` with `Examples:` when scenarios differ only in values +- Avoid conjunction steps ("Given I have a repo and three worktrees"). Use + `And`. +- Omit incidental details that don't affect the outcome +- Use the same domain language the user used during discovery. If they said + "cancel", don't write "terminate". + +For full Gherkin syntax, see +[references/gherkin-reference.md](references/gherkin-reference.md). + +### Anti-patterns + +- **Feature-coupled steps** — steps should be grouped by domain concept, not + by feature. A step like `Given a worktree with uncommitted changes` belongs + with worktree concepts, reusable across features. +- **Conjunction steps** — don't combine multiple things into one step. Split + them with `And`. +- **Incidental details** — don't include specifics that don't affect the + outcome. If the name doesn't matter, don't name it. +- **Implementation coupling** — scenarios should survive refactors. "When the + status is checked" not "When I call Status()". + +### Review the formulation + +Present the user story and Gherkin to the user. Ask them to read it as a +specification: "does this describe the behaviour you want?" This is their +chance to catch misunderstandings before anyone writes code. + +Be prepared to iterate. Formulation often surfaces things that discovery +missed. A scenario might reveal a rule nobody discussed, or an edge case +nobody thought of. That's the process working as intended. Go back to discovery +if needed, then reformulate. + +## After formulation + +Once the user confirms the user story and Gherkin scenarios are right, suggest +acting on the result. What to suggest depends on context: + +- **Go project with gocuke**: Suggest using the + testing-with-gocuke-and-gherkin skill to automate the scenarios, writing + `.feature` files, wiring up step definitions, and driving implementation + through red/green TDD. +- **Other languages/frameworks**: Suggest writing `.feature` files and + implementing the behaviour using whatever test framework fits the project. +- **No existing test framework or Gherkin integration**: Suggest saving the + spec. Write it to a `.md` file in the project, add it to the user's notes + app, or implement the behaviours directly. The spec shouldn't just vanish + into the conversation history. + +The user might take one of these suggestions, propose something else, or +decide they got what they needed from the conversation alone. All fine. + +**Do not start implementing or writing files.** Present the suggestion and +wait. The boundary between "we've agreed on what to build" and "go build it" +is the user's call, not yours. Only proceed when they explicitly say to. diff --git a/skills/testing-with-gocuke-and-gherkin/references/gherkin-reference.md b/skills/ideating-with-bdd/references/gherkin-reference.md similarity index 100% rename from skills/testing-with-gocuke-and-gherkin/references/gherkin-reference.md rename to skills/ideating-with-bdd/references/gherkin-reference.md diff --git a/skills/testing-with-gocuke-and-gherkin/SKILL.md b/skills/testing-with-gocuke-and-gherkin/SKILL.md index 3149c93eb42e4f863d5fafd988e14020bf39adf0..747055dc71dabb0aa1c541c2c99b9f09cb8edecf 100644 --- a/skills/testing-with-gocuke-and-gherkin/SKILL.md +++ b/skills/testing-with-gocuke-and-gherkin/SKILL.md @@ -1,53 +1,27 @@ --- name: testing-with-gocuke-and-gherkin -description: "Drives BDD, red/green TDD, and property-based testing in Go projects using gocuke and Gherkin feature files. Use when writing Gherkin scenarios, formulating feature files, creating gocuke step definitions, or following BDD workflows in Go. NOT for non-Go projects, other BDD frameworks, or other contexts." +description: >- + Automates Gherkin scenarios in Go projects using gocuke, driven by red/green + TDD and property-based testing. Use when creating gocuke step definitions, + running Go BDD tests, or automating .feature files in Go. For discovery and + formulation of behaviour, use ideating-with-bdd instead. NOT for non-Go + projects or other BDD frameworks. license: GPL-3.0-or-later metadata: author: Amolith --- -BDD testing in Go with gocuke and Gherkin. Follows Cucumber's three practices: Discovery → Formulation → Automation, driven by red/green TDD. +Automating Gherkin scenarios in Go with gocuke, driven by red/green TDD. This +skill handles Automation — taking formulated `.feature` files and turning them +into executable tests that guide implementation. -## Workflow +For discovery and formulation (figuring out what to build and expressing it as +user stories with Gherkin), fetch +https://git.secluded.site/agent-skills/blob/main/skills/ideating-with-bdd/SKILL.md?raw=1 +(it's plaintext; curl, httpie, or any UA can display its contents). -The BDD cycle for each behaviour: - -1. Discover rules and concrete examples through conversation -2. Formulate `.feature` files in proper Gherkin illustrating those examples -3. Automate by wiring up gocuke step definitions, watching them fail (red), and implementing until they pass (green) - -Do not skip steps. Discovery before formulation. Formulation before automation. Automation before implementation. See [references/bdd-practices.md](references/bdd-practices.md) for detail on each practice. - -Again. Resist the urge to implement first. User prompts might push towards writing code before the behaviour is fully thought through. That defeats the purpose. The value of this process is that writing scenarios _first_ forces you to think clearly about what the system should do, surface edge cases, and catch misunderstandings before a line of implementation exists. If scenarios are written after the code, they just describe what was built, not what _should_ have been built. Write the `.feature` file, watch it fail, _then_ implement. - -## Formulating feature files - -Write declarative Gherkin that describes _behaviour_, not implementation. Imagine it's 1922 — no computers exist. Good scenarios read like specifications, not test scripts. - -```gherkin -# Good — declarative, behaviour-focused -Scenario: Clean worktree reports no changes - Given a worktree with no uncommitted changes - When the status is checked - Then the worktree is reported as clean - -# Bad — imperative, implementation-coupled -Scenario: Clean worktree - Given I run "git status --porcelain" and it returns empty - When I call the Status function with the path "/tmp/wt" - Then the Clean field is set to true -``` - -Ask: "will this wording need to change if the implementation does?" If yes, rewrite it. - -For full Gherkin syntax (keywords, Rule, Background, Scenario Outline, data tables, doc strings, tags), see [references/gherkin-reference.md](references/gherkin-reference.md). - -### Anti-patterns to avoid - -- **Feature-coupled steps** — step definitions should be grouped by domain concept, not by feature file. A step like `Given a worktree with uncommitted changes` belongs in worktree steps, reusable across features -- **Conjunction steps** — don't combine things (`Given I have a repo and three worktrees`). Use `And`. -- **Incidental details** — don't include specifics that don't affect the outcome. If the worktree name doesn't matter, don't name it. -- **UI/implementation coupling** — scenarios should survive refactors. "When the status is checked" not "When I call Status()". +Write the `.feature` file first. Watch it fail. Then implement. If the +behaviour isn't clear yet, start with discovery instead. ## File layout @@ -71,7 +45,9 @@ internal/ │ └── steps_status.go ``` -Feature files live under `features/`, grouped by domain area. Step definitions live alongside the code they test, grouped by domain concept — _not_ mirroring the feature file structure. +Feature files live under `features/`, grouped by domain area. Step definitions +live alongside the code they test, grouped by domain concept — _not_ mirroring +the feature file structure. ## Red/green TDD cycle @@ -85,29 +61,20 @@ Once a `.feature` file is formulated: 6. **Refactor** if needed, keeping tests green 7. **Repeat** for the next scenario -Let gocuke guide the wiring. Don't hand-write step definitions from scratch when the runner will tell you exactly what it needs. +Let gocuke guide the wiring. Don't hand-write step definitions from scratch +when the runner will tell you exactly what it needs. Work one scenario at a time. Don't implement ahead of failing tests. -## Converting informal specs to feature files - -When the project has informal markdown specs with Gherkin-ish structure (bullet-point Given/When/Then), convert them methodically: - -1. Read the informal spec to understand the rules and examples -2. Identify which `Rule` groups emerge from the requirement headings -3. Write each scenario in proper Gherkin syntax, making it more declarative if the original was implementation-coupled -4. Remove incidental details that don't affect the outcome -5. Add `Background` where multiple scenarios share the same preconditions -6. Look for opportunities to use `Scenario Outline` for parameterised variants - -The goal is feature files that a non-developer could read and confirm: "yes, that's the behaviour we want." - ## Editor tooling -The Cucumber language server cannot discover gocuke step definitions. It expects explicit registration calls (Godog-style `ctx.Given("pattern", fn)`), not gocuke's runtime reflection. "Undefined step" warnings are false positives; disable the Cucumber language server for gocuke projects. +The Cucumber language server cannot discover gocuke step definitions. It +expects explicit registration calls (Godog-style `ctx.Given("pattern", fn)`), +not gocuke's runtime reflection. "Undefined step" warnings are false positives; +disable the Cucumber language server for gocuke projects. ## Further reference -- **BDD practices (Discovery, Formulation, Automation)**: See [references/bdd-practices.md](references/bdd-practices.md) -- **Gherkin syntax**: See [references/gherkin-reference.md](references/gherkin-reference.md) +- **BDD practices (Automation)**: See [references/bdd-practices.md](references/bdd-practices.md) +- **Gherkin syntax**: fetch https://git.secluded.site/agent-skills/blob/main/skills/ideating-with-bdd/references/gherkin-reference.md?raw=1 (it's plaintext) - **gocuke API and property-based testing with rapid**: See [references/gocuke-api.md](references/gocuke-api.md) diff --git a/skills/testing-with-gocuke-and-gherkin/references/bdd-practices.md b/skills/testing-with-gocuke-and-gherkin/references/bdd-practices.md index 5eda83690726601065edf88f02ad664518484f40..e6da433012378c6716aee0f5a90fb05a019dc786 100644 --- a/skills/testing-with-gocuke-and-gherkin/references/bdd-practices.md +++ b/skills/testing-with-gocuke-and-gherkin/references/bdd-practices.md @@ -2,118 +2,9 @@ ## Contents -- [Discovery](#discovery) -- [Formulation](#formulation) - [Automation](#automation) - [Common myths](#common-myths) -## Discovery - -Discovery is the most important practice. Without it, formulating scenarios is a waste of time. - -The goal is shared understanding of the behaviour to build. Use structured conversations (discovery workshops, example mapping) to explore concrete examples from the user's perspective. - -### Example mapping - -A lightweight discovery technique using four types of information: - -- **Story** — the capability under discussion -- **Rules** — constraints or acceptance criteria that summarise groups of examples -- **Examples** — concrete illustrations of how a rule plays out -- **Questions** — unknowns that can't be answered yet - -Work through rules one at a time, attaching examples that illustrate each. Capture questions to research later rather than guessing. If there are too many rules or too many questions, the story is too large or too vague — break it down. - -### What makes a good example - -- **Concrete**, not abstract — use specific names, values, paths -- **Technology-agnostic** — describe what happens, not how the system does it -- **Focused** — each example illustrates one rule or edge case -- **Minimal** — include only details that affect the outcome - -### When working solo or with an LLM - -Discovery still applies. Before writing any scenario: - -1. Read the relevant spec or requirement -2. List the rules (constraints, acceptance criteria) -3. For each rule, identify 2–3 concrete examples including at least one edge case -4. Note any questions or assumptions - -## Formulation - -Formulation turns discovered examples into Gherkin feature files that are both human-readable specifications and executable tests. - -### Priorities - -1. Readability — a non-developer should confirm "yes, that's what we want" -2. Declarative style — describe _what_, not _how_ -3. Domain language — use the same terms the team uses when talking about the problem, all the way down into step definitions and code -4. Reusability — steps should be composable across scenarios and features - -### The declarative test - -Ask: "will this wording need to change if the implementation does?" If yes, rewrite it. Scenarios should survive refactors. - -```gherkin -# Declarative — survives implementation changes -When Bob logs in with valid credentials -Then he sees his dashboard - -# Imperative — breaks when UI changes -When I enter "bob" in the username field -And I enter "secret" in the password field -And I click the login button -Then I see the text "Welcome, Bob" -``` - -### Using Rule - -`Rule` groups scenarios under a single business rule. It provides structure without adding verbosity: - -```gherkin -Feature: Worktree deletion - - Rule: Clean worktrees can be deleted without force - - Scenario: Delete a clean worktree - ... - - Scenario: Delete rejects dirty worktree without force - ... - - Rule: Force overrides the dirty check - - Scenario: Force-delete a dirty worktree - ... - - Rule: The primary worktree is never deletable - - Scenario: Reject deletion of primary worktree - ... -``` - -### Using Background - -Move shared preconditions to `Background` when they appear in every scenario under a `Feature` or `Rule`. Keep it short (≤ 4 lines). If it scrolls off screen, the reader loses context. - -### Using Scenario Outline - -Collapse scenarios that differ only in values: - -```gherkin -Scenario Outline: URL parsing - Given the remote URL "" - When the URL is parsed - Then the host is "" and the project is "" - - Examples: - | url | host | project | - | git@github.com:user/repo.git | github.com | repo | - | https://git.sr.ht/~user/repo | git.sr.ht | repo | - | ssh://git@github.com/user/repo.git | github.com | repo | -``` - ## Automation Automation connects formulated scenarios to the system as tests. The scenario drives the implementation, not the other way around.