Tech debt tickets
Harness agnostic skill pack for AI coding agents that audits codebases for technical debt across ten categories
npx -y skills add jjw013/tech-debt-skill --skill tech-debt-ticketsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Converts a findings.md (produced by tech-debt-audit) into one ticket markdown file per finding. Supports a user-supplied ticket-template.md override at the project root. After writing files, offers to push tickets to a ticketing API (Jira, GitHub, GitLab, Linear) — but never pushes without explicit consent.
SKILL.md
10.3 KB, as published. Nobody here has run it
Tech Debt Tickets
Overview
This skill reads a findings.md produced by tech-debt-audit and writes one ticket markdown file per finding into a tech-debt-tickets/ directory. Each ticket is paste-ready for Jira, GitHub Issues, GitLab, or Linear; the format is determined by either the user's custom template (ticket-template.md at the project root) or the pack's default.
After all tickets are written, the skill asks whether the user wants to push them to a ticketing API. It does NOT push automatically. Pushing involves a separate, explicit confirmation per target system.
When to Use
Trigger on any of:
- User chose "tickets" after the audit finished (path 1 from the audit skill summary).
- User directly invokes this skill pointing at an existing
findings.md. - User has picked this skill explicitly from the
using-tech-debt-skillsrouter.
Do NOT use this skill when:
findings.mddoes not exist or doesn't conform to the schema — runtech-debt-auditfirst.- The user wants fixes applied — use
tech-debt-fixinstead.
Persona Adopted
This skill adopts the technical-writer persona defined at agents/technical-writer/SKILL.md. Read that file before proceeding.
If the harness supports sub-agents: delegate the rendering + rephrasing work to a sub-agent prompted with the technical-writer persona. The parent composes the final summary and handles the API-push prompt.
If the harness does not support sub-agents: assume the technical-writer persona directly.
The persona's rules are binding:
- Never copy the finding description verbatim — translate for audience.
- Always produce checkable acceptance criteria.
- Redaction is permanent — never fill in what the audit redacted.
- Never push to external systems without explicit per-invocation consent.
Process
1. Confirm inputs with the user
Ask (or accept from the prior skill's handoff):
- Findings file path — default
<repo>/findings.md. Confirm. - Output directory — default
<repo>/tech-debt-tickets/. Confirm. If the directory already contains files, ask whether to overwrite or abort. - Template choice — see step 3.
2. Validate findings.md against schema
Read findings.md. Validate against templates/findings.schema.md §4 rules:
- Has top-level YAML frontmatter.
-
schema_versionis"1.0". -
summary.total_findingsequals the count of## TD-headings. - Every finding has a valid YAML block with required fields.
- Every finding has Description, Rationale, and Suggested fix sections.
If any check fails, abort with a clear message. Do not attempt to "fix" the findings file; the audit skill is authoritative for its own output.
3. Resolve the template
Look up the template in this order; first match wins:
- If the user passed an explicit template path, use it.
- If
<project_root>/ticket-template.mdexists, use it. Announce: "Using user template at./ticket-template.md." - Otherwise, use the pack's default
templates/ticket.template.md. Announce: "Using default template (pack). To customize, drop aticket-template.mdat your project root."
Read the template in full. Check it for {{placeholder}} names; warn the user if any placeholder isn't in the known list (see templates/ticket-template.example.md for the full list) — typos become empty strings in the output.
4. For each finding, render a ticket
Parse findings.md into individual findings. For each finding:
- Extract the structured YAML block.
- Extract the three markdown sections (Description, Rationale, Suggested fix) — the text content after each
**Section**header, up to the next##or**Section**boundary. - Compute derived placeholders:
{{location}}: iffilepresent withline→<file>:<line>. Iffileonly →<file>. Ifscope: repository→(repository-wide).{{tags}}: the YAML list rendered as a comma-separated string.{{title}}: everything in the heading afterTD-NNN:.
- Substitute every
{{placeholder}}in the template with the corresponding value. Unknown placeholders become empty strings — emit a warning for each so typos surface. - Apply the technical-writer persona's translation rules:
- If the
descriptionreads like a finding (evidence-focused, engineer-for-engineer), rewrite it to be stakeholder-aware — but preserve the engineering detail insuggested_fix. - If the template's acceptance criteria are template-generic (e.g., "suggested approach implemented"), supplement with finding-specific checkable items where possible. Only do this if the template includes an acceptance-criteria section.
- If the
- Write to
<output_dir>/<id>--<slug>.mdwhereslugis the title, lowercased, non-alphanumerics collapsed to-, trimmed to 50 chars.
5. Special handling for high-severity findings
If any finding has severity: critical:
- Prepend
[CRITICAL]to the ticket title. - If the finding is about a committed secret (
category: security+ tags includesecrets/committed-credentials), the ticket must include a rotation-and-history-purge section regardless of template — the template'ssuggested_fixplaceholder will likely already have this if the audit was done right, but double-check. If it's missing, flag to the user rather than silently proceed.
6. Produce the summary
Print a summary:
Tickets written: <count>
Output directory: <path>
Template used: <default | user-supplied at <path>>
By severity:
critical: <n> → [list of IDs]
high: <n>
medium: <n>
low: <n>
Warnings:
<any template placeholder warnings>
<any findings skipped for schema-validation reasons>
7. Offer API push — with explicit consent
Print:
Files are written. Do you want to push these tickets to a ticketing system?
1. No — I'll review locally and file manually (or never file).
2. Yes → which system? (Jira / GitHub Issues / GitLab / Linear / other)
3. Dry-run — show me the first API call you'd make for the first ticket, without sending.
If the user says yes:
- Ask for the specific system and project/repo target.
- Ask for credentials path or environment variable name. Do NOT accept credentials pasted into the chat.
- Verify a write-capable tool is available in the current harness (MCP server, API binding, gh CLI, etc.). If none is available, explain what's needed and stop.
- For each ticket, ask confirmation before the FIRST API call. After the first succeeds, ask whether to continue batch-posting the rest or prompt per ticket.
- Log each successful post and failure to
<output_dir>/push-log.md. - If any critical-severity ticket fails to post, stop the batch and surface it immediately.
Do NOT:
- Accept credentials in chat.
- Batch-push without the first-call confirmation.
- Retry failures silently.
Rationalizations
| Excuse | Rebuttal |
|---|---|
| "The user said 'generate tickets'; they obviously also want them pushed." | No. Writing files is one action. Calling an external API is another. The step 7 prompt is non-negotiable. |
| "This finding's description is already stakeholder-ready; I'll just copy it." | If it's truly ready, quick rewrite costs nothing; if it's not, skipping the rewrite is debt. Do the rewrite. |
| "Template doesn't have an acceptance-criteria section, so I'll make one up inside the suggested-approach." | If the user's template omits ACs, trust their choice — don't smuggle them in elsewhere. Ask if they want ACs elsewhere. |
"A placeholder {{foo}} is unknown; I'll treat it like a typo and delete it." | Don't delete. Substitute empty, warn. The user may have typed it intentionally as a literal; warnings let them see it. |
| "Two findings are really the same thing — I'll merge them into one ticket." | Don't. Findings have separate IDs for traceability. If you think they should be one ticket, say so in the summary and let the user decide; don't silently collapse. |
| "Critical finding about auth — let me file a Jira ticket right away without asking." | Especially never for critical findings. Auth issues often want a private issue (not the public repo's Issues tab), which is a human decision. |
| "The template's placeholder list is outdated for a new field I just added to findings.md." | The schema is authoritative. If you added a field to findings, update the template in the pack AND warn about gaps with user templates — don't bend the rendering in ways users can't see. |
Red Flags
Stop and reset if:
- You're about to push to an external system without an explicit per-push-batch confirmation.
- You're copying the finding's description verbatim into the ticket.
- The ticket title begins with "Fix" or "Improve" with no object.
- You're inventing acceptance criteria that aren't traceable to the finding.
- You notice a secret value somewhere in the rendered ticket — STOP, scrub the ticket, re-check every ticket in the batch.
- Tickets for
auto_fixable: truefindings get no distinction — the user may want the fix skill to handle those instead of filing tickets for them. - The output directory already has tickets and you're about to overwrite without asking.
Verification
The skill is done when ALL of these are true:
- All findings produced a ticket file OR were explicitly skipped with a reason in the summary.
- Each ticket filename follows
<id>--<slug>.md. - No secret values appear in any ticket file (grep pass before finishing).
- Summary has been shown to the user.
- The API-push prompt (step 7) was shown and the user responded.
- If push was declined, no external API calls were made.
- If push was accepted, per-system confirmation was captured AND the first-ticket confirmation happened before batching.
-
push-log.mdexists in the output directory if any push attempt happened.
If any item fails, fix it before reporting the skill complete.
Version History
- 1.0 (current) — Reads findings.md per schema v1.0. Supports user-supplied
ticket-template.mdoverride. Generic markdown output; API push is opt-in per invocation.