Agent instructions, skills, SSH host aliases and expansion triggers are worth having identical on every machine one person owns, and belong in none of the shared configuration. They live in user/ now, with a manifest saying where each piece goes and a link-user stage that puts it there. That stage does nothing unless the machine said yes. Somebody who clones Panama to try the desktop keeps their own ~/.claude/CLAUDE.md exactly where it was; the question names the destinations and defaults to no. Anything displaced goes to config/old rather than being deleted. ~/.claude/CLAUDE.md and ~/.codex/AGENTS.md were byte-identical copies of one file, which is the drift this exists to prevent. Also adds the vitals toggles for the battery and Claude usage readouts, which had preferences and no way to reach them.
803 lines
52 KiB
Markdown
803 lines
52 KiB
Markdown
---
|
|
name: ticket
|
|
description: End-to-end Jira ticket workflow — fetch a ticket into .claude/docs/epics/, write a plan, implement it with clean commits, run pre-mr-review to convergence, and write the MR doc. Use when the user gives you a Jira ticket key (e.g. KACP-11111) to work, or asks to plan/implement/wrap up a ticket.
|
|
disable-model-invocation: true
|
|
---
|
|
|
|
# Ticket Workflow
|
|
|
|
Turns a Jira ticket key into: a saved ticket record, a reviewed plan, implemented and
|
|
committed code, a converged `pre-mr-review` audit, and an MR doc ready to paste into
|
|
GitLab/GitHub. This skill is user-level (`~/.agents/skills/ticket/`) and works the same
|
|
way in any repo that has a `.claude/docs/` directory and a `pre-mr-review` skill.
|
|
|
|
Invoked as `/ticket KACP-11111`. The ticket key is passed as the skill's arguments. Called
|
|
again later with the same key, it resumes wherever it left off — see **Phase 0**.
|
|
|
|
Not to be confused with `/review-ticket`. That skill writes the *developer review* on a
|
|
Jira story, the estimate, risk level, and testing tables, as part of authoring a ticket
|
|
before anyone builds it. It has nothing to do with reviewing code. The code review in
|
|
this skill is Phase 2 step 5 and is performed by a dispatched agent, not by a skill.
|
|
|
|
## Directory layout this skill maintains
|
|
|
|
```
|
|
.claude/docs/epics/
|
|
<EPIC-KEY>/
|
|
epic.md # brief epic context, written once, best-effort
|
|
<TICKET-KEY>/
|
|
resources/
|
|
ticket.md # title, description, dev review instructions
|
|
<attachments...> # images, videos, other files as downloaded
|
|
<video>.transcript.txt # only for videos that got transcribed
|
|
<video>.transcript.srt
|
|
plan.md
|
|
deliverables/ # only for tickets whose output is documents, not code
|
|
<deliverable-slug>/
|
|
<deliverable-slug>.md
|
|
<deliverable-slug>.typ
|
|
<deliverable-slug>.pdf
|
|
proof/ # captured working feature proof, uploaded to Jira by the user
|
|
mr.md # the MR description only, written once pre-mr-review says Ready to Open MR
|
|
tickets/
|
|
<TICKET-KEY>/ # same shape, for tickets with no epic
|
|
resources/...
|
|
plan.md
|
|
deliverables/...
|
|
mr.md
|
|
```
|
|
|
|
## Scripts this skill uses
|
|
|
|
- `~/.agents/skills/ticket/scripts/jira-fetch-issue.sh <KEY> <OUT.json>` — fetches one
|
|
issue (`fields=*all`, rendered HTML description, field-name map) via `JIRA_BASE_URL` /
|
|
`JIRA_CREDENTIALS`.
|
|
- `~/.agents/skills/ticket/scripts/jira-download-attachments.sh <issue.json> <resources-dir>`
|
|
— downloads every attachment on that issue into the given directory, printing
|
|
`filename<TAB>mimeType<TAB>bytes` per file.
|
|
- `~/.agents/skills/ticket/scripts/transcribe.sh <media-file> <output-dir> [model]` —
|
|
transcribes via whisper.cpp in podman, auto-detecting NVIDIA/AMD/Vulkan acceleration
|
|
and falling back to CPU on failure. Requires `podman`; uses host `ffmpeg` if present.
|
|
|
|
Both Jira scripts require `JIRA_CREDENTIALS` (`[email protected]:api-token`, Basic auth)
|
|
to already be exported in the environment. `JIRA_BASE_URL` defaults to
|
|
`https://ksense-tech.atlassian.net` if unset.
|
|
|
|
Each Bash tool call runs in a fresh shell that does not inherit state from previous
|
|
calls, so a plain `export` the user ran earlier in their own terminal will not show up
|
|
here. Before calling either Jira script, always run `source ~/.bashrc 2>/dev/null` in
|
|
the same Bash call (chained with `&&` or on the line before), then check the var is
|
|
actually set. Only if it's still missing after that should you stop and tell the user
|
|
to export it (or point you at wherever it's actually set, e.g. a dotfiles repo) rather
|
|
than guessing or prompting for a token inline.
|
|
|
|
### AMD Vulkan acceleration
|
|
|
|
`transcribe.sh` uses the whisper.cpp Vulkan image when `/dev/dri` and `vainfo` are
|
|
available. On a host with more than one AMD or Intel GPU, select the intended render
|
|
node explicitly instead of exposing every DRI device and trusting enumeration order:
|
|
|
|
1. Identify the GPU PCI address with `lspci | rg -i 'vga|display|3d'`.
|
|
2. Map it to a render node with `ls -l /dev/dri/by-path` and resolve the matching
|
|
`pci-<address>-render` symlink with `readlink -f`.
|
|
3. Run the helper with the resolved node, for example:
|
|
`WHISPER_VULKAN_DEVICE=/dev/dri/renderD128 ~/.agents/skills/ticket/scripts/transcribe.sh <media-file> <output-dir> [model]`.
|
|
4. Verify the runtime log. `Selected acceleration: vulkan` only confirms the intended
|
|
path. Require `ggml_vulkan: Found ...`, the exact requested GPU name, and
|
|
`use gpu = 1` before claiming hardware acceleration worked.
|
|
|
|
The current whisper.cpp images declare `bash -c` as their container entrypoint. The
|
|
helper overrides it with `/app/build/bin/whisper-cli`. An older helper without this
|
|
override can fail before Whisper starts with `-f: line 1: /models/...: Permission
|
|
denied` and then fall back to CPU.
|
|
|
|
The accelerated paths remain best-effort on other hosts. The helper falls back to the
|
|
CPU image after an accelerated runtime failure. If the user explicitly requested GPU
|
|
acceleration, CPU fallback does not satisfy the request. Diagnose the accelerated path,
|
|
rerun it, and verify the device log instead of accepting the fallback transcript.
|
|
|
|
## House style (applies to everything this skill writes or commits)
|
|
|
|
- No code comments unless the user explicitly asks for one in that spot.
|
|
- No em dashes, en dashes, semicolons, or arrow glyphs in commit messages, `ticket.md`,
|
|
`plan.md`, or `mr.md`. Plain punctuation only.
|
|
- Commits are `git commit -m "<short imperative message>"` only — no body, no
|
|
co-author line, no `Claude` / `Codex` / `AI` trailer of any kind.
|
|
- Never `git push`. Never open an MR/PR. This skill prepares everything needed to open
|
|
one by hand; opening it is the user's call.
|
|
- Don't check a checklist box (in `mr.md` or anywhere else) unless you actually verified
|
|
it. Leave it unchecked and say why in the notes rather than guessing.
|
|
|
|
## Verification tools available
|
|
|
|
The goal isn't "a plausible-sounding plan" or "code that compiles" — it's a plan and
|
|
an implementation that are actually correct, checked against the real system rather
|
|
than assumed from the ticket text. Use whichever of these actually verify the thing
|
|
in question, before writing `plan.md` (Phase 1) and again whenever Phase 2's
|
|
implementation makes a claim that's checkable:
|
|
|
|
- **The codebase itself.** Don't take the ticket's description of "how things work
|
|
today" at face value. Read the actual models, routes, and components involved and
|
|
reconcile any mismatch. If the ticket says a field works one way and the code says
|
|
otherwise, say so in the plan rather than silently trusting either source.
|
|
- **Jira, beyond the single ticket.** Many tickets assume Jira's own data model (custom
|
|
fields, issue types, workflow states) or context that lives on linked issues,
|
|
comments, or the epic rather than on the ticket itself. Search related issues
|
|
(`searchJiraIssuesUsingJql`, issue links, other children of the same epic) and check
|
|
the real field list (the `names` map `jira-fetch-issue.sh` already pulls, or
|
|
`/rest/api/3/field` for the full set) instead of guessing at a custom field's shape.
|
|
- **Staging**, via Infisical (see the `infisical-api` / `infisical-user-setup-guide`
|
|
skills for pulling secrets). Staging is fair game to probe directly whenever it
|
|
would settle something real, no need to ask first, that's what it's for.
|
|
- **Prod and CI env vars**, at `.claude/docs/env/prod/.env` and
|
|
`.claude/docs/env/ci/.env`. Ask the user for permission before every use, even if
|
|
they granted it last time, say what you want to verify and why. Once granted: use
|
|
the values (e.g. source them for a one-off read-only command) without printing the
|
|
raw file contents or individual secret values into your output. Read-only, always —
|
|
never run anything that writes, mutates, or deletes against prod or CI. If what you
|
|
actually need is a prod database query, that's exactly the kind of thing to ask
|
|
about explicitly rather than assume the file's DB credential is fair game by default.
|
|
|
|
If something would need access you don't have (a different repo, a system you can't
|
|
reach), say so explicitly in `plan.md`'s Open questions instead of silently skipping
|
|
the check.
|
|
|
|
**How to write what you found, in a deliverable.** State it as a plain confirmed
|
|
fact: "Confirmed in prod: 67 of 70 companies have `hourlyRate` set." Never describe
|
|
the verification method itself, no "a read-only pull," "a read-only pass," "read-only
|
|
query," or similar plumbing language. The reader doesn't know or care that you ran a
|
|
SQL query, they care what's true. This applies to prod, staging, Jira, and the
|
|
codebase equally.
|
|
|
|
## Deliverable documents (spikes, proposals, anything whose output is a document)
|
|
|
|
Some tickets (spikes, research, migration proposals, the KACP-22764 kind of ticket)
|
|
don't produce code, they produce documents for a PM or another engineer to read. When
|
|
a `plan.md` Step produces a document rather than a code change, it becomes its own
|
|
subfolder under `<target-dir>/deliverables/<deliverable-slug>/` with three files:
|
|
|
|
- `<slug>.md` — the source of truth for content. Write this first, get the content
|
|
right before worrying about layout.
|
|
- `<slug>.typ` — a Typst version of the same content, laid out for an actual printed
|
|
or PDF-read document, not a mechanical markdown-to-typst conversion. Real headings,
|
|
`table()` for tabular data, and a diagram (via the `cetz` package,
|
|
`#import "@preview/cetz:VERSION"`) wherever a diagram would genuinely communicate
|
|
faster than prose — entity relationships, hierarchies, flows. Don't force a diagram
|
|
in where a bullet list would do. Style is engineering-oriented and readable: nothing
|
|
colorful or flashy, this goes to a technical PM and other engineers.
|
|
- `<slug>.pdf` — compiled from the `.typ` file.
|
|
|
|
**Write for the actual audience, not for yourself.** The reader is a PM or another
|
|
engineer who has never seen `.claude/docs/`, doesn't know what `plan.md` or
|
|
`ticket.md` are, and doesn't have this repo (or any other local repo) checked out.
|
|
Never reference `.claude/docs/` or any local file path in a deliverable's content.
|
|
Never say "see plan.md" or "see ticket.md", those are personal working files, not
|
|
things a reader can open. Refer to "this ticket" or a plain Jira link, not a local
|
|
path. If a fact came from another repo on this machine, state the fact, don't cite
|
|
the local checkout path it came from.
|
|
|
|
**Structure mirrors the ticket, not a narrative.** The PM reads a deliverable to
|
|
verify that everything they asked for is in it, and to come back later and re-find
|
|
one specific answer. Build the document from the ticket's own structure:
|
|
|
|
- If the ticket asks direct questions (a spike's "Questions to Answer" table), the
|
|
first section is `Questions and answers`: every ticket question in ticket order,
|
|
each with its priority, a direct two or three sentence answer, and a pointer to
|
|
the section holding the detail. This page is how the reader checks all
|
|
acceptance criteria without reading the rest.
|
|
- One section per named deliverable or requested topic, titled with the ticket's
|
|
own words. If the ticket says "status-weighting approach" there is a section
|
|
called "Status weighting"; if it asks how the datamodel changes, the section is
|
|
"Datamodel". Plain flat headings, one level below the title, in roughly the
|
|
ticket's order of importance (schema and calculations early).
|
|
- Each section is the artifact, not prose about it: schema changes as real schema
|
|
code in the repo's conventions (e.g. Prisma model blocks), math as formula code
|
|
blocks, mappings as tables, UI as the real mockup screenshots. Current-state
|
|
context earns a sentence or two inside the section that needs it; the section
|
|
states the decision, not the investigation that produced it.
|
|
- Sections are short. Cover every question and requirement, spend few words each.
|
|
Depth lives in the code blocks and tables, not in longer paragraphs.
|
|
- The voice is a dry engineering spec. Plain declarative sentences, no scene
|
|
setting, no flourishes ("the heart of the model", "the honest story"). A
|
|
correct document that reads glossy costs the reader's trust in it.
|
|
|
|
**State final decisions, don't narrate the journey.** A deliverable answers "what
|
|
goes where and why," not "here's what we used to think, here's what turned out to be
|
|
wrong, here's what's resolved now versus still open." No "Corrections made" section
|
|
listing earlier mistakes, no "Resolved" / "Still open" split, no "first draft said
|
|
X, that was wrong" asides. Figure out the right answer (including asking the user
|
|
directly, mid-task, for anything you can't determine yourself) before or while
|
|
writing the deliverable, then write the resolved shape as plain fact, the same way
|
|
the very first version of a proposal document should read: a clean "stays here,
|
|
moves there, and why" description, nothing else. If something genuinely can't be
|
|
resolved without more input and truly must ship as an open question, keep it to the
|
|
smallest possible list, phrase it as a direct question, and ask the user about it
|
|
directly (don't just leave it sitting in the document) rather than defaulting to
|
|
"flag everything as open" as a way to look thorough.
|
|
|
|
**Describe the mock, not how far the implementation went.** A mockup deliverable
|
|
should say that a quick UI mockup was made by updating the relevant screens, then
|
|
explain what the mock demonstrates. A schema deliverable should present the proposed
|
|
schema and migration direction. Never tell the deliverable's audience that the mock
|
|
was fully coded, built as a real feature, production-ready, implemented end to end,
|
|
or created on a working branch. The code-based mock workflow below is an internal
|
|
method for producing accurate screenshots, not part of the deliverable's story.
|
|
|
|
Process, per deliverable:
|
|
|
|
1. Write `<slug>.md`.
|
|
2. Write `<slug>.typ` from it, per the styling notes above.
|
|
3. Compile: `typst compile <slug>.typ <slug>.pdf`. `typst` should already be on PATH;
|
|
if it isn't, tell the user rather than silently skipping the PDF.
|
|
4. Actually look at the compiled PDF using the Read tool (it reads PDFs directly, page
|
|
by page for longer documents). Check every page for real layout problems: text or
|
|
a table overflowing a page, an awkward page break splitting a table or diagram,
|
|
cramped or excessive spacing, a diagram that rendered wrong. A successful compile
|
|
only means valid Typst, not that it looks right — actually look.
|
|
5. If anything looks wrong, fix `<slug>.typ` and go back to step 3. Repeat until the
|
|
PDF genuinely looks right, not just until it compiles without erroring.
|
|
|
|
If `.claude/docs/` is tracked by git in this repo (check with
|
|
`git check-ignore .claude/docs` — no output means it's tracked), commit a
|
|
deliverable's three files together as one commit, same as any other step. If it's
|
|
gitignored (as in command-center), these files never show up in git at all, which is
|
|
expected and fine — they're meant to be shared manually (Slack, attached to the Jira
|
|
ticket, however this team actually hands off docs), not through the MR. Don't try to
|
|
force-add gitignored files to work around this without asking first, that's an
|
|
existing deliberate house rule, not an oversight.
|
|
|
|
If a deliverable is a UI mock, capture the UI mock described in **Mocks and datamodel
|
|
changes** below rather than drawing a separate wireframe. In the deliverable itself,
|
|
describe it only as a quick UI mockup.
|
|
|
|
## Mocks and datamodel changes: build them for real
|
|
|
|
When a ticket calls for mocks or datamodel changes (a spike proposing new screens or a
|
|
new schema, for instance), don't stop at wireframes or a schema proposal document.
|
|
Build it for real, on the ticket's branch. Mark these steps `(mock)` in `plan.md`.
|
|
|
|
A mock deliverable is **two artifacts**, not one, and they answer different questions.
|
|
The code proves the thing is buildable and surfaces the problems a picture hides. The
|
|
visual mocks show what it should look like once it's built properly, unconstrained by
|
|
what was quick to wire up. Ship both, and don't let either stand in for the other.
|
|
|
|
- **Datamodel changes**: make the actual schema change (e.g. edit
|
|
`packages/db/prisma/schema.prisma` and generate a migration the normal way for this
|
|
repo) rather than only describing it in a document. The proposal document from
|
|
Deliverable documents above can and should still exist, but it now describes
|
|
something that's actually in the branch, not just a plan for something that might
|
|
be built later.
|
|
- **UI mocks**: build the actual screens/components in the app, wired up enough to
|
|
navigate to and look real, not a static image or a markdown wireframe. Where it
|
|
isn't much more work, prefer making it an actually working proof of concept (real
|
|
data flowing through, not a placeholder-filled shell) over a purely cosmetic mock —
|
|
that's almost always more informative for close to the same effort.
|
|
MVP quality is the bar for this half, not polish: real data flowing and a screen you
|
|
can navigate to is what matters, and rough or ugly is fine, because the visual mocks
|
|
below are what carry the intended look.
|
|
- **Visual mocks alongside the code, one or two of them.** The built version is
|
|
deliberately rough, so on its own it under-sells the idea to anyone reviewing it.
|
|
Produce one or two polished mocks that aren't constrained by what was cheap to build:
|
|
the layout, spacing, and density as they should actually be. In Claude Code the
|
|
`design` skill produces a canvas of artboards for exactly this; in a harness without
|
|
it, a self-contained HTML page does the same job. These are design intent, not
|
|
implementation promises, so call out anything a mock shows that the code doesn't do
|
|
yet.
|
|
- **Scope discipline still applies.** This is a proof of concept, not a production
|
|
feature. Don't chase every edge case and don't fix unrelated pre-existing bugs you
|
|
happen to notice along the way, just implement enough of the real thing to be
|
|
screenshotted and evaluated. If doing it for real would take significantly longer
|
|
than a static mock would, say so in `plan.md` rather than silently scoping it down
|
|
without mentioning the tradeoff.
|
|
- **Screenshot the real thing.** Once it's built and running, use the `run` skill to
|
|
get the app up and a browser automation tool (e.g. `claude-in-chrome`) to capture
|
|
the actual screens, instead of drawing a wireframe. Save screenshots under
|
|
`deliverables/<slug>/screenshots/` and the visual mocks under
|
|
`deliverables/<slug>/mocks/`, and embed both in `<slug>.typ` via `image()` when
|
|
building the mockups deliverable. Label which is which. A reader who can't tell a
|
|
built screen from a design mock will read the mock as a promise of what already
|
|
works.
|
|
- **Same rigor as any other code.** This is real work on the ticket branch like any
|
|
other implementation step: same commit discipline, included in Phase 2's
|
|
verification pass, and not exempt from `pre-mr-review` just because the ticket is a
|
|
spike.
|
|
|
|
The `prototype` skill is a different job, not this one. It makes throwaway code for
|
|
settling which direction to take, parked on a branch out of main and thrown away after.
|
|
Reach for it when the spike's real open question is which of several directions to
|
|
build. Once a direction is settled, the deliverable is the two artifacts above, and both
|
|
ship with the ticket.
|
|
|
|
---
|
|
|
|
## Branch setup — run this before any repo work in Phase 1 or Phase 2
|
|
|
|
Every ticket gets its own branch, prefixed with the ticket key
|
|
(`<KEY>-Title-Case-Hyphenated-summary`, matching this org's existing convention, e.g.
|
|
`KACP-22823-Fix-Invalid-Date-In-Retainer-Datagrid`). Do this unconditionally as the
|
|
first thing in Phase 1, before fetching or writing anything, not just in Phase 2 —
|
|
spikes and plans can turn into real code (prototypes, mockup components) partway
|
|
through, and the branch needs to already exist when that happens.
|
|
|
|
1. Determine the repo's default branch (`main` here; if genuinely unsure, check
|
|
`git symbolic-ref refs/remotes/origin/HEAD`).
|
|
2. Find candidate branches for this ticket, local and remote:
|
|
`git branch --list "<KEY>-*"` and `git branch -r --list "origin/<KEY>-*"`.
|
|
3. **No matches** — fresh ticket branch:
|
|
- Run `git status`. If there are uncommitted changes, stop and ask before doing
|
|
anything — don't risk carrying unrelated work onto a new branch.
|
|
- If not already on the default branch, check it out.
|
|
- Update it: `git pull --ff-only`. If that fails (local default branch has
|
|
diverged from `origin`), stop and ask rather than forcing anything.
|
|
- Create the new branch off the now up-to-date default branch, named from the
|
|
ticket title (2-6 words, Title-Case-Hyphenated, prefixed with `<KEY>-`).
|
|
`git checkout -b <name>`.
|
|
4. **Exactly one match** — this ticket already has a branch:
|
|
- If not already on it: check `git status` first. If there are uncommitted changes
|
|
that don't look like they belong to this ticket, stop and ask before switching.
|
|
Otherwise check it out (`git checkout <branch>`, or
|
|
`git checkout -t origin/<branch>` if it only exists remotely).
|
|
- Compare it to the default branch: `git merge-base <branch> <default>` vs
|
|
`git rev-parse <default>`. If they match, the branch is current off the default
|
|
branch — proceed normally.
|
|
- If the default branch has moved on since the branch's merge-base, don't silently
|
|
merge or rebase anything. Tell the user how many commits the branch is behind
|
|
(and how many commits of ticket work are already on it), then ask
|
|
(AskUserQuestion) what they want: merge the default branch in, rebase onto it,
|
|
proceed as-is, or abandon it and cut a fresh branch instead. Do whichever they
|
|
pick.
|
|
5. **More than one match** — don't guess which one is "the" branch. List them (last
|
|
commit date and subject each) and ask the user which to use.
|
|
|
|
Once this resolves you're on the correct branch, and Phase 1/Phase 2 work happens
|
|
there. `.claude/docs/` itself is gitignored in this repo, so which branch you're on
|
|
doesn't affect `ticket.md`/`plan.md`/`mr.md` directly — this is about making sure any
|
|
actual code (mockup prototypes, spike code, real implementation) lands in the right
|
|
place from the start.
|
|
|
|
## Phase 0 — figure out where this ticket stands
|
|
|
|
1. Validate the ticket key looks like `[A-Z]+-[0-9]+`. If not, ask the user for a
|
|
correct key.
|
|
2. Look for an existing directory for this ticket without hitting the network:
|
|
`find .claude/docs/epics -mindepth 2 -maxdepth 2 -type d -name "<KEY>"`
|
|
(this matches both `epics/<EPIC>/<KEY>` and `epics/tickets/<KEY>`).
|
|
3. Branch on what you find:
|
|
- **Nothing found** — this is a fresh ticket. Go to **Phase 1**.
|
|
- **Directory exists, no `plan.md`** — a previous run was interrupted before writing
|
|
a plan. Go to **Phase 1** and regenerate from scratch (re-fetch, overwrite
|
|
`ticket.md`, re-check attachments); it's idempotent and cheap.
|
|
- **`plan.md` exists, no `mr.md`** — ask the user (AskUserQuestion) what they want:
|
|
- Re-fetch the ticket and rewrite the plan from scratch (they want to start over)
|
|
- Proceed to implementing the existing `plan.md` as-is (they reviewed and approved it)
|
|
- Resume implementation (some plan steps are already checked off / some commits
|
|
already exist on the ticket branch — pick up from the first unchecked step)
|
|
- Run `pre-mr-review` now (implementation looks done, just need the audit + MR doc)
|
|
Route to **Phase 1** or **Phase 2** accordingly.
|
|
- **Both `plan.md` and `mr.md` exist** — this ticket looks finished. Tell the user
|
|
`mr.md` already exists at its path and ask whether they want you to refresh it
|
|
(e.g. they made more changes since) or leave it alone. Only re-enter Phase 2's
|
|
verification/pre-mr-review loop if they say the code changed since `mr.md` was
|
|
written. Also fetch the ticket and check whether its type's Jira fields (Phase 2
|
|
step 9) are actually filled; an `mr.md` from before this skill filled Jira
|
|
directly may mean the fields were never written, offer to fill them.
|
|
|
|
## Phase 1 — fetch, scaffold, and plan
|
|
|
|
1. Do **Branch setup** above first, unconditionally.
|
|
2. Run `jira-fetch-issue.sh <KEY> <tmp-path>` (a scratch path is fine here — you don't
|
|
yet know the final directory). Read the resulting JSON.
|
|
3. Determine the epic: `fields.parent.key`, if present. If absent, this ticket has no
|
|
epic.
|
|
4. Resolve the target directory:
|
|
- With epic: `.claude/docs/epics/<EPIC-KEY>/<KEY>/`
|
|
- Without epic: `.claude/docs/epics/tickets/<KEY>/`
|
|
Create it and its `resources/` subdirectory.
|
|
5. Move/copy the fetched JSON to `<target-dir>/resources/issue.raw.json` for your own
|
|
reference while writing `ticket.md` — this raw file is scratch, not part of the
|
|
deliverable; feel free to leave it (it's harmless context for later) or delete it
|
|
once `ticket.md` is written, your call.
|
|
6. If there's an epic and `.claude/docs/epics/<EPIC-KEY>/epic.md` doesn't already exist:
|
|
best-effort fetch the epic issue too (`jira-fetch-issue.sh <EPIC-KEY> <tmp>`) and
|
|
write a short `epic.md` (title + description, converted to markdown, a couple
|
|
paragraphs at most). If this fetch fails for any reason, skip it and continue — it's
|
|
context, not a blocker.
|
|
7. Write `resources/ticket.md` by reading the fetched issue JSON yourself:
|
|
- Title, type, status, priority, assignee, epic key (or "None"), and a link
|
|
(`<JIRA_BASE_URL>/browse/<KEY>`).
|
|
- Description: convert `renderedFields.description` (HTML) to clean markdown. If
|
|
empty, say so.
|
|
- Developer review instructions: the field name varies by project and isn't a fixed
|
|
custom field ID. Look at the `names` map in the response for any field whose name
|
|
matches something like "dev review instructions" / "review instructions"
|
|
(case-insensitive substring match), then render that field's value the same way as
|
|
the description. If nothing matches, write "None provided" — don't guess a field.
|
|
- Test cases: same approach for any field whose name matches something like
|
|
"test cases" / "test table" / "working feature proof" / "qa" (case-insensitive
|
|
substring match), e.g. KACP's "Test Cases & Working Feature Proof" field. This
|
|
is part of the ticket's testing section and MUST be captured into `ticket.md`
|
|
whenever it holds anything beyond an empty template. Often it's just the bare
|
|
instruction panel and empty table, note that and move on. But when it has real
|
|
content, that content is part of the implementation and has to be known from
|
|
the start: render every row verbatim as a markdown table under its own
|
|
`## Test cases and working feature proof` heading, keeping the ticket's own
|
|
column headers, and carry any prose or instructions in the field alongside the
|
|
table. These are the scenarios the developer must prove, so Phase 1's plan must
|
|
already say how each row gets proven, Phase 2's verification must actually
|
|
prove each row, and Phase 2 step 9 fills the proof column back into the Jira
|
|
field itself. If nothing matches, write "None provided".
|
|
- Risk mitigation: same approach for any field whose name matches something like
|
|
"risk mitigation" / "risk management" / "risks" (case-insensitive substring
|
|
match), e.g. KACP's "Risk Mitigation" field. Same rule as test cases: an empty
|
|
template gets noted, real content gets captured in full because it shapes the
|
|
implementation from the start. Render it as a markdown table under its own
|
|
`## Risk mitigation` heading, keeping the ticket's own column headers and
|
|
every row verbatim. The PM and Lead Developer write the risks and mitigation
|
|
strategies; implementing those strategies and proving each one is the developer's
|
|
job, so every row needs a real mitigation in the code and its proof filled into
|
|
the Jira field in Phase 2 step 9. If nothing matches, write "None provided".
|
|
- Developer fill-in tables, in general: any ticket table with a column the developer
|
|
is meant to complete (Working Feature Proof, Mitigation Proof, and the like) is
|
|
copied into `ticket.md` in full, with that column left showing where its answer
|
|
goes rather than dropped. `ticket.md` is the record of what the ticket actually
|
|
asks for. Never substitute your own invented test cases or risks for the ticket's,
|
|
in `ticket.md` or in the Jira fields. Your own additional cases are welcome, but
|
|
they go alongside the ticket's rows, clearly marked as additional, never in place
|
|
of them.
|
|
- Sweep for anything else populated: list every key in the `names` map whose field
|
|
actually has a non-null, non-empty value on this issue (jq over `.fields` joined
|
|
with `.names`), and skim any populated field not already captured above. Capture
|
|
the ones relevant to implementing or verifying the ticket; ignore workflow
|
|
plumbing (ranks, sprints boards, reviewer assignments, rich-field duplicates).
|
|
This exists because real content sometimes hides in per-project custom fields
|
|
with unpredictable names — a name-pattern miss must not silently drop content.
|
|
- Any other fields on the ticket that look clearly relevant to implementing it
|
|
(acceptance criteria field, story points, labels, components) are worth a short
|
|
line each; don't dump every custom field verbatim.
|
|
8. Run `jira-download-attachments.sh <issue.raw.json> <target-dir>/resources/`. For each
|
|
attachment with a `video/*` mime type, check whether another attachment already looks
|
|
like its transcript (same base filename with `.txt`/`.srt`/`.vtt`, or a filename
|
|
containing "transcript"). Collect any videos with no matching transcript.
|
|
9. If there are untranscribed videos, ask the user (AskUserQuestion, one question,
|
|
multiSelect if more than one video) whether to transcribe them now. For each they
|
|
approve, run `transcribe.sh <video-path> <target-dir>/resources/`. Note in `ticket.md`
|
|
under Attachments which videos have a transcript and which were skipped.
|
|
For every video that gets transcribed, also extract frames — ticket videos are
|
|
almost always screen recordings, and the transcript alone misses what was on
|
|
screen (the UI being pointed at, the annotation, the row that's wrong). Extract to
|
|
`<target-dir>/resources/<video-basename>.frames/` with scene detection plus a time
|
|
floor, for example:
|
|
`mkdir -p <frames-dir> && ffmpeg -i <video> -vf "select='gt(scene,0.1)+isnan(prev_selected_t)+gte(t-prev_selected_t\,15)'" -fps_mode vfr <frames-dir>/frame-%03d.png`
|
|
Tune the scene threshold or floor so a typical video yields tens of frames, not
|
|
hundreds (raise the floor for long recordings). Then actually look at the frames
|
|
with the Read tool during research, cross-referencing the transcript's timestamps,
|
|
and treat what's visible on screen as part of the ticket's content the same way
|
|
the transcript is. Skip frame extraction only when the video is confirmed
|
|
audio-only or the user says the visuals don't matter.
|
|
10. Now actually understand the ticket in the context of this codebase: read whatever
|
|
source files, tests, or docs are relevant to what's being asked. Use Explore/grep
|
|
as needed — this is normal engineering research, not scripted. Use the
|
|
**Verification tools available** above to check the ticket's own claims against
|
|
reality (codebase, Jira, staging, and prod/CI env with permission) rather than
|
|
taking the ticket's description at face value — this is what makes the plan
|
|
trustworthy instead of just plausible-sounding.
|
|
11. Write `plan.md` in `<target-dir>/plan.md` (a sibling of `resources/`, not inside
|
|
it). Structure:
|
|
```
|
|
# Plan: <KEY> — <short title>
|
|
|
|
## Acceptance criteria
|
|
- [ ] <criterion from the ticket, restated precisely>
|
|
...
|
|
|
|
## Open questions
|
|
<Anything genuinely blocking or ambiguous that needs the user's answer before or
|
|
during implementation. "None" if there really aren't any — don't manufacture
|
|
questions to look thorough.>
|
|
|
|
## Approach
|
|
<Narrative: what you're going to do and why, which files/modules/functions are
|
|
involved, how it fits the existing patterns in this codebase.>
|
|
|
|
## Steps
|
|
- [ ] <step 1, roughly one commit's worth of work — mark it `(deliverable)` if it
|
|
produces a document via the Deliverable documents process instead of code, or
|
|
`(mock)` if it's a real schema/UI change built to demonstrate a mock rather than
|
|
ship a finished feature, see Mocks and datamodel changes>
|
|
- [ ] <step 2>
|
|
...
|
|
|
|
## Risks and edge cases considered
|
|
- <edge case> — <how the plan handles it>
|
|
...
|
|
|
|
## Test plan
|
|
- <how you'll verify each acceptance criterion, including existing test suites to
|
|
run and any new tests to add>
|
|
```
|
|
Be thorough: address every acceptance criterion, resolve as many open questions as
|
|
you reasonably can by reading the code first, and don't leave logic gaps. Steps
|
|
should be concrete enough that Phase 2 can execute them without re-deriving the
|
|
approach. The Test plan must name every test case `ticket.md` captured and say how
|
|
that exact case gets proven, and the Risks section must name every risk
|
|
`ticket.md` captured and say which code enforces its mitigation. Read the notes
|
|
column of a ticket test case as part of the case, not as commentary: a note like
|
|
"confirm the certificate matches the emailed version" is its own thing to prove.
|
|
|
|
**Wide refactors are the exception to one-commit steps.** A wide refactor is a single
|
|
mechanical change whose blast radius fans across the codebase (renaming a column,
|
|
retyping a shared symbol), so one edit breaks thousands of call sites at once and no
|
|
single step can land green. Don't force it into one. Sequence it as expand, then
|
|
migrate, then contract: first add the new form beside the old so nothing breaks, then
|
|
migrate the call sites in batches sized by blast radius (per package, per directory)
|
|
with each batch its own step, then delete the old form once no caller remains. Every
|
|
step stays green because the old form still exists until the last one. Say in the
|
|
Approach that this is what you're doing and why, since the step count looks inflated
|
|
otherwise.
|
|
12. Stop here. Tell the user `plan.md` is ready at its path, summarize the approach in
|
|
a couple of sentences, and mention any open questions that need their input before
|
|
you'd implement it. Do not start implementing in this same run — wait for them to
|
|
review the plan (editing it directly if they want) and invoke `/ticket <KEY>` again.
|
|
|
|
## Phase 2 — implement, verify, and hand off
|
|
|
|
Entered only when the user has confirmed (per Phase 0) that the plan is approved.
|
|
|
|
1. Do **Branch setup** above first, unconditionally — even if Phase 1 already did this
|
|
for the same ticket earlier, confirm you're still actually on that branch now (the
|
|
user may have switched branches between runs).
|
|
2. Read `plan.md` fresh — the user may have hand-edited it.
|
|
3. Work through `plan.md`'s Steps checklist in order. For each step: implement it (a
|
|
step marked `(deliverable)` follows the **Deliverable documents** process above
|
|
instead of writing code; a step marked `(mock)` follows **Mocks and datamodel
|
|
changes** — real schema/UI work, not a static wireframe), then check it off
|
|
(`- [x]`) in `plan.md`, then make one commit for it (or a few, if the step
|
|
naturally splits into independent units). Commit messages are short and imperative,
|
|
describing what changed, following House style above.
|
|
|
|
If a step fails in a way `plan.md` didn't predict, and the cause isn't obvious within
|
|
a couple of minutes, call the Skill tool with "diagnosing-bugs" rather than trying
|
|
fixes to see what sticks. Note anything it turns up that changes the plan.
|
|
4. Do not run the full verification suite after every commit (checks-at-the-end mode).
|
|
Once every step is implemented and checked off, find and run this project's standard
|
|
verification (check `package.json` scripts for something like `ci:check`,
|
|
`typecheck`, `lint`, `test`, or fall back to whatever the repo's README documents).
|
|
Fix anything broken, committing fixes as their own commits, until it's clean. If you
|
|
can't find any verification command at all, say so explicitly later in `mr.md`
|
|
rather than claiming a build/lint/test pass that never happened. Beyond the standard
|
|
suite, use the **Verification tools available** above for anything the suite
|
|
wouldn't actually catch, e.g. confirming behavior against real staging data via
|
|
Infisical, or a specific prod/CI config question, when that's genuinely what it
|
|
takes to be confident the change works as intended rather than just "looks right."
|
|
5. Get an independent code review, from a FRESH agent, before running `pre-mr-review`.
|
|
|
|
This step exists because `pre-mr-review` cannot do it. That skill is constitutionally
|
|
read-only: it may not run tests, execute code, probe a database, or run any
|
|
experiment, and its own rules tell it to mark anything unprovable as "Needs
|
|
verification" rather than proving it. So it cannot catch a claim that is plausible on
|
|
the page and false in reality. A reviewer that can actually run things can. It has
|
|
already caught a mitigation that was proven by construction to be wrong, on a branch
|
|
whose own audit had blessed it.
|
|
|
|
Order matters and is not just convenience. `pre-mr-review`'s output is a readiness
|
|
verdict that gets pasted verbatim into `mr.md`. Anything that runs after it
|
|
invalidates that verdict by construction, and you end up rerunning it and rewriting
|
|
the handoff. Review first, fix, commit, and only then run `pre-mr-review` over the
|
|
final tree.
|
|
|
|
- **Skip this step for genuinely trivial changes**: a copy tweak, a styling fix, a
|
|
one line correction with no logic in it. Run it whenever the change adds or
|
|
modifies a procedure, touches schema or migrations, touches permissions or
|
|
auth, involves concurrency, or has a risk table in its ticket. When unsure, run it.
|
|
- **Always dispatch a NEW agent.** Never reuse an agent from earlier in this ticket
|
|
and never review your own work in your own context. The value here is entirely in
|
|
the reviewer not being the author, so an agent that helped implement or plan the
|
|
change cannot provide it.
|
|
- **Give the reviewer its reading order explicitly**, or it produces noise about
|
|
conventions the project already settled: the epic summary if there is one
|
|
(`.claude/docs/epics/<EPIC-KEY>/summary.md`), then this ticket's `resources/` and
|
|
`plan.md`, then `AGENTS.md`, and only then the diff. Give it the exact commit range.
|
|
- **Tell it to verify rather than suspect**, to try to refute its own findings before
|
|
reporting them, to mark each finding CONFIRMED or PLAUSIBLE, and to give exact
|
|
`file:line` plus a concrete failure scenario. Tell it explicitly not to write,
|
|
commit, push, or run anything destructive.
|
|
- **Point it at the claims already made.** Every "proven by X" already written into
|
|
the ticket's risk or test tables must be re-derived, not taken on trust. A false
|
|
proof claim in Jira is worse than an unproven one, because it stops anyone else
|
|
from checking.
|
|
- **Ask the spec questions explicitly**, or the review only finds bugs in what you
|
|
did write and never notices what you didn't. Three questions, each answered against
|
|
`ticket.md` and `plan.md` rather than the diff alone: what the ticket asked for that
|
|
is missing or only partly done; what behavior is in the diff that nothing asked for;
|
|
and what looks implemented but is implemented wrongly. Have it quote the AC ID or
|
|
the `plan.md` line each finding traces to.
|
|
|
|
Then respond to the review, in writing:
|
|
|
|
- **Findings are not automatically true.** Verify each one against the codebase
|
|
before acting on it. Reviewers do produce confident wrong answers. Say plainly
|
|
which findings you rejected and why, rather than quietly accepting all of them.
|
|
- **Fix everything real**, each meaningful fix as its own commit. Do not defer a
|
|
known hole to a follow-up ticket unless the user decides that.
|
|
- **When a fix changes a mechanism rather than a line**, write a test that fails
|
|
against the old behavior and passes against the new one, and actually confirm it
|
|
fails by reverting the fix. A test that passes either way proves nothing.
|
|
- **If a finding invalidates something already written into Jira or a deliverable,
|
|
correct it there too.** The code being fixed does not fix the false claim.
|
|
- **Terminate deliberately.** Run the reviewer ONCE on the branch. `pre-mr-review`
|
|
then reviews the whole diff including your fixes and serves as the second pass.
|
|
Only dispatch a second reviewer if a fix changed a mechanism, not for line level
|
|
fixes, and never loop "review until clean."
|
|
|
|
6. Confirm this project actually has a `pre-mr-review` skill (`.claude/skills/pre-mr-review/`
|
|
in the current repo). If it doesn't, stop here, tell the user implementation and
|
|
local verification are done but this repo has no `pre-mr-review` skill to run, and
|
|
let them decide how to proceed.
|
|
7. Invoke the `pre-mr-review` skill. Read its verdict.
|
|
- **Ready to Open MR**: continue to step 8.
|
|
- **Almost Ready / Not Ready Yet**: fix what it flagged (each meaningful fix as its
|
|
own commit), then invoke `pre-mr-review` again. Repeat until the verdict is Ready
|
|
to Open MR. Don't write `mr.md` before that verdict is reached.
|
|
8. Read `~/.agents/skills/ticket/templates/mr.md` — this is the org's MR template,
|
|
copied into this skill so it still works even though the original
|
|
`.claude/docs/mr/template.md` no longer exists in the command-center repo. `mr.md`
|
|
is ONLY the MR description: the filled template plus the pasted pre-MR handoff.
|
|
Jira ticket fields are not written here, they go straight into Jira in step 9.
|
|
Fill it in for real:
|
|
- H1: from the ticket and the actual work done, not the ticket title verbatim if the
|
|
real change ended up narrower/broader.
|
|
- Summary: one short paragraph max. High level only, what changed, not how. This
|
|
is not the place for a list of every file touched.
|
|
- Issue Link: `<JIRA_BASE_URL>/browse/<KEY>`.
|
|
- New ENVs: list any env vars actually introduced; "None" if none.
|
|
- Additional Notes: a bulleted checklist of the changes you actually made, not a
|
|
dumping ground. Between Summary and this section, every acceptance criterion from
|
|
`plan.md` (or, for a bug ticket, the bug itself) needs to be directly addressed,
|
|
not just gestured at. If there's genuinely unrelated work worth mentioning (e.g.
|
|
an incidental fix along the way), it goes after everything ticket-relevant, still
|
|
as short bullets. Five bullet points max total, ticket-relevant and incidental
|
|
combined. If it doesn't fit in five, it's too much detail for this section, trim
|
|
it rather than running long.
|
|
- Checklist: check only boxes you actually verified (e.g. only check "Build
|
|
verified" if you actually ran a build and it passed).
|
|
- Replace `<!-- Paste the Pre-MR handoff here -->` with the exact content of the
|
|
latest `pre-mr-review` handoff file (the one with verdict Ready to Open MR) —
|
|
paste it verbatim, don't summarize it.
|
|
|
|
The handoff section of `mr.md` is GENERATED OUTPUT, not something you author.
|
|
It is the block that states whether the branch is ready to merge, so it must be
|
|
the audit's own words, not a retelling of them. Concretely:
|
|
|
|
- Never hand-write a handoff section, and never edit one in place. If it is
|
|
wrong, thin, or stale, fix the handoff file by rerunning `/pre-mr-review`,
|
|
then re-paste.
|
|
- On EVERY rerun, replace the whole existing handoff block with the whole
|
|
regenerated one. Do not patch the copy sitting in `mr.md` to match the new
|
|
head — that is how the two silently diverge, and the version the reviewer
|
|
reads stops being the version the audit actually produced.
|
|
- After pasting, verify the tail of `mr.md` is byte-identical to the handoff
|
|
file. If it isn't, you edited it.
|
|
- The handoff file itself must follow `templates/handoff.md` in the repo's
|
|
`pre-mr-review` skill. If real content doesn't fit that structure, the fix is
|
|
to write it into the handoff file under the right heading, not to bolt an
|
|
extra section onto `mr.md`.
|
|
- Developer responsibilities: if the ticket's dev review instructions impose their
|
|
own deliverables on the developer (e.g. KACP's standing "document three to five
|
|
additional edge cases discovered during implementation, each with its handling
|
|
and test, or its deferral and follow-up story"), satisfy them EXPLICITLY, under a
|
|
heading that uses the requirement's own words, in the JIRA FIELD that owns them —
|
|
not in `mr.md`. In command-center that is the engineer-facing patch notes field
|
|
(`customfield_10260`, "For The Engineer: Patch Notes"). Step 9 writes it.
|
|
Scattered coverage across notes does not count as having answered a named
|
|
requirement, and neither does burying it in the MR description.
|
|
Save this as `<target-dir>/mr.md` (next to `plan.md`, not under `resources/`).
|
|
|
|
**`mr.md` is the template plus the pasted handoff, and NOTHING ELSE.** This is a
|
|
hard shape, not a starting point. Its only headings are the template's own numbered
|
|
sections and the handoff's. Do not add narrative sections, however well justified
|
|
they feel: no "how I built it", no per-ticket deep dives, no edge-case writeups, no
|
|
"Jira Ticket Fields" section, no test tables, no root cause analysis. Those live in
|
|
Jira and step 9 puts them there.
|
|
|
|
Anything you are tempted to add as a section belongs in **Additional Notes**, as one
|
|
tight bullet. If it will not compress to a bullet, it is Jira content, not MR
|
|
content. A reviewer should be able to read the whole file in about a minute; if it
|
|
has grown past roughly 120 lines including the handoff, it has drifted.
|
|
9. Fill the Jira ticket fields directly, by issue type. Rich text fields are ADF:
|
|
render markdown with `python3 ~/.agents/skills/review-ticket/scripts/review2adf.py
|
|
render <file.md>` and PUT via `{"fields": {...}}` to `/rest/api/3/issue/<KEY>`.
|
|
After every PUT, re-fetch and verify the field landed (compare extracted text,
|
|
treating empty `attrs` objects and `localId`/`colwidth`/`width` as noise). The
|
|
field-to-type map below is verified against the project's edit screens, don't PUT
|
|
a field to a type that doesn't carry it.
|
|
|
|
**Proof first.** Before filling any proof column, capture working feature proof
|
|
yourself wherever possible: run the app (`run` skill) and screenshot the real
|
|
feature with browser automation, or capture test output for behavior with no UI.
|
|
Save artifacts under `<target-dir>/proof/` with names that match the test-case
|
|
rows they prove. A proof cell references its artifact by filename plus "attached"
|
|
(Gib uploads every attachment, this skill NEVER uploads files to Jira) or names
|
|
the passing test. When proof genuinely can't be captured here (needs prod, a real
|
|
inbox, a flag flip), the cell says exactly what's needed and step 10 lists it for
|
|
Gib. A row with no proof and no named gap is missing work, not a documentation
|
|
gap: go run the check first.
|
|
|
|
**Cap the proof at five files, and aim for two or three.** Gib uploads every
|
|
attachment by hand, so each file has a real cost and a wall of near-duplicate
|
|
screenshots buries the two that matter. Before filling the proof column, pick the
|
|
smallest set that actually carries the evidence and delete the rest from `proof/`.
|
|
|
|
- One screenshot can prove several rows at once. A company page that shows the
|
|
navigation, the tabs, and the absent section proves three criteria in one image,
|
|
so prefer it over three separate captures.
|
|
- Prefer text over images wherever the evidence is textual. Command output, a
|
|
config diff, a grep result, or a list of rendered labels all belong in a single
|
|
`.txt` file, which is cheaper to attach and easier to read than a screenshot of
|
|
the same thing. Fold what a dropped screenshot proved into that file rather than
|
|
losing the evidence.
|
|
- Capture as many as you like while working. The cap applies to what survives in
|
|
`proof/` when you fill the Jira fields, not to what you take along the way.
|
|
- Never reference a file in a proof cell that is not in `proof/`, and never leave a
|
|
file in `proof/` that no proof cell references. The two lists match exactly.
|
|
|
|
**Bug** (fields on the Bug edit screen):
|
|
- `customfield_10259` For the Engineer: Root Cause Analysis: the actual diagnosed
|
|
cause as a short narrative naming the real files and mechanism, not the ticket's
|
|
theory.
|
|
- `customfield_10263` Precipitating Event: what introduced or exposed the bug and
|
|
when (the commit, upgrade, or change that made it start happening).
|
|
- `customfield_10260` For The Engineer: Patch Notes: changelog-style statement of
|
|
the fix.
|
|
- `customfield_10142` Working Feature Proof: the test-case table (Summary, Steps,
|
|
Expected Results, Working Feature Proof, Notes) with the real scenarios verified
|
|
and the proof column filled.
|
|
|
|
**Story** (fields on the Story edit screen):
|
|
- `customfield_10253` Test Cases & Working Feature Proof: ALWAYS fetch and read
|
|
this field, whoever wrote the dev review, and no matter what state it's in.
|
|
Whatever rows it carries are the scenarios to prove: fill the empty Working
|
|
Feature Proof cells of the existing rows in place, never duplicate rows. If the
|
|
field is still a bare template with no rows, add the real scenarios verified as
|
|
new rows. New rows go through `review2adf.py tables <field.json> <rows.md>`,
|
|
which preserves the instruction panels and headers.
|
|
- `customfield_10129` Risk Mitigation: same in-place treatment for the Mitigation
|
|
Proof column.
|
|
- `customfield_10260` Engineer Patch Notes: changelog-style, what changed. This is
|
|
also where the dev review instructions' own developer deliverables go, under a
|
|
heading in the requirement's own words. For KACP that is the standing "three to
|
|
five additional edge cases discovered during implementation", each with how it was
|
|
handled and what covers it. Deliver the number asked for, not more, and pick the
|
|
ones a reviewer most benefits from. This field, not `mr.md`.
|
|
- `customfield_10261` User Story Patch Notes: the same change in user-facing words.
|
|
- `customfield_10142` Working Feature Proof: ALWAYS fill this on a Story, never
|
|
leave it empty. It renders as its own panel in the ticket's testing section, so
|
|
an empty field reads as unfilled testing even when every test-table cell is
|
|
complete (this happened on KACP-23143). At minimum it lists the files staged in
|
|
`proof/` for Gib to attach, one line each saying what the artifact shows, plus a
|
|
pointer that per-row proof lives in the Test Cases table. A headline artifact (a
|
|
demo capture, a before/after pair) leads the list when one exists.
|
|
|
|
**Spike** (deliverables, not code): no test or proof fields to fill. The output is
|
|
the deliverables directory, and step 10 tells Gib which files to upload where (the
|
|
ticket, Drive, or both, per the ticket's instructions). Fill `customfield_10260`
|
|
only if the spike actually shipped code.
|
|
|
|
Before moving on, re-read `ticket.md` row by row: every test case and every risk
|
|
the ticket carries now has its developer column filled in Jira. Leave none
|
|
unanswered.
|
|
10. Tell the user: implementation is committed on `<branch>`, `pre-mr-review` verdict is
|
|
Ready to Open MR, the Jira fields are filled (name which), and `mr.md` is ready at
|
|
its path. Then the manual list, which should only ever be:
|
|
- push the branch, open the MR, and paste `mr.md` in as the description
|
|
- upload the named proof or deliverable files (from `proof/` or `deliverables/`)
|
|
to the ticket, plus anything flagged as proof only Gib can capture
|
|
Remind them nothing was pushed, no MR was opened, and no attachments were uploaded.
|
|
|
|
## Resuming mid-implementation
|
|
|
|
If Phase 0 routes here because some steps in `plan.md` are already checked off: check
|
|
`git log` on the current branch against the plan's steps to sanity-check they actually
|
|
match reality (a checked-off step should have a corresponding commit), then continue
|
|
from the first unchecked step. If the plan and the git history disagree, stop and ask
|
|
the user rather than guessing which one is right.
|