Problem
The update-jira-ticket skill fires for Claude and marches it down a full HTML-sanitization path — author HTML against an allowlist, run the deterministic pre-flight checker (update-jira-ticket.mjs) — even though Claude's available tool is editJiraIssue, which takes Markdown directly and has no HTML surface at all. The observed cost is repeated wasted work: content gets sanitized as the skill directs, only for Markdown (not HTML) to be what the tool actually wanted.
The skill's core machinery — the element allowlist, the composition rules, the pre-flight checker — exists solely to neutralize INVALID_INPUT errors from Jira's HTML→ADF conversion. When the available tool accepts contentFormat: "markdown" | "adf", that converter is never invoked, so the entire HTML path is a category error: the failure classes the checker guards against cannot arise.
Context
Two distinct Jira-update tool shapes exist in the wild:
- HTML-based:
update_jira_issue / create_jira_issue with description_html / comment_html. The conversion to ADF is where the known INVALID_INPUT triggers (code-mark nesting, multi-line <pre>, named entities, Confluence constructs) arise.
- Markdown/ADF-based:
editJiraIssue (Atlassian Rovo) with fields.description + contentFormat: "markdown" | "adf". Markdown is the simplified, safe path; ADF is full-fidelity JSON but verbose and harder to author.
The skill is a two-artifact bundle: hand-authored prose (SKILL.md) plus a generated helper (update-jira-ticket.mjs, an esbuild bundle of src/update-jira-ticket/). The checker and its src/ tree govern only the HTML path, so this change is confined to SKILL.md — no checker or source changes. The skill was originally written around the single HTML surface and encoded that one environment's constraint as the path; the fix is a decision gate that routes to the correct branch.
Proposed solution
Restructure SKILL.md around a decision gate, retaining the existing HTML content in substance:
- Open with a tool-identification gate that names both shapes and states how to determine which is available (inspect the available MCP tools; prefer the
contentFormat tool when both are present).
- Add a short Markdown branch: author Markdown, pass via
contentFormat: "markdown", prefer a local Markdown artefact when one exists. State a clear preference for Markdown over ADF, reserving ADF for fidelity Markdown cannot express. Explicitly state that the HTML allowlist, composition rules, and pre-flight checker do not apply, and that the checker must not be run.
- Retain the existing HTML path as the other branch, reframed from "the one correct path" to the correct path for the HTML-surface tool. Its sub-sections nest under the branch (demoted a heading level) so the gated guidance no longer reads as universal.
- Correct the frontmatter
description so it names both tool shapes and scopes the pre-flight checker to the HTML branch, instead of implying the HTML surface is universal.
Acceptance criteria
Must have
Problem
The
update-jira-ticketskill fires for Claude and marches it down a full HTML-sanitization path — author HTML against an allowlist, run the deterministic pre-flight checker (update-jira-ticket.mjs) — even though Claude's available tool iseditJiraIssue, which takes Markdown directly and has no HTML surface at all. The observed cost is repeated wasted work: content gets sanitized as the skill directs, only for Markdown (not HTML) to be what the tool actually wanted.The skill's core machinery — the element allowlist, the composition rules, the pre-flight checker — exists solely to neutralize
INVALID_INPUTerrors from Jira's HTML→ADF conversion. When the available tool acceptscontentFormat: "markdown" | "adf", that converter is never invoked, so the entire HTML path is a category error: the failure classes the checker guards against cannot arise.Context
Two distinct Jira-update tool shapes exist in the wild:
update_jira_issue/create_jira_issuewithdescription_html/comment_html. The conversion to ADF is where the knownINVALID_INPUTtriggers (code-mark nesting, multi-line<pre>, named entities, Confluence constructs) arise.editJiraIssue(Atlassian Rovo) withfields.description+contentFormat: "markdown" | "adf". Markdown is the simplified, safe path; ADF is full-fidelity JSON but verbose and harder to author.The skill is a two-artifact bundle: hand-authored prose (
SKILL.md) plus a generated helper (update-jira-ticket.mjs, an esbuild bundle ofsrc/update-jira-ticket/). The checker and itssrc/tree govern only the HTML path, so this change is confined toSKILL.md— no checker or source changes. The skill was originally written around the single HTML surface and encoded that one environment's constraint as the path; the fix is a decision gate that routes to the correct branch.Proposed solution
Restructure
SKILL.mdaround a decision gate, retaining the existing HTML content in substance:contentFormattool when both are present).contentFormat: "markdown", prefer a local Markdown artefact when one exists. State a clear preference for Markdown over ADF, reserving ADF for fidelity Markdown cannot express. Explicitly state that the HTML allowlist, composition rules, and pre-flight checker do not apply, and that the checker must not be run.descriptionso it names both tool shapes and scopes the pre-flight checker to the HTML branch, instead of implying the HTML surface is universal.Acceptance criteria
Must have
contentFormat-based tool (e.g.editJiraIssue) is available, the skill instructs authoring in Markdown (preferred) or ADF, and explicitly states the HTML allowlist, composition rules, and pre-flight checker do not apply.contentFormatpath.description_htmltool, reframed as one branch of the gate.descriptionnames both tool shapes and scopes the pre-flight checker to the HTML branch.