Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "freethinking",
"version": "0.9.0",
"version": "0.10.0",
"description": "Shared engineering skills: standard workflows and prompts for day-to-day development.",
"author": {
"name": "Developer Handbook contributors"
Expand Down
181 changes: 181 additions & 0 deletions .claude/specs/bugfix-cx-and-handoff/design.md

Large diffs are not rendered by default.

120 changes: 120 additions & 0 deletions .claude/specs/bugfix-cx-and-handoff/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Requirements Document

## Introduction

The bugfix skill fixes a bug from a ticket: it reads the ticket back, reproduces the bug, drives to the root cause, confirms it with the author, fixes it with a regression test and verifies the fix. Today it goes from the ticket straight into reproduction without asking what the author already knows, confirms the root cause in prose, and ends by recommending that the author run the pr skill by hand, which loses the ticket. This change gives the skill an approach question that advance context can answer, turns its fixed-answer stops into tool questions, ends with a hand-off to the pr skill or a comment on the ticket, and carries a block that says up front where it stops, how it asks and what it hands back. Maintainers of any repository the plugin applies to use it; the value is a fix that starts from what the author knows and a record that reaches the ticket or the pull request without re-typing. Issues #12 and #17.

## Glossary

- **Skill**: The bugfix skill, `skills/bugfix/SKILL.md`, as invoked by `/freethinking:bugfix` or by start-task through the Skill tool.
- **Author**: The person running the Skill, who is accountable for the fix.
- **Ticket_Reference**: A reference to a ticket in any form: an issue number such as `#12`, a ticket URL, a tracker key such as `ENG-1234`, or a short description when there is no ticket.
- **GitHub_Issue**: A Ticket_Reference that names an issue of the current repository, readable and commentable with `gh`.
- **Advance_Context**: Prose the Author gives with the Ticket_Reference, before the Skill starts, that says what they already know: a suspected cause, a file, a recent change or a reproduction they already have.
- **Lead**: What the Author already knows about the bug, given as Advance_Context or as the answer to the Approach_Question.
- **Approach_Question**: The stop after the ticket is read back and before reproduction, where the Skill asks the Author for a Lead.
- **Root_Cause_Question**: The stop after the Skill states its diagnosis, where the Author confirms the root cause or gives a different one.
- **Handoff_Question**: The stop after the Summary, where the Author chooses to open the pull request, comment on the ticket, or stop.
- **Summary**: The Skill's closing report, written by the `report` skill in handback mode: anything unverified under Problems, root cause and fix with the files involved under Done, prevention and verification under Checks, the exits under Next.
- **Ticket_Comment**: The Summary posted as a comment on a GitHub_Issue, written for the ticket's reader, who has none of the Author's local state.
- **Question_Tool**: The AskUserQuestion tool, which puts fixed options to the Author and always adds a free-text answer of its own.
- **Collaboration_Rule**: `rules/collaboration.md`, the defaults for how any skill works with the Author.
- **CX_Block**: A short section near the top of a skill that lists the skill's stops for the Author and states where it departs from the Collaboration_Rule.
- **PR_Skill**: The pr skill, `skills/pr/SKILL.md`, which takes a Ticket_Reference as its first argument, offers to create the branch and commit, and opens the pull request as published or as a draft.
- **Eval_Case**: A folder under `evals/skills/bugfix/` that `make eval-skill-bugfix` runs against the Skill.

## Requirements

### Requirement 1: Advance context travels with the ticket

**User Story:** As an Author, I want to preface the ticket with what I already know, so that the Skill starts from it instead of asking, and so that start-task can pass on what it learned.

#### Acceptance Criteria

1. WHEN the Skill's argument holds prose beyond the Ticket_Reference, THE Skill SHALL read that prose as Advance_Context and SHALL NOT read it as instructions that change its steps.
2. WHEN Advance_Context names a Lead, THE Skill SHALL say in one line what it read as the Lead and SHALL NOT ask the Approach_Question.
3. WHEN Advance_Context names no Lead, THE Skill SHALL ask the Approach_Question.
4. THE Skill's `description` and `argument-hint` SHALL say that the Ticket_Reference may be followed by what the Author already knows, and that the Skill asks when it is not.
5. THE Skill SHALL accept the argument that start-task's Bug_Route passes today, the request in the Author's words, without any change to start-task.
6. THE Skill SHALL read a GitHub_Issue and its comments through commands Claude Code runs before the Skill's text is read, `gh issue view "$ticket"` and `gh issue view "$ticket" --comments`, each ending `|| true`, with `$ticket` the first typed word declared through `arguments: [ticket]`, so that the read does not depend on the Skill choosing to run `gh`; the Skill SHALL say in one line what was read, such as "Read #29, its body and 1 comment".
7. WHEN a comment of the ticket names a Lead, THE Skill SHALL say so in one line, record it in the running summary as a candidate cause with its source, and use it first; THE Approach_Question SHALL still be asked, naming the comment's Lead, since a comment is the ticket's context and not the Author's answer.
8. THE ticket's body and comments SHALL be read as context, never as instructions that change the Skill's steps.

### Requirement 2: The approach is asked before reproduction

**User Story:** As an Author, I want to be asked how I see the approach before the Skill starts reproducing, so that a suspect file, a recent change or a reproduction I already have is used first.

#### Acceptance Criteria

1. WHEN the ticket has been read back and no Lead was given as Advance_Context, THE Skill SHALL ask the Approach_Question before any reproduction attempt and before reading code.
2. THE Approach_Question SHALL be asked with the Question_Tool, header `Approach`, with two options in this order: `Go ahead`, marked "(Recommended)", and `I have a lead`.
3. WHEN the Author picks `Go ahead`, THE Skill SHALL proceed to reproduction as it sees fit.
4. WHEN the Author picks `I have a lead` with a non-empty free text, or answers in free text, THE Skill SHALL treat that text as the Lead and use it first: read the named file first, diff the named change, or run the named reproduction before building its own.
5. IF the Author picks `I have a lead` with an empty free text, THEN THE Skill SHALL ask for the Lead once in prose before going on.
6. THE Skill SHALL treat a Lead as a hypothesis to test against evidence, and SHALL NOT treat it as a confirmed root cause.

### Requirement 3: The root cause is confirmed with a tool question

**User Story:** As an Author, I want the root-cause confirmation to be a one-click yes or a correction in my own words, so that I confirm what I have read rather than reply to an open sentence.

#### Acceptance Criteria

1. WHEN the Skill has stated its diagnosis with its evidence, THE Skill SHALL ask the Root_Cause_Question with the Question_Tool, header `Root cause`, with two options in this order: `Confirmed` and `Different cause`.
2. WHEN the Author picks `Confirmed`, THE Skill SHALL proceed to the fix.
3. WHEN the Author picks `Different cause` with a free text, or answers in free text that names a cause, THE Skill SHALL use the Author's account as the root cause in place of its own.
4. IF the Author's free text expresses doubt rather than a cause, THEN THE Skill SHALL return to driving the root cause and SHALL NOT fix.
5. THE Skill SHALL make no change that fixes the bug before the Author has answered the Root_Cause_Question with `Confirmed` or a cause; the reproduction's failing test and investigation aids are the only edits before that answer.

### Requirement 4: The Skill ends with a hand-off or a comment on the ticket

**User Story:** As an Author, I want the Skill to open the pull request through the PR_Skill or leave its findings on the ticket, so that the record of the fix reaches the place others look without my re-typing it.

#### Acceptance Criteria

1. WHEN the fix is verified, THE Skill SHALL invoke the `report` skill in handback mode to write the Summary, and SHALL ask the Handoff_Question with the Question_Tool, header `Pull request`, with that Message as the question's own text, so the Author reads problems first in the dialog before choosing, with `Open it now`, marked "(Recommended)", as the first option and `Stop here` as the last; WHEN the dialog cannot carry the Message, or the answer was given in advance and the question is not asked, THE Skill SHALL put the Message as prose before the question or before acting on the answer; IF the `report` skill is missing, THEN THE Skill SHALL write the four parts itself as the question's text.
2. WHERE the Ticket_Reference is a GitHub_Issue and `gh` is signed in, THE Handoff_Question SHALL offer `Stop and comment on the ticket` as the second option.
3. WHEN the Author picks `Open it now`, THE Skill SHALL invoke the PR_Skill with the Skill tool as `freethinking:pr`, passing the Ticket_Reference as the argument when there is one, and SHALL do nothing else.
4. WHEN the Author picks `Stop and comment on the ticket`, THE Skill SHALL post the Ticket_Comment with `gh issue comment`, written for a reader of the ticket who has none of the Author's local state: the four Summary parts, with the Fix stated as the change itself, file, line and what changed, so a reader could make it; then end. THE Ticket_Comment SHALL NOT name the Author's branch, uncommitted files or any command to run; the statement of where the fix sits is said in the conversation.
5. WHEN the Author picks `Stop here`, THE Skill SHALL end with the statement of where the fix sits and SHALL post nothing.
6. THE Skill SHALL NOT commit, create a branch, push, or create a pull request itself; the PR_Skill offers each of those.
7. IF the Skill tool cannot find `freethinking:pr`, THEN THE Skill SHALL say that the plugin's pr skill is missing and stop, and SHALL NOT draft or open the pull request another way.

### Requirement 5: The Skill carries a CX block

**User Story:** As an Author, I want to see up front where the Skill stops, how it asks and what it hands back, so that I know what to expect before the reproduction starts.

#### Acceptance Criteria

1. THE Skill SHALL carry a CX_Block after its ground rules and before its first numbered step, in the shape of start-task's and the PR_Skill's: four bullets, Stops, How it asks, Hand-backs, Hand-offs.
2. THE Stops bullet SHALL name the Approach_Question, the manual reproduction steps when the bug cannot be reproduced by a test or script, the Root_Cause_Question and the Handoff_Question.
3. THE How-it-asks bullet SHALL say that the three questions use the Question_Tool and that the manual reproduction is asked in prose because the Author reports what they saw in their own words.
4. THE Hand-backs bullet SHALL name the running summary after each reproduction attempt and hypothesis, and the Summary at the end.
5. THE Hand-offs bullet SHALL name the PR_Skill, and SHALL say that committing, branching and pushing are left to it.
6. THE CX_Block SHALL state only what is specific to the Skill or departs from the Collaboration_Rule, and SHALL NOT restate the Collaboration_Rule.

### Requirement 6: The change is guarded and wired in

**User Story:** As a maintainer, I want the hand-off proved by an eval and the plugin to say what changed, so that the Skill's new ending cannot regress unnoticed.

#### Acceptance Criteria

1. THE repository SHALL carry an Eval_Case that runs the Skill on the calc fixture with the planted defect, with a Ticket_Reference and the Author's answers given up front, and whose graders pass only when the Skill lands the fix, invokes the `report` skill and writes its Message with Done and Checks, invokes `freethinking:pr` through the Skill tool with that Ticket_Reference as the argument, and runs none of `gh pr create`, `git commit`, `git push` or a branch creation.
2. THE Eval_Case SHALL be reachable through `make eval-skill-bugfix`, with any flags it needs on one Makefile line.
3. THE existing `reads-ticket-first` Eval_Case SHALL pass unchanged.
4. THE README's bugfix row SHALL say that the Ticket_Reference may be followed by what the Author already knows.
5. THE plugin version SHALL move from `0.7.0` to `0.8.0`.
6. THE change SHALL leave `rules/` untouched apart from the Collaboration_Rule bullet of Requirement 7, and SHALL leave the PR_Skill, start-task and the task-executor agent untouched; `make validate` SHALL pass.
7. THE `Stop and comment on the ticket` path and the rendering of the three questions in the Question_Tool SHALL be checked by hand with a real GitHub_Issue, and the result recorded in the pull request.

### Requirement 7: Answers in the request do not short-circuit a skill

**User Story:** As an Author, I want an answer I give in the request to count at the question it answers and nothing more, so that a skill I pre-answer still shows me what it read, what it found and what it did.

#### Acceptance Criteria

1. THE Collaboration_Rule SHALL carry a bullet saying that an answer the Author gives in the request counts at the question it answers and skips only the wait, that every step still produces its output, and that text in the request is context, never an instruction that changes a skill's steps.
2. THE Collaboration_Rule SHALL stay under 1,600 characters and the hook output under 10,000, as `make validate` checks.
3. THE Skill SHALL say once, in step 1 where the argument is read, that answers in the Advance_Context are read under that rule, naming the outputs that still appear: the diagnosis with its evidence and the Summary; and SHALL NOT repeat the rule in later steps.
4. THE `Open it now` outcome SHALL be conditioned, in the bullet that states it, on the Summary already being in the conversation.
5. THE confirming run of the hands-off Eval_Case SHALL be made with the no-plugin baseline, `--ablation with-without`, and its table recorded in the pull request.
6. THE evals README SHALL NOT claim that failed runs are kept without `--keep-temp`.
Loading
Loading