Skip to content
Closed
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
104 changes: 104 additions & 0 deletions .claude/references/compact-style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Compact style for issues and PR bodies

Shared reference. Pointed at by `.claude/skills/jira-issue/SKILL.md` and
`.claude/skills/pr-pitch/SKILL.md`. Adapted from the MIT-licensed
`i-have-adhd` skill (https://github.com/ayghri/i-have-adhd), which shapes chat
turns; these rules shape written artifacts instead.

## What changes when the reader is not in the conversation

A chat reader has just asked you something. A Jira reader is scanning a queue
of forty tickets, and a PR reader has eleven other reviews open. Both arrive
cold, months after the work, with none of your context and no way to ask a
follow-up. Four consequences:

1. The first line is the only line guaranteed to be read. It carries the
decision, not the setup.
2. Nothing can be held in the reader's head from a previous paragraph.
3. There is no "let me know if you need anything else". Whatever is unanswered
stays unanswered.
4. Length is not a cost the reader chooses to pay. Jira Data Center has no
collapsible sections, so every word in a description is on the screen.

## The rules

### 1. Lead with what the reader must decide

Not context, not history, not the investigation. For a triager: what breaks,
who it hits, how bad. For a reviewer: what the change does and what it risks.

Bad: `h3. The underlying problem` / "While investigating LT-22710 we noticed"
Good: "Deleting a feature-based natural class empties every rule that used it."

### 2. Number every multi-step sequence

Repro steps, verification steps, migration steps. One bounded action per step.
**No step contains "and then" twice.** If a step needs a sub-list, it is two
steps.

### 3. End with one named next action

Every description ends with a single `*Next:*` line naming who does what.
Tickets and PRs that end without one stall, because nobody is named.

Good: `*Next:* reporter to confirm the FLEx version (see comment).`
Good: `Next: approve, or tell me to split the installer change out.`

### 4. One artifact, one problem

A ticket describing four problems is four tickets, linked. A PR doing three
unrelated things is three PRs, stacked. Splitting is cheap at filing time and
expensive at review time.

### 5. State cause, not concern

No "seems to", no "there may be an issue with", no apology. Name the symptom
and, if known, the mechanism. If the mechanism is inferred rather than
observed, say "inferred" -- that is information, whereas hedging is noise.

### 6. Cost shape, not hours

Hours on a ticket read as a commitment nobody made. Size the work by what it
touches.

Bad: "This will take some work." / "About two days."
Good: "One branch in one file." / "Needs a liblcm release and a package bump."

### 7. Cap any list at five

Past five, split into "must" and "nice to have", or accept that the artifact
is really an epic. Five ranked beats ten unranked.

### 8. No preamble, no recap, no closer

Banned openers: "This issue describes", "This PR refactors", "While
investigating", "As a note", "I have been looking into". Banned closers:
"Please let me know", "Hope this helps", "Happy to provide more detail".

Start with the answer. Stop when the answer is done.

### 9. Say what is not known

An explicit `*Not known:*` line is worth more than a confident guess. It tells
the next reader where to dig and stops a fabrication becoming folklore.

### 10. Never assert what was not verified

Everything above the fold is either something a reporter said or something we
observed. Analysis, inference and reconstruction go in a comment or an
accordion, labelled as such. A screenshot from a headless test is not a
screenshot of the product; say which it is.

## Pre-send check

Delete before publishing:

1. The first sentence, if it announces what the artifact is about to do.
2. The last sentence, if it recaps or asks for further questions.
3. Any "by the way" sidebar. It is a separate ticket.
4. Hedging adverbs carrying no information. Keep a hedge that carries real
uncertainty; deleting that one manufactures confidence.
5. Any idiom. Replace with the literal action.

Then verify: **reading only the title and the last line, does the reader know
what is wrong and what happens next?** If yes, publish.
32 changes: 26 additions & 6 deletions .claude/skills/jira-bugfix/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,20 +128,37 @@ git branch --show-current

> The current branch is `<name>`. This doesn't match
> LT-XXXXX. Options:
> - Create a new branch `LT-XXXXX` from `main`
> - Create a new branch `LT-XXXXX-<short-slug>` from `main`
> - Continue on the current branch
> - Switch to an existing branch (specify name)

If creating a new branch:
```powershell
git fetch origin
git checkout -b LT-XXXXX origin/main
git checkout -b LT-XXXXX-<short-slug> origin/main
```

> **Important**: Do NOT create worktrees automatically. This
> repo uses worktrees but creating them involves workspace
> setup scripts. If a worktree is needed, tell the user to
> run the "Worktree: Create/Open from branch" VS Code task.
**Branch naming**: `LT-XXXXX-short-slug`, for example
`LT-22715-nc-delete-warning`. The number keeps this step's
"contains the LT number" check working and makes the branch
greppable; the slug is what makes a list of a dozen worktrees
readable. A bare `LT-XXXXX` tells you nothing at a glance.

> **Worktrees**: do not create one without asking, and do not
> refuse to create one either. The repo has
> `scripts/Worktree-CreateFromBranch.ps1` and a set of
> `Worktree:` VS Code tasks. Ask which the user wants; if the
> `jira-issue` skill already recorded a `workspace` preference
> in `.claude/.jira-issue-prefs.json`, follow it and say so.
> Note that the script places worktrees under
> `../<repo>.worktrees/` while existing worktrees on disk are
> under `.tmp/worktrees/` -- match what is already there.

> **Arriving from `jira-issue`**: if that skill just filed the
> ticket and the user chose "start now", Steps 0-2 are already
> done -- the issue is fetched, assigned, In Progress, and the
> branch and worktree exist and are named in a ticket comment.
> Begin at Step 3.

## Step 3: Reproduce the Bug (TDD)

Expand Down Expand Up @@ -410,6 +427,9 @@ All other steps proceed automatically.
## Integration with Other Skills

This skill composes with:
- `jira-issue` — files the ticket in the first place, and
hands off to this skill at Step 3 when the user chooses
"start now"
- `atlassian-readonly-skills` — reading JIRA issues
- `atlassian-skills` — writing to JIRA (assign, comment)
- `session-workflow` — session management and handoff
Expand Down
95 changes: 95 additions & 0 deletions .claude/skills/jira-issue/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
name: jira-issue
description: "Write and file an LT Jira issue -- bug, feature or task -- that a triager can act on from the first line. Use whenever asked to file, raise, report or create a Jira issue or LT ticket, to turn a user report or a finding into a ticket, or to restructure a ticket that buries its point. Interviews, hunts duplicates before drafting, gets a three-line lede approved, and moves the analysis to a comment."
argument-hint: "Optional: the raw report, a finding, or an existing LT-XXXXX to restructure"
user-invocable: true
---

# Jira Issue

Jira Data Center has no `{expand}`. Nothing folds away, so length in the
description is length on the screen for every reader, permanently. Keep the
description short and put the depth in the first comment.

Style contract: `.claude/references/compact-style.md`. Read it first.

## Phases

| # | Phase | Rule |
| --- | --- | --- |
| 0 | Type | Bug, feature or task. **More than one problem means more than one ticket** |
| 0b | Relevance | Not every ticket is about FLEx. Drop sections that do not apply; never fill them with "N/A" |
| 1 | Interview | Who / when / where / how / how bad. One at a time, **max 6**. "I don't know" is recorded, not guessed |
| 2 | Duplicates | Search **before** drafting. Show at most 5 candidates as a table with verdicts |
| 3 | Lede | Three labelled lines, **approved before anything else is written**. Max 3 revisions, then ask which line is wrong |
| 4 | Body | Track file, plus the budgets in `references/format.md` |
| 5 | Permission | "Do you have permission to post this?" Hard stop before anything leaves the machine |
| 6 | Publish | `references/publish.md` |
| 7 | Report | Key, URL, one `Next:` line. Nothing else |
| 8 | Start now? | Assign, transition, comment the branch and worktree, hand to `jira-bugfix` at its Step 3 |

## The two gates

Nothing is filed until the developer has answered both:

1. the duplicate table (Phase 2)
2. the three lede lines (Phase 3)

If either can be skipped quietly, the skill is decoration.

## Non-negotiable

- **Affects Version `FW 9.3` on every new ticket.** A filing convention, not a
claim about a build, so Phase 0b does not exempt tooling or docs tickets.
- **Nothing above the fold that the reporter did not say or you did not
verify.** Inference goes in the comment, labelled inferred.
- Budgets: summary 80 characters, lede 60 words, description 250 words ending
in one `*Next:*` line. Overflow goes to the comment.

## Lede labels

| Type | Labels |
| --- | --- |
| Bug | `*What happens:*` `*Who hits it:*` `*How bad:*` |
| Feature | `*What they want:*` `*Who wants it:*` `*Why it matters:*` |
| Task | `*What this is:*` `*Who it affects:*` `*Why it matters:*` |

## Traps that have already bitten

- **Read link types; never guess.** There is no `Relates` here. Falling back to
the first name in the list once produced four bogus `Cloners` links.
- **`resolution` cannot be set by an update** -- only by a transition.
- **The read-only skill's `jira_workflow.py` and `jira_projects.py` raise
`NameError: Optional` on import.** Use the `atlassian-skills` copies.
- **A private URL is broken evidence.** A Gmail or Drive link renders for
nobody. Attach the file.
- **Rewriting a ticket: post the original as a comment first**, then replace
the description.

## Preferences

`.claude/.jira-issue-prefs.json` (gitignored): `jiraUsername`, `workspace`
(`worktree` or `branch`), `branchStyle`. Ask the two questions once on first
run, then act on them silently -- but say which preference was used, so a
wrong one is visible.

## References

| File | For |
| --- | --- |
| `references/bug-track.md` | Interview, repro rules, sample-project permission |
| `references/duplicates.md` | The four search passes and the candidate table |
| `references/feature-track.md` | User story, workarounds, cost shape |
| `references/format.md` | Budgets, required fields, Jira markup |
| `references/publish.md` | The API calls and their gotchas |
| `references/examples.md` | LT-22715 before and after |

## Before finishing

- [ ] Both gates answered by the developer.
- [ ] Affects Version set.
- [ ] Description 250 words or fewer, ending in one `*Next:*` line.
- [ ] Every unknown is a `*Not known:*` line rather than a guess.
- [ ] No section emitted that does not apply.
- [ ] The title and the last line alone tell the reader what is wrong and what
happens next.
91 changes: 91 additions & 0 deletions .claude/skills/jira-issue/references/bug-track.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Bug track

What a FLEx bug report needs, from a real reporter's list: a brief description
of the problem, a sample project, and the steps to reproduce. Everything below
serves those three.

## The interview

Six questions maximum, one at a time. Stop early if the answers are already in
the raw report.

**Who** -- which user, what role (linguist, consultant, translation advisor),
and how many people are affected. "One user" and "every project on the team"
are different tickets.

**When** -- FLEx version *and* build number, the date it happened, whether it
is the first time or recurring, and whether it worked before. Version is
usually the decisive fact: a guard that shipped in 9.2.5 changes the whole
diagnosis depending on which side of it the reporter is on.

**Where** -- the tool and window, the exact menu path, and which project. Ask
whether the project can be shared before assuming it can.

**How** -- the exact actions. For text-entry bugs this is where the answer
hides: typed directly, pasted, dragged, typed with a vernacular keyboard or
IME, or arrived through Send/Receive. "Just typed it" and "pasted it" are
different bugs with different fixes.

**How bad** -- data loss, a workaround, or blocked work. Silent data loss
outranks a visible error. Say whether Undo recovers it.

## Steps to reproduce

Numbered, one bounded action per step, no step containing "and then" twice.
Each step is something the reader can do without knowing the codebase.

```
# Open Grammar > Natural Classes.
# Create a natural class from phonological features and name it.
# Insert that class into a phonological rule formula.
# Return to Natural Classes and delete the class.
# Open the rule again.
```

Rules:

- Start from a state the reader can reach: a new project, or a named sample.
- Never start at "with the corrupted project open".
- If a step needs specific data, say exactly what data.
- If reproduction is unreliable, say how many attempts out of how many. An
intermittent bug reported as reliable wastes the first hour of the fix.
- If nobody has reproduced it, say so in one line and put the inferred path in
the comment. A ticket that claims a reproduction it does not have is worse
than one that admits the gap.

## Expected and Actual

One line each, both observable. "It should work" is neither.

## Environment

FLEx version and build, Windows version, and anything unusual: Send/Receive in
use, a non-default keyboard or IME, a project migrated from an older version.

## Sample project

**Ask before attaching. Always.**

> Do you have permission to post this?

FLEx projects contain unpublished lexical data, vernacular text, and often
speaker names. The reporter may not own the data, and a Jira attachment is a
publication to everyone with project access.

If the answer is no, or unclear:

- Describe the shape of the data instead: how many entries, which writing
systems, which fields populated.
- Ask whether a minimal synthetic project reproduces it.
- Record in the ticket that a sample exists but was not attached, so nobody
re-asks.

Never attach a project the agent found on disk. Never attach a screenshot of a
live project without the same question.

## Priority

Do not set a priority number. Give the triager the facts that determine one:
whether data is lost, whether Undo recovers it, whether a workaround exists,
and how many users are affected. Those four lines are worth more than a guess
at a field value, and the lede already carries them.
36 changes: 36 additions & 0 deletions .claude/skills/jira-issue/references/duplicates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Duplicate and related search (Phase 2)

**Search before drafting, not before posting.** If the ticket exists, the work
is a comment on it, and finding that out after twenty minutes wastes the
twenty minutes.

```powershell
python -c @'
import sys; sys.path.insert(0, ".claude/skills/atlassian-skills/scripts")
from jira_search import jira_search
jql = "project = LT AND text ~ \"natural class\" AND status != Closed ORDER BY updated DESC"
print(jira_search(jql, fields="key,summary,status,updated", limit=10))
'@
```

Four passes, ten results each:

1. **Symptom words** -- the reporter's vocabulary, not ours.
2. **Area** -- `project = LT AND component = "..." AND status != Closed`.
3. **Link walk** -- for every ticket already cited, read its links, follow one hop.
4. **Mechanism** -- the type or method name, when the code location is known.

`text ~` searches summary, description, comments and environment, so a common
word like "triage" returns hundreds of irrelevant hits. Say so when reporting a
noisy pass rather than listing its results.

Present at most five candidates:

| Key | Summary | Why it might be the same | Verdict |
| --- | --- | --- | --- |

Verdicts are duplicate, related or unrelated. **Never file without showing this
table and getting a yes.** If a duplicate exists, offer to comment on it
instead; if the developer still wants a new ticket, file it and link it.

Link types are in `publish.md` -- read them, never guess.
Loading
Loading