Skip to content

LT-22723: Agent skills for filing Jira issues and writing PR bodies - #1100

Open
johnml1135 wants to merge 11 commits into
mainfrom
skill-compression
Open

LT-22723: Agent skills for filing Jira issues and writing PR bodies#1100
johnml1135 wants to merge 11 commits into
mainfrom
skill-compression

Conversation

@johnml1135

@johnml1135 johnml1135 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Filing an LT ticket with an agent now goes through a skill instead of improvisation, and the three skills that already existed lost two thirds of their bulk without losing a rule. /jira-issue interviews for who/when/where/how, searches Jira for duplicates before drafting, gets a three-line lede approved by the developer, caps the description at 250 words, and moves the analysis into the first comment.

LT-22723 was filed by the skill itself as the worked example, and the 28 tickets filed before it were rewritten the same way — median description 368 → 140 words, every original preserved verbatim as a comment.

The unknown you arrive with: why does a set of writing-style skills need 1,500 lines? It doesn't — the branch is net +584, because most of it is deletion. Jira Data Center has no {expand} macro, so nothing in a description can be folded away; every budget here serves that one constraint. There is no product code on this branch. Markdown, plus three lines of .gitignore.

Start here: .claude/skills/jira-issue/SKILL.md — 95 lines, the whole design. The six references/ files are detail it delegates to.

Where to look:

  • Two gates block publishing — the duplicate table and the lede approval. If either can be skipped quietly, the skill is decoration; both are written as "never file without".
  • compact-style.md is shared, not copied. pr-pitch reads the same file, so ticket style and PR style cannot drift apart.
  • The compression is deduplication, not shortening. jira-bugfix carried its own copy of the JIRA API calls, the custom_fields workarounds and the transition rules; it now points at jira-issue/references/publish.md and delegates commits, PRs and coverage to the skills that own them. Read the diff for deletions of duplicated procedure, not for changed rules — a rule that changed meaning is a bug.
  • Screenshots get a defined path — capture, curate, publish — with the rule that the test is the evidence and the screenshot is the courtesy. jira_add_attachment is proven against live Jira (LT-22723 carries attachment 154621).
  • Nine references pointed at nothing across the Avalonia migration and WinApp skills. Every target existed; the paths were written relative to the skill root while the citing file lives in references/.

Deliberately not here: the Atlassian transport skills, which are a separate PR — they are Python and vendored, and need a different kind of review.

Verification: gitlint clean on all 11 commits. 39/39 key rules survive compression (pr-pitch 15/15, pr-preflight 14/14, jira-bugfix 10/10), checked by grep rather than by eye. Every .md reference in .claude resolves from the directory it is written in — nine dangling before, zero after. Skill frontmatter parses. No trailing whitespace on any added line. No build.ps1 or test.ps1 run: nothing compiled changed. Build\Agent\check-and-fix-whitespace.ps1 errors on a clean branch because it reads a log Tee-Object never creates, so whitespace was verified by hand.

Next: review, or tell me to split the compression commits out of the new-skill commits.


Reading this a year from now — start here

This began as four separate PRs — the new skill, the evidence framework, the compression pass, and a reference-path fix — stacked in that order. They were consolidated because they are one story told in four parts, and because the alternative was asking a reviewer to hold four bases in their head. All eleven commits survive, so the original boundaries are still there in git log.

The design was written as a document in Docs/workflows/ and deliberately deleted before merge; it was working scaffolding, not something anyone needs in order to change this code correctly. What follows is that record.

What was measured, before and after
File Before After
jira-bugfix/SKILL.md 455 114
pr-pitch/SKILL.md 376 141
pr-preflight/SKILL.md 276 119
jira-issue/SKILL.md (new) 224 first draft 95

A SKILL.md is loaded whole every time its skill triggers, so every line it holds is context spent whether the reader needs it or not. Procedure only one phase needs now lives in a reference that loads when that phase is reached.

The 28 rewritten tickets: median 368 → 140 words, longest 1,255 → 271, two still over the 250 budget and justified (LT-22709's acceptance-test steps are the deliverable; LT-22715 carries a cause plus four children plus three options).

Decisions, and why

Search before drafting, not before posting. If the ticket already exists, the work is a comment on it. Discovering that after twenty minutes of drafting wastes the drafting.

The lede is approved before anything else is written. Every other budget is enforceable by counting; this one is only enforceable by stopping.

"I don't know" is recorded, not resolved. Missing facts become a *Not known:* line. Nothing enters a description that the reporter did not say or that we did not verify — inferred mechanism goes to the comment, labelled inferred. Fabricated detail in a ticket becomes folklore that outlives the ticket.

Affects Version FW 9.3 on every new ticket, as a filing convention rather than a claim about a build — so the relevance rule that drops FLEx-specific sections from a tooling ticket does not exempt it.

Branches are LT-XXXXX-short-slug. A real session was lost hunting for "the branch for LT-22715" among sixteen descriptively-named worktrees.

Preferences are a gitignored file, not agent memory — portable to any agent this repo supports, and per-clone, so one developer's worktree preference never becomes another's default.

Paths not taken

A second skill pair mirroring pr-preflight / pr-pitch. Two entrypoints for a workflow that is mostly linear. The PR pair earns its split because the write-up gets re-run on existing PRs; a Jira description is rewritten far less often.

Collapsible sections in the description. {expand} is a Confluence macro, not a Jira one — verified absent before the comment split was designed around it. Had it existed, the whole shape would be different.

A standalone compact-writing skill. A fourth skill in the chain, loadable when nobody asked for it. A reference file that two skills read costs less.

An orphan evidence branch hosting screenshots behind sha-pinned raw URLs. Cut before review: speculative, unbuilt, and it traded permanent repo weight for a problem that lasts one review. The honest third route is to hand the file to the author.

Compressing the Atlassian skills here. They are vendored and need their own review; they are the other PR.

The i-have-adhd adaptation

compact-style.md adapts the MIT-licensed i-have-adhd skill. That skill shapes chat turns; these rules shape written artifacts, which changes several:

  • "Lead with the next action" becomes "lead with what the reader must decide" — a triager's next action is a triage decision.
  • "Give specific time estimates" becomes cost shape, not hours: "needs a liblcm release and a package bump" rather than "about two days". Hours on a ticket read as a commitment nobody in the conversation is authorised to make.
  • "Restate state every turn" does not apply to filing; it applies to later comments.
  • "Make completed work visible" was dropped — PR territory, not ticket territory.

Two rules were added with no chat equivalent: say what is not known, and never assert what was not verified.

Evidence

The reference failure is real. LT-22715's first rendered line was h3. The underlying problem, its description ran past a thousand words, and it stated in its own text that it contained "four separate user-visible problems". It has since been split into LT-22724 through LT-22727, linked with Issue split, and references/examples.md carries the before-and-after.

The skill was used to file its own ticket. LT-22723 went through the type check, the relevance check (tooling, so no environment or repro sections), three JQL passes finding no duplicate, developer-approved lede, and publish. 232 words against a 250 budget; summary 60 characters against 80.

Jira API surfaces were read, not guessed. jira_create_issue sets {'accountId': ...} for assignee, which is Cloud-only — SIL Jira is Data Center and needs {'name': ...}. resolution cannot be set by an update at all, only by a transition. Both confirmed by hitting them.

The compression was verified by grep, not by reading. Distinctive rules from each original — the 200-400 word budget, the triage buckets, "Always trust the written code", the 65,536 cap, the four analysis passes, "Author does not understand", the TDD escape hatch, "never transition to Done" — were checked present in the compressed files. 39 of 39.

One rule was genuinely dropped, deliberately: jira-bugfix's IDE-Specific Notes, obsolete now that pr-preflight owns PR creation.


This change is Reviewable

johnml1135 and others added 7 commits August 21, 2026 08:58
Agent-authored LT tickets put good analysis in the wrong shape. The
reference failure opens with a heading, runs past a thousand words,
and states that it contains four separate user-visible problems, so a
triager scanning a queue cannot act on it.

Jira Data Center has no expand macro, so nothing in a description can
be folded away. The skill keeps the description short and moves the
depth into the first comment.

The skill interviews for who, when, where and how under a cap of six
questions, hunts duplicates before drafting rather than before
posting, and gets a three-line lede approved before anything else is
written. Unknowns are recorded rather than guessed, and nothing enters
a description that the reporter did not say or that we did not verify.

compact-style.md is a shared reference adapting the MIT-licensed
i-have-adhd skill from chat turns to written artifacts. pr-pitch now
points at it and gains a Start here line, numbered verification steps,
a closing Next line, an optional status line for long-lived PRs, and
the pre-send check.

jira-bugfix gains the LT-XXXXX-short-slug branch convention, a relaxed
worktree rule that asks rather than refuses, and a note that it is
entered at Step 3 when jira-issue hands off.

Evidence and screenshot handling is deliberately absent; it follows in
a stacked branch.

Co-Authored-By: Claude Opus 5 <[email protected]>
Not every LT ticket is about FLEx the product. One about developer
tooling, an agent skill, the build or documentation has no FLEx version,
no project file, no menu path and nothing to reproduce inside the
application.

Phase 0b now decides what kind of thing the ticket is about before the
interview starts, and maps that to the environment questions worth
asking. Asking which FLEx build was running, for a ticket about a
Markdown reference file, spends one of six questions and signals that
the ticket was generated rather than written.

The output rule is the same: never emit a section that does not apply. A
template dutifully filled with N/A costs the reader the same scan and
returns nothing, so the heading goes instead.

Co-Authored-By: Claude Opus 5 <[email protected]>
The design document was a working artifact, not something a future
maintainer needs in order to change this code correctly. Under the
pr-pitch triage it is RESEARCH: a one-time investigation whose
conclusions are now carried by the skill itself.

Its content survives in the pull request body, where the decisions, the
rejected alternatives and the reasoning stay recoverable without
shipping scaffolding into the repository.

Refs LT-22723

Co-Authored-By: Claude Opus 5 <[email protected]>
Every new LT ticket carries Affects Version FW 9.3, with no exception.
It is a filing convention that keeps the queue filterable rather than a
claim about which build the reporter was running, so the Phase 0b
relevance rule does not exempt a tooling, build or documentation ticket
from it. A specific point release the reporter names is added alongside
FW 9.3, never in place of it.

Neither jira_create_issue nor jira_update_issue exposes the versions
field, so it goes through custom_fields. The same applies to assignee,
which those helpers send as a Cloud-style accountId that SIL's Data
Center rejects; both fallbacks are now written down where the publish
step needs them.

Refs LT-22723

Co-Authored-By: Claude Opus 5 <[email protected]>
The example carried placeholder keys for the four symptom tickets that
splitting LT-22715 would create. Those tickets now exist, filed on
2026-08-21 as LT-22724 through LT-22727 and linked back with Issue
split, so the example names them.

A worked example that cites real tickets can be checked by a reader.
One that cites LT-AAAAA cannot, and quietly invites the reader to treat
the whole example as hypothetical.

Refs LT-22715, LT-22723

Co-Authored-By: Claude Opus 5 <[email protected]>
SKILL.md goes from 224 lines to 95. It is the only file loaded every
time the skill triggers, so every line it holds is context spent whether
or not the reader needs it. Mechanics move to references, which load
when the phase that needs them is reached.

Moved out: the four duplicate-search passes to a new duplicates.md, the
publish calls to publish.md, the relevance table to format.md. What
stays is the phase table, the two gates, the budgets and the traps.

Recorded from the retroactive rewrite of 28 tickets:

- Link types must be read, never guessed. There is no Relates in this
  Jira, and falling back to the first name in the list produced four
  bogus Cloners links between a cause ticket and its children.
- 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 on import; use the atlassian-skills copies.
- A private Gmail or Drive URL in a description is broken evidence.
- Rewriting a ticket posts the original as a comment first.

Task-type tickets gain their own lede labels. Two of the rewritten
tickets were Tasks and had to improvise them.

Refs LT-22723

Co-Authored-By: Claude Opus 5 <[email protected]>
A visible change should ship with a picture, and the repo already has
the hard half: headless Skia capture for Avalonia, MCP capture for
WinForms, and an Output/ManualEvidence naming convention. What was
missing is the last mile -- trimming, captioning, provenance labelling,
and any route at all from a PNG to a PR body or a ticket.

The rule evidence.md turns on is that the test is the evidence and the
screenshot is the courtesy. A control-level headless capture is not a
screenshot of the product, and every image now says which it is.

Publishing probes three routes and reports the one it used: native gh
attach once it ships, gh image where a session cookie is reachable, and
an orphan evidence branch with sha-pinned raw URLs otherwise. Only the
third works under an Actions token, which is why it stays.

jira_add_attachment uploads to Jira. It drives client.session directly
because AtlassianClient.post sends JSON only, while multipart needs the
XSRF header and no Content-Type. Its validation paths are exercised; the
upload path has not yet been run against a live issue.

A screenshot of a live project is a data disclosure exactly as a project
file is, so the permission gate covers both.

Co-Authored-By: Claude Opus 5 <[email protected]>
evidence.md sits in .claude/references/ and pointed at
fieldworks-avalonia-ui/references/visual-snapshot-testing.md as if it
were a sibling. The file is under .claude/skills/, so the pointer
resolved from nowhere. Made absolute from the repo root.

Co-Authored-By: Claude Opus 5 <[email protected]>
@johnml1135
johnml1135 marked this pull request as draft August 21, 2026 15:41
johnml1135 and others added 2 commits August 21, 2026 11:47
The third upload route proposed creating a never-merged orphan branch to
host screenshots and referencing them by sha-pinned raw URL. It was
speculative, nothing had been built, and it solved a problem lasting one
review by putting binaries in history permanently.

Route three is now the honest one: when no upload path is available, say
which was tried and hand the file to the author to drag in. The skill
also states plainly that images are not committed to the repository and
no side branch is created to host them.

Refs LT-22723
jira-bugfix, pr-preflight and pr-pitch drop from 1107 lines to 374,
about two thirds. A SKILL.md is loaded whole every time its skill
triggers, so every line it holds is context spent whether the reader
needs it or not. Procedure that only one phase needs now lives in a
reference that loads when that phase is reached.

Moved out: the review-summary template, the accordion catalogue, and
the publish-and-verify mechanics.

Deduplicated rather than shortened in place. jira-bugfix carried its own
copy of the JIRA API calls, the assignee and version workarounds, and
the transition rules; it now points at the jira-issue skill's
publish.md. It also delegates commit messages, PR creation and test
coverage to the skills that own them instead of restating them.

Nothing about the guidance changed. The pitch structure, the triage
buckets, the four analysis passes, the interview discipline and every
gate survive verbatim or tightened.

Refs LT-22723

Co-Authored-By: Claude Opus 5 <[email protected]>
Nine cross-references in the Avalonia migration and WinApp skills were
written relative to the skill root while the citing file lives inside
references/, so they resolved to references/references/<name>.md and
pointed at nothing. Every target exists; only the paths were wrong.

Seven become plain sibling names, which is what a file inside
references/ needs to reach the file next to it. Two genuinely cross
skill boundaries and become repo-root paths: winforms-avalonia-parity
cites parity-evidence in the migration skill, and architecture-patterns
cites style-system in the Avalonia UI skill.

Nothing else changed. No prose, no guidance, no file moved or renamed.

Verified by resolving every reference in every .claude markdown file
from the directory it is written in: nine dangling before, none after.

Co-Authored-By: Claude Opus 5 <[email protected]>
@johnml1135 johnml1135 changed the title LT-22723: Compress jira-bugfix, pr-preflight and pr-pitch LT-22723: Agent skills for filing Jira issues and writing PR bodies Aug 21, 2026
@johnml1135
johnml1135 changed the base branch from jira-issue-evidence to main August 21, 2026 17:13
@johnml1135
johnml1135 marked this pull request as ready for review August 21, 2026 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant