From wiki-page-author
Use when the user wants to create, edit, fix, or break down tickets — including epics, features, spikes, bugs, chores, documentation, and ODDs (Open Design Decisions raised from the wiki).
How this skill is triggered — by the user, by Claude, or both
Slash command
/wiki-page-author:ticket-authorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill writes ticket proposal files to `proposed-tickets/`. Each file becomes a ticket (or epic) when the PR/MR is merged.
This skill writes ticket proposal files to proposed-tickets/. Each file becomes a ticket (or epic) when the PR/MR is merged.
Each ticket is read by a human reviewer and executed by an LLM agent that has the wiki and the codebase in context.
Every ticket is anchored where its why lives. Identify the anchor before writing — it decides what the body carries (see Body Rules).
The test: does the ticket need motivational rationale — business case, user impact, domain or strategic justification — to make sense?
Mechanical detail doesn't flip the anchor: a wiki-anchored ticket may carry it too, with the why still on the wiki. The why is what classifies — if a reader would need business case, user impact, or domain rationale to know why the work matters, it is wiki-anchored.
If unsure, ask the user.
Understand the request. Determine how many tickets are needed, then choose each ticket's type by taking the first rule that matches, top to bottom. Epic is handled when planning the breakdown in step 4.
Identify each ticket's anchor. For each ticket, decide whether it is wiki-anchored or codebase-anchored (see Ticket Anchoring). If unsure, ask the user before drafting.
Gather context from the project. Before writing tickets, read what's already in the repo to understand the domain — wiki pages, existing code, documentation, whatever is there. Use the terminology that already exists (page names, class names, module names). Do not invent new terminology for concepts that already have a name. When a wiki page informing a ticket carries a top-of-page > [!CAUTION] block, warn the user that the page is under investigation.
Plan the ticket set. Decide the breakdown:
epic: auto.epic: auto; an epic file never carries its own epic: field — an epic is not a child of another epic.Write all ticket files. Batch-write every .md file to proposed-tickets/. For each ticket, read the appropriate template from assets/ and use it as the structural basis:
Review and fix. Exclude ODD tickets (labels include type::ODD) from what the reviewer is given. Whether the reviewer runs depends on the request from step 1:
ticket-reviewer subagent to review every non-ODD file in proposed-tickets/.ticket-reviewer. If they decline, stop here.Fix what the reviewer reports, then re-review — up to three times. If files still report NEEDS WORK after the third, surface those to the user instead of looping further.
| Field | Required | Type | Notes |
|---|---|---|---|
title | Yes | string | Non-empty |
type | No | string | Only accepted value is epic |
labels | No | list | |
weight | No | integer | |
epic | No | integer or "auto" | IID of an existing epic, or "auto" to link to the epic created in the same branch |
Lowercase kebab-case named by the ticket's title.
Write actionable descriptions. A reader recovers the concrete problem and the done-state from the ticket's Scope and Acceptance Criteria alone, without opening the linked spec. This is a self-sufficiency floor, not a licence to duplicate: the linked doc still owns the field tables, rationale, and full spec (see Don't duplicate spec detail from the source doc and What the ticket carries depends on its anchor).
Bad — thin pointer; the problem and done-state live only in the spec:
Campaign expiry is wrong. See Campaign Lifecycle.
Good — problem and done-state recoverable from the ticket; the spec carries the detail:
Campaigns stay active past their end date because expiry is evaluated only on write. Scope: evaluate expiry at read time so a campaign past its end date reports inactive. Field semantics and edge cases: Campaign Lifecycle.
Do not infer technical decisions. Do not prescribe specific class names, design patterns, library choices, file paths, or route paths unless they come from the wiki or existing code, or the user asks for them. An identifier carried by an anchor (a linked wiki page, a referenced code file) or named in the user's request is not inferred — stating it is required, not a violation. What this rule forbids is a prescribed name or path with no anchor and no user request behind it.
Use the language of existing documentation. When a concept already has a name in the wiki or existing code, use that name. Do not introduce new terminology for the same thing.
Reference files, not line numbers. No #L104, no #L3-6 — line anchors rot when files change. Identify the location by content (symbol name, string, or section heading); link to the file, not a line range.
Implementation Approach orients, not prescribes. Reference patterns and existing implementations by concrete anchors (files, classes, wiki pages) — not step-by-step imperatives, numbered or bulleted. Bullets are fine for structural facts about layout or shape. Every Scope item must be reachable from the Approach.
Bad — enumerates as numbered imperative steps:
- Add
User- Add
phonefield toUser- Update
UserController.createUserto accept the new fields- Add migration script for existing users
Good — prose orientation with anchors:
Add
phonefields toUser. ExtendUserController.createUserto handle the new fields. A new migration script populatesphonefor existing users.
Good — bullets carrying structural facts, not steps:
Project resources follow a one-thing-per-file convention:
- one file per user under
src/main/resources/users/, named<username>.yml- one config per environment under
src/main/resources/env/- one migration per release under
src/main/resources/db/migrations/
Name what to take and what to change, not a single verb. When a ticket instructs the agent to reproduce structure from a referenced class, file, or module, single verbs (mirror, match, follow, reference) leave the executing agent guessing where on the spectrum to land. Spell out the structure being borrowed and the parts being changed. Class names follow the class's role: infrastructure names (base classes, configs, converters) come with the borrowed structure; domain names (entities, repositories, services) are part of what to change.
Bad — gestures at the relationship with a single verb:
Mirror inventory-service's store setup, adapting packages.
Good — names what to take and what to change:
Take the class structure and converter logic from inventory-service's
BaseRecordandStoreConfig. Change package names fromcom.example.inventorytocom.example.orders. Bring along anything these classes reference.
Bad — no distinction between infrastructure and domain classes:
Take the entity and repository structure from
Analyst,AnalystRepository,BaseEntity.
Good — infrastructure name stays; domain classes are renamed:
Take the entity and repository shape from
Analyst,AnalystRepository, andBaseEntity: a MongoDB-mapped entity extendingBaseEntity, paired with a Spring DataMongoRepository. ChangeAnalyst/AnalystRepositorytoProject/ProjectRepository.BaseEntitykeeps its name.
What the ticket carries depends on its anchor.
Wiki-anchored tickets link to the wiki page that holds the what and why. The ticket body carries scope, anchors, and AC — plus any causal-mechanical detail (sequencing, invariants) the executing agent needs. What stays off the ticket is motivational rationale (business case, user impact, strategic priority) and domain background; those belong on the wiki page. If justification feels necessary in the ticket, the wiki page is the place for it.
Codebase-anchored tickets are the source of truth for themselves. The ticket body carries the mechanical detail the executing agent needs — sequencing constraints, invariants, what depends on what for the mechanism to work. This is causal-mechanical detail, not motivational rationale. If the ticket needs motivational rationale to make sense, the anchor was misidentified — go back to step 2.
Bad — wiki-anchored ticket carrying motivational why:
We need
phoneonUserbecause the support team has been asking for a way to contact users outside the app, and customer success has flagged this as a top-three churn driver this quarter.
Good — wiki-anchored ticket links the wiki:
Rationale and field semantics: Contact Channels for Users.
Don't duplicate spec detail from the source doc. If a referenced doc (wiki page for wiki-anchored tickets, another ticket or a code file for codebase-anchored ones) owns the full spec, list scope only (names, structural decisions, enum/constant values) and link it as source of truth. This holds inside Acceptance Criteria too — an AC resolves spec-owned values through the authoritative link, not by reproducing the field or validation matrix inline (see Acceptance Criteria assert outcomes, not restatement).
Bad: duplicates the schema doc:
Fields:
username(String),firstName(String)...
Good: scope only, defer to source:
Fields per
User-Storage.md.
Acceptance Criteria assert outcomes, not restatement. Each criterion is a falsifiable check a reviewer would perform — not an imperative, not a project-wide baseline (build/lint/test belong in the project's CLAUDE.md), not subjective. State assertions that correspond to a scope goal are fine if falsifiable. A reviewer must be able to tell pass from fail without guessing. Defer spec-owned values to their authoritative link (see Don't duplicate spec detail from the source doc); quote inline only a constant the check's pass/fail genuinely turns on.
Bad — restates the task, baselines, and subjective judgements:
- Create the User entity
- Code compiles without errors
- Code is idiomatic
Good — each line is a check a reviewer can run:
- A
Userwith populatedauthoritiesround-trips through Mongo with all fields preservedZonedDateTimefields survive a round-trip with timezone intact- Mongock migration creates a unique index on
usernameand non-unique indexes onauthoritiesandorganisation- No classes exist outside the File Structure diagram
Bad — unresolved reference:
- Mongock migration creates the required indexes
Good — names the constants the check turns on, defers the rest:
- Mongock migration creates indexes on
state,_class,createdAt, andcreatedBy- Seed documents contain fields matching the Project Schema
Testing names behaviours, not cases. Feature and bug tickets require automated tests. Name the behaviours that must have coverage; the implementing agent derives cases and edges from the code change, wiki, and codebase already in context. A behaviour is a rule the system honours ("a campaign past its end date reports inactive"); a case is one input that exercises it ("a campaign one day past its end date"). Name the behaviour, not the case. Do not enumerate cases, edges, frameworks, or file paths. For bugs, a regression test covering the reproduction is mandatory — name the broken behaviour the reproduction exercises; this is the one entry that pins a specific scenario, and it still names no framework or file path.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Applies a firm's KYC/AML rules grid to parsed onboarding records: assigns risk rating, checks required documents, outputs rule outcomes with citations, and routes for escalation.
Generates daily or weekly digests of activity from connected sources (chat, email, docs, tasks, CRM), highlighting action items, decisions, mentions, and project updates.
npx claudepluginhub sheriff-stuff/scribe-skills --plugin ticket-author