Claude opencode Skill

test-documentation

Analyze, prioritize, and document test cases in TMS (Jira/Xray), or repair an existing Story-ATS-ATP-ATR-TC cascade through a sealed explicit mode. Use for Test/ATP/ATR artifacts, ROI and automation verdicts, maintaining traceability, fix-traceability, or broken TMS links. The re

LLM Mart · 0 points · 20 views 7 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download upex-galaxy-agentic-qa-boilerplate-.agents_skills_test-documentation-d287bb2.zip · 87 KB
Part of upex-galaxy/agentic-qa-boilerplate — 13 skills

Install

skills CLI npx skills add https://github.com/upex-galaxy/agentic-qa-boilerplate/tree/main/.agents/skills/test-documentation
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install upex-galaxy-agentic-qa-boilerplate@llmmart
Git git clone https://github.com/upex-galaxy/agentic-qa-boilerplate.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole upex-galaxy/agentic-qa-boilerplate collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Forbidden invocations

NEVER invoke /sdd-* skills from this workflow. SDD is an optional user-installed ceremony; this skill ships self-contained and does not chain SDD under any condition. If you need to refactor KATA, fixtures, cli/, scripts/, or api/schemas/ pipeline, exit this skill first and invoke /framework-development — which itself runs Plan → Code → Verify → Archive natively (no SDD required).

This boundary is mechanical, not advisory: scripts/lint-skills.ts rejects any /sdd- mention outside this section. See: .agents/skills/agentic-qa-core/references/skill-composition-strategy.md §4 (governs users who manually install SDD).

Test Documentation — QA Bridge

Take already-validated tests and formalize them in the TMS (Jira, Xray, or equivalent) with full traceability, the right priority, and a clear automation verdict.

Three phases, always in this order: Analyze -> Prioritize (ROI) -> Document. Never skip prioritization: most scenarios should end up Deferred, not automated.

One hard prerequisite: the tests being documented must describe behavior that was already validated ({{jira.status.story.qa_approved}} story, closed bug, or finished exploratory session). The TMS is a documentation and regression-protection tool, not an exploration tool.


Dependencies

Requires agentic-qa-core. Loads on demand:

  • agentic-qa-core/references/test-design-doctrine.md — MANDATORY before deriving TCs from acceptance criteria. Governs the 1:N TC explosion, the formal-technique triggers, and the floor-not-ceiling coverage model. EP + BVA are operationalized here against the canon.
  • agentic-qa-core/references/defect-management-doctrine.md — MANDATORY before parenting a Test or raising an Improvement. Governs QA process-epic parenting (every Test hangs from the QA Test Repository epic, Part 4), the mandatory components axis (Part 3), and the Improvement bridge for under-specified ACs (Part 1). This skill files no Bugs.
  • agentic-qa-core/references/briefing-template.md, agentic-qa-core/references/dispatch-patterns.md, agentic-qa-core/references/orchestration-doctrine.md, agentic-qa-core/references/session-management.md, agentic-qa-core/references/preflight-gate.md, agentic-qa-core/references/traceability-linking.md — cited inline by the sections that use them.

Compact Rules

Test-design doctrine (binding — full canon: agentic-qa-core/references/test-design-doctrine.md):

  • Documenting an AC→TC map is the FLOOR (≥1 TC per AC is a minimum, never a target). Coverage = AC-conformance + risk-beyond-AC; the TC set must include boundary / negative / state / anomaly cases the AC is silent on.
  • 1:N applies to DERIVATION (consider many cases by technique), not to the REGRESSION repository. Only regression-worthy scenarios (Candidate/Manual) are persisted there; most are Deferred. jira-native: Stage 4 CREATES Tests for those only (Deferred = report-only). jira-xray: sprint Tests already exist (Stage 1) — Stage 4 PROMOTES the regression-worthy into the Test Plan + enriches them. Document because it will be re-run, never to hit a count.
  • Apply techniques by trigger: EP always; BVA wherever a range/limit/length/date-window exists; State-Transition for stateful entities; Decision Table when 2+ conditions interact; Pairwise when 3+ combinable factors.
  • Parametrize for artifact economy: same-behavior data variants → ONE Test (Scenario Outline + Examples rows) per partition, NOT N separate Tests; split only when action / outcome / status / state differs. (Canon: doctrine §"Part 2.5".)
  • Cross-cutting characteristics (XSS, perf, a11y) deferred to app-level suites are an EXPLICIT handoff, not a silent drop — name the receiving suite or file the gap.

Test-documentation operational rules:

  • Documents already-validated behavior only — not an exploration tool (exploration belongs to /sprint-testing).
  • TC identity = Precondition + Action + verifiable outcome. Naming (TC): {US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]; Validate <feature> is reserved for the GROUPING layer (Test Set summary / describe()). Reject "Login test", "Login - error", "TC1: Test form".
  • ROI formula → one of three verdicts per TC: Candidate (feeds test-automation), Manual, Deferred. Prioritize by risk.
  • Cardinality: US→TC is 1:N; AC→TC is N:1 or N:M. Resolve TMS modality (Xray vs Jira-native) in Phase 0 before documenting.
  • Bug-driven (GOLDEN RULE): not every bug is a regression TC, but a regression-worthy bug MUST end with a Test — REUSE the existing failed Test if it came from one, else CREATE one (both modalities). A non-qualifying bug is treated like a failed test → Deferred, no new Test.

Read full SKILL.md when: resolving TMS modality, computing ROI, writing Gherkin, or wiring US-ATP-ATR-TC traceability links.


Mode routing

Resolve mode before the readiness preflight and Phase -1 session workflow.

  • repair-traceability: selected only by the legacy fix-traceability alias or an explicit request to repair a ticket's existing traceability. Forward $ARGUMENTS unchanged and load only references/repair-traceability.md. Preserve its sealed sequence: audit -> present plan -> explicit user approval -> apply -> verify. Do not start Analyze -> Prioritize -> Document, create unrelated test cases, or broaden the ticket scope.
  • document (default): normal TMS documentation, ROI, and Candidate/Manual/Deferred work. Continue with the workflow below.

If the user has not supplied the ticket key required by repair-traceability, ask for it before any TMS call. Missing credentials remain a hard stop under AGENTS.md Critical Rule #10.

repair-traceability on ONE ticket cannot see the failure that matters most. Coverage-link direction is a project-wide condition: an inverted link is invisible on its own Story (the link is present, the coverage panel is merely empty, nothing reports it) and only reads as a pattern in aggregate — on one measured project, 21 of 43 linked Stories were wired the wrong way, one of them losing a fully populated 69-Test Test Set. So when the mode audits a ticket, ALSO offer the project-wide mixed-direction sweep before applying anything: the [TMS_TOOL] traceability check accepts several keys or a JQL query and returns one repair worklist. Direction doctrine, the delete-before-recreate rule (Jira dedupes the pair+type, so adding the corrected link is a silent no-op) and the sweep are canon in agentic-qa-core/references/traceability-linking.md §4 and §10. Read them before proposing any link repair; the plan the user approves must say which links get deleted, by id.


Subagent Dispatch Strategy

Orchestration & Session contracts: this skill follows agentic-qa-core/references/orchestration-doctrine.md (mandatory subagent dispatch — main thread is command center) AND agentic-qa-core/references/session-management.md (Phase 0 resume check, plan-first persistence at .session/<skill-slug>/<scope>/, archive on completion). Phase 0 (resume check) and Phase 1 (plan write) are NOT optional. The orchestrator also applies the per-stage Definition-of-Done gates in agentic-qa-core/references/stage-gates.md: verify a stage's DoD (planning stages include the Test-Design Checklist) BEFORE recording its progress checkpoint and advancing.

This skill is per-scope: <scope> = <JIRA-KEY> (ticket / bug scope), <module-slug> (module scope), or <YYYY-MM-DD>-adhoc (ad-hoc scope). Session state lives at .session/test-documentation/<scope>/{plan.md, progress.md} per agentic-qa-core/references/session-management.md §3 + §9.

Naming collision note: this skill already owns ## Phase 0 — Resolve TMS modality (the TMS gate). The session resume check is therefore named ## Phase -1 — Session resume check to avoid colliding with the existing Phase 0 anchor. Resume fires FIRST, then the TMS modality gate, then the rest of the pipeline.

This skill is compliant with the doctrine in AGENTS.md §"Orchestration Mode (Subagent Strategy)" and the session contract in .agents/skills/agentic-qa-core/references/session-management.md. Every dispatch follows the 7-component briefing format defined in .agents/skills/agentic-qa-core/references/briefing-template.md, and the pattern selected per phase matches the decision guide in .agents/skills/agentic-qa-core/references/dispatch-patterns.md. Phase 1 (Analyze) and Phase 2 (Prioritize) stay inline because planning and decisions live in the orchestrator; the only Parallel hotspot is bulk TC creation in Phase 3, which is also the only step that branches per TMS modality.

Phase Pattern Subagent role
Phase -1 — Session resume check inline orchestrator only; reads .session/test-documentation/<scope>/progress.md if present, offers resume / restart / abort per agentic-qa-core/references/session-management.md §4
Phase 0 — Resolve TMS modality inline orchestrator only; existing 4-step probe — unchanged
Phase 1 — Analyze scope Single inline — planning lives in the orchestrator (anti-pattern to delegate)
Phase 2 — ROI / Candidate-Manual-Deferred verdict Single inline — decisions live in the orchestrator
Phase 3 — TMS TC creation (N > 10 TCs) Parallel M subagents, chunks of ~5-10 TCs per agent; cap = 10 to avoid Jira/Xray rate limits; each subagent loads /xray-cli (Modality jira-xray) or /acli (Modality jira-native)
Phase 3 — TMS TC creation (N ≤ 10 TCs) Single inline — dispatch overhead is not justified for small batches
Phase 3 — Traceability linking (US <-> ATS/ATP/ATR <-> TCs) Single inline — requires aggregated state of all created entities
Phase 3 — Final report / reports (COVERAGE-MATRIX-<scope>.md, PRIORITIZATION-<scope>.md) Single inline — synthesis lives in the orchestrator
  • Concurrency cap = 10 subagents for Parallel TC creation. Jira and Xray APIs both rate-limit at ~10 writes/sec sustained; fanning out wider triggers 429 responses. If a module has >100 TCs, batches per subagent must be larger than 10 each (cap is on subagent count, not chunk size).
  • Error protocol: On any subagent failure: STOP, report the partial success state (which TCs landed, which failed, with their issue keys / errors), present retry / skip / abort options. Do NOT auto-fix nor auto-rollback. See .agents/skills/agentic-qa-core/references/orchestration-doctrine.md.

Readiness Preflight Gate (MANDATORY — runs before Phase -1)

Full doctrine: agentic-qa-core/references/preflight-gate.md. Runs FIRST, before the resume check and before the TMS-modality gate. Two laws: (1) args-as-answers — the scope (module / ticket / bug / ad-hoc) and any stated modality are provided args; ask only the gaps. (2) probe, don't assume. Surface gaps + REDs as ONE AskUserQuestion checklist; self-fix with approval + explanation; STOP on any blocking RED. This skill documents already-validated behavior in the TMS — it does NOT execute against a live system, so its gate centers on TMS write capability. Generic baseline (env resolution, test-user creds, secret/restart handling, the two laws, output contract) is inherited from the reference §3.1 — not repeated here. Below is only this skill's specific capability delta.

Capability Need Why here
Issue-tracker ([ISSUE_TRACKER_TOOL]) REQUIRED TC / ATP / ATR creation, linking, transitions. Load /acli; validate via bun run jira:check.
TMS modality + [TMS_TOOL] REQUIRED The whole Phase 0 gate. jira-xray → /xray-cli loaded + XRAY_* creds set + Xray issue types present. jira-native → /acli covers it. Resolve before Phase 1; ask only if all auto-checks fail.
Source repos readable OPTIONAL Phase 1 source-code validation reads backend/frontend code, not a running env — no live-env or DB/API/browser probe needed.

Active env, test-user creds, DBHub, OpenAPI/API_TOKEN, Playwright, resend and kata-manifest.json (an automation-only concern owned by /test-automation) are N/A — documentation never hits a live system nor writes test code. After the gate clears (all REQUIRED GREEN), continue to Phase -1 below.


Phase -1 — Session resume check (MANDATORY, inline)

Runs BEFORE Phase 0 (TMS modality gate). Compute prospective <scope> from invocation: <JIRA-KEY> for ticket/bug scope, <module-slug> for module scope, <YYYY-MM-DD>-adhoc for ad-hoc. Then:

  1. Check .session/test-documentation/<scope>/progress.md.
  2. If it does NOT exist → proceed to Phase 0 (TMS modality).
  3. If it DOES exist:
    • Read plan.md (chosen scope, TMS modality, TC list, ROI verdicts).
    • Read tail of progress.md (last completed phase + next planned phase).
    • Surface to the user: scope, TMS modality, last completed phase, next phase, any pending TC creation chunks that did not finish (the most common interruption point — Phase 3 parallel bulk create capped at 10 subagents).
    • Offer resume / restart / abort. On restart, archive to .session/.archive/<YYYY-MM-DD>-test-documentation-<scope>-aborted/ first.

Critical resume case: Phase 3 parallel bulk create interrupted mid-batch. The progress.md records per-chunk completion (one entry per Parallel subagent return), so resume skips already-created TCs by reading the chunks marked completed and dispatching only the missing chunks. This is why per-subagent checkpoint matters (see Phase 3 below).


Phase 0 — Resolve TMS modality (mandatory gate)

Every project runs in one of two modalities. Resolve it before Phase 1. The same ATP/ATR/TC concepts have different containers in each mode.

The question you MUST answer first

Does this project have Xray installed and licensed on Jira?
  A. Yes -> Modality jira-xray
  B. No  -> Modality jira-native (no Xray)

How to resolve it without asking (in order)

  1. Check AGENTS.md for {{TMS_CLI}}. Value bun xray (or any Xray CLI) -> Modality jira-xray. Value is unset, acli-only, or {{TMS_CLI}} matches {{ISSUE_TRACKER_CLI}} -> Modality jira-native.
  2. If AGENTS.md is ambiguous, look for a .context/master-test-plan.md line such as TMS: Xray on Jira or TMS: Jira native.
  3. If still ambiguous, list existing issue types in the project via [ISSUE_TRACKER_TOOL] List issue types. If the project exposes Test Plan / Test Execution / Test Set / Pre-Condition, it is Modality jira-xray. Otherwise Modality jira-native.
  4. Only if all three checks fail, ask the user the question above. Do NOT ask by default — autoresolve first.

What changes per modality

Artifact Modality jira-xray Modality jira-native
ATP (Acceptance Test Plan) Test Plan issue titled ATP: {STORY-KEY}: {story title}, parented to the QA Master Test Plan epic, linked to the US Same Test Plan issue by excellence (native Jira work type, Xray-independent); falls back to the Story {{jira.acceptance_test_plan}} field (then a ## Acceptance Test Plan (ATP) comment) only when the Test Plan work type is absent from the instance.
ATR (Acceptance Test Results) Test Execution issue with Test Runs per TC, Environment, Begin/End Date, titled ATR: {STORY-KEY}: Story Testing, parented to the QA Test Artifacts epic Same Test Execution issue by excellence; falls back to the Story {{jira.acceptance_test_results}} field (then a ## Acceptance Test Results (ATR) comment) only when the Test Execution work type is absent from the instance.
TC (Test Case) Xray Test issue (type Manual / Cucumber / Generic) Jira-native Test issue type (or Task with custom type), Description carries the full TC template
ATS (Acceptance Test Set) Test Set issue titled ATS: {US_ID}: {story title}, mandatory per Story — holds ALL the Story's TCs (membership Xray-internal), linked to the US (is tested by — the coverage-panel link) Same Test Set issue when the work type is present — membership expressed as TC→ATS issue links (the "membership is never a link" rule is xray-only). Work type absent → no ATS: direct TC→Story links (cascade last resort)
TS / Precondition / Test Plan First-class Xray issue types (TS: feature Set is optional grouping) Same native work types when present in the instance; absent → use labels + Epic grouping
Result sync CI imports JUnit/Cucumber via [TMS_TOOL] Import Results -> Test Runs auto-update Custom script updates Test Status field on each TC + comment with build context
CLI tag [TMS_TOOL] resolves to bun xray or equivalent [TMS_TOOL] falls through to [ISSUE_TRACKER_TOOL] (acli / Jira MCP)

Resolve {{TC_CREATION_STAGE}} in the same gate

The modality says which TMS tool is live; .agents/project.yaml → testing.tc_creation_stage (referenced as {{TC_CREATION_STAGE}}) says whether this skill CREATES the Candidate/Manual Test items or REFINES + promotes ones /sprint-testing already made. Read it here, alongside the modality; unset or unrecognized → auto. The knob's full table + rationale is sprint-testing/SKILL.md §"Which stage creates the TCs" — that section is authoritative, this one only consumes it.

Resolved value Phase 3's verb for a Candidate / Manual scenario
auto (default) jira-xray → promote + enrich an existing sprint Test · jira-native → create the Test here
sprint-testing promote + enrich in BOTH modalities — the items already exist; creating a second one duplicates the repository
test-documentation create in BOTH modalities — no sprint items exist to promote

Whatever the verb, the canonical title rule is identical: a created TC is titled to the form, a promoted TC has its title re-derived and verified first (§"Title on promotion"). If the verb says promote but no sprint Test exists for a scenario (a Story tested before the knob was set, or a scenario derived only now), fall back to create for that scenario and note it in progress.md — never skip the TC.

Persist the decision

Once resolved, save the modality and the resolved {{TC_CREATION_STAGE}} into .session/test-documentation/<scope>/plan.md §Inputs (canonical session record) and ALSO mirror to test-session-memory.md for the ticket (if one exists, for per-ticket sub-agent context). Treat as sticky: do not re-resolve mid-session. If you detect drift (e.g. [TMS_TOOL] suddenly fails), stop and ask the user before re-resolving.

Reference implementations:

  • Modality jira-xray concepts + Xray REST/GraphQL/CLI -> references/xray-platform.md
  • Modality jira-native project setup (Test issue type, Screen Scheme, custom fields) -> references/jira-setup.md
  • Both modes side-by-side (field mapping, workflow, Description template) -> references/jira-test-management.md

When to use each scope

Pick the scope based on the input, not the output. All four scopes share the same Analyze -> Prioritize -> Document pipeline; only the input source and defaults differ.

Scope Input Typical volume Default labels Notes
Module-driven A module of the system explored end-to-end 20-100+ scenarios regression, e2e or integration Batch of TCs grouped under the Regression Epic. Most scenarios will be Deferred.
Ticket-driven A QA Approved user story from a sprint 3-8 scenarios regression, plus the test type Output of a sprint-testing session. ATP/ATR created per US.
Bug-driven A closed bug with a verified fix 0-2 scenarios regression, automation-candidate (usually) Run the Bug-driven decision (below). Not every bug qualifies; if it does, reuse the existing failed Test or create one — an important bug must end with a Test. ROI biased up: "it failed once, it can fail again."
Ad-hoc / Exploratory New scenarios found in exploratory testing 1-10 scenarios regression Apply the 3 Phase-0 questions harshly; ad-hoc scenarios are often one-time validations.

If the user gives you a story ID, use ticket-driven. If they give you a bug ID, use bug-driven. If they give you a module name or a session output, use module- or ad-hoc accordingly.

Bug-driven decision — "an important bug must have a test" (GOLDEN RULE)

Not every bug becomes a regression Test — a one-time typo in a stable area is treated like a failed test (the fix was verified in sprint-testing) and Deferred. But run the same analysis + prioritization you'd run on any scenario; if the bug IS regression-worthy, it MUST end with a Test that covers it, in BOTH modalities. Where there is an important bug, there must be a test that catches it again — this rule is worth gold.

1. Is this Bug/Defect a regression candidate?  (apply Phase-0 filter + ROI; the prior-bug rule biases up)
   NO  -> No new Test. Treat as a failed test: fix already verified in sprint-testing -> log as Deferred. Done.
   YES -> step 2.

2. Was the bug found FROM an existing, already-executed Test?  (a Test that ran and failed — jira-native OR xray)
   YES -> REUSE that existing Test for the bug's retest + regression. It already lives in the test set;
          ensure it is linked to the bug (`tests / is tested by`) and promoted into regression. Do NOT duplicate.
   NO  -> CREATE + design the corresponding Test for the bug's retest.
          jira-native: new `Test` issue.  jira-xray: new Xray `Test` (+ plugin-appropriate Test Plan / Test Set linking).
          Link to the bug via `tests / is tested by`.

This overrides sprint-testing's "the bug is the test case" — that phrase covers only the immediate in-sprint retest, NOT future regression. The retest reproduces+verifies the fix now; this rule decides whether a persistent Test must exist (reuse or create) so the bug can never silently return.

Scope handoff to /test-automation. The Candidate TCs produced here flow downstream to /test-automation, which re-scopes them into its own 3 planning scopes: module-driven → Module (Macro), ticket-driven → Ticket (Medium), bug-driven → Regression-driven (Micro). ad-hoc / exploratory Candidates have no 1:1 automation scope — they enter under whichever fits (a module batch, or regression-driven for a single TC). Manual and Deferred verdicts are terminal and never reach automation.

After scope confirmation, write .session/test-documentation/<scope>/plan.md per agentic-qa-core/references/session-management.md §6 — Goal (scope + TMS modality + expected TC count), Inputs (PBI references, ATP source, prior bugs), Approach (per-phase dispatch table above), Phase breakdown (Phase 1 Analyze → Phase 2 Prioritize → Phase 3 TC creation with chunk count → Traceability → Final report), Risks, Verification checklist (all TCs created with traceability + both reports written + the Deferred list mirrored to Jira), Cross-references (.context/PBI/epics/EPIC-<KEY>-<slug>/stories/STORY-<KEY>-<slug>/test-cases/*.md per-TC files + .context/reports/COVERAGE-MATRIX-<scope>.md + .context/reports/PRIORITIZATION-<scope>.md — filenames per §"Reports — fixed filenames"). Append ## Phase -1 — Session resume check — <ts> with status: completed, next: Phase 0 — Resolve TMS modality to progress.md.


Phase 1 — Analyze

Inputs you must gather

Source What to read Why
User Story / Epic Description, ACs, comments, linked issues Scenario identification, risk signals
Closed bugs linked to the story Summary, root cause, fix area Prior-bug prioritization rule
Exploratory session notes Validated scenarios, observations Reuse nomenclature already used
Existing ATP (if present) — modality-aware (see §Phase 0) jira-native: Story field {{jira.acceptance_test_plan}} → synced .context/PBI/epics/EPIC-<KEY>-<slug>/stories/STORY-<KEY>-<slug>/acceptance-test-plan.md (read-only Jira cache — sync via bun run jira:sync-issues get <STORY> --include-comments). jira-xray: Test Plan issue description → bun run jira:sync-issues get <ATP_KEY> → test-plans/ATP-<KEY>-<slug>.md (acronym prefix = conforming ladder title; a non-conforming title keeps the legacy TESTPLAN- / TESTEXEC- / RETESTEXEC- prefix); per-TC run state via [TMS_TOOL] (xray-cli) Scenarios may already exist — do not reinvent
Existing ATR (if present) — modality-aware (see §Phase 0) jira-native: Story field {{jira.acceptance_test_results}} → synced acceptance-test-results.md (same jira:sync-issues get <STORY> --include-comments). jira-xray: Test Execution issue description → bun run jira:sync-issues get <ATR_KEY> → test-executions/ATR-<KEY>-<slug>.md (sync supports these types); per-TC run results via [TMS_TOOL] (xray-cli) Prior run results — do not re-execute what is already recorded
Implementation plan / source code Actual files, APIs, test IDs Validate design matches implementation before documenting
.context/business/domain-glossary.md (if present) Canonical entity + process names, anti-glossary banned terms Vocabulary reference for TC names, steps, and preconditions — terms must match the glossary

Separate real scenarios from cross-cutting characteristics

Cross-cutting traits are validated inside every test, not as separate TCs.

Cross-cutting (NOT a TC) Validated by
Mobile responsive Running each test in mobile viewport
XSS prevention Using special-character test data inside tests
Performance Timing assertions inside tests
Accessibility A11y assertions inside UI tests
API contract Response schema checks inside API tests
Generic "error handling" Specific negative-path scenarios

Deferral ≠ omission. Moving a cross-cutting trait out of per-feature TC scope is an explicit handoff, not a silent drop. Each row must land somewhere: woven into a TC's data/assertions (the table above) OR owned by a named app-level suite (XSS / perf / a11y regression suite). If no such suite exists for a trait the feature genuinely exposes, file the gap (Deferred TC or a note in the ATR) — never let it evaporate.

A real scenario is a user flow: clear business objective, concrete precondition + action, verifiable outcome. The TC name uses the should form — {US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]; reserve Validate <feature> for the GROUPING layer (Test Set summary / describe()), never for the individual case.

Source-code validation (mandatory before documenting)

The design in the ATP was written before code existed. Before creating any TC:

  1. Open the implementation plan (if any) and list the files it touches.
  2. Grep the actual code for data-testid=, route handlers, API paths, and text formats.
  3. Compare the ATP's assumptions against what the code does. If they diverge, correct the TC design and add a Refinement Notes section.

Common discrepancies to check for:

  • An API the ATP assumed exists turns out to be SSR/direct DB.
  • UI text format in the ATP ("based on N reviews") vs reality ("(N reviews)").
  • Hardcoded IDs in the ATP vs variable pattern required in TMS.

Skipping this step is the single most common cause of invalid automated tests later.

Sprint TCs are DRAFTS — refine them, do not inherit them

Whatever /sprint-testing Stage 1 left behind — Xray Test items, or ATP outlines under jira-native — was written to run once, this sprint, by the person who wrote it. It is an input to this phase, never its output. Before any of it enters the regression repository, refine it:

What Stage 1 produced What this phase must do
Title re-derive it to the canonical form (§"Title on promotion") — a sprint title reads for the tester who was there, a regression title reads for whoever runs it in six months
Steps / Gherkin raise to repeatable detail: no "as before", no implicit state, no step that only makes sense right after the previous test. Parameterize same-behavior data variants into one Scenario Outline (doctrine §Part 2.5) rather than leaving N near-duplicates
Preconditions make them explicit and buildable from a cold environment. A sprint test may have relied on data the tester happened to have; a regression test may not
Variables replace every hardcoded id / email / UUID captured during the sprint with {variable} + a Variables table saying how to obtain it
Scope a sprint TC that turned out to cover two (precondition, action) pairs splits here; two that cover the same pair merge (TC identity rule below)

Record what changed. A refined TC carries a short Refinement Notes line in its Description (same section the source-code validation above writes to) naming what was tightened and why — otherwise a reviewer cannot tell a refined TC from an untouched sprint artifact.

Under jira-native with {{TC_CREATION_STAGE}} = auto there is no sprint Test item to refine — the outline in the ATP plays that role, and the same table applies to it.

TC identity rule (load-bearing)

A TC is defined by Precondition + Action. All expected results from the same (precondition, action) pair belong to the same TC, not separate TCs.

Same TC:                                    Different TCs:
  Precondition: valid credentials             Precondition: valid credentials     -> TC-A
  Action:       submit login                  Precondition: locked account        -> TC-B
  Assertions:   redirect + token + welcome    Precondition: invalid credentials   -> TC-C
                (all one TC)                  (all same action, but preconditions differ)

Splitting one (precondition, action) into N "check panel A / check panel B / check panel C" TCs is a textbook anti-pattern. One TC, multiple assertions.

Technique-driven TC derivation (1:N — full canon: agentic-qa-core/references/test-design-doctrine.md)

One AC yields multiple TCs by default. Derive them by the AC's shape, then let the TC-identity rule above merge only within a partition — never across partitions, boundaries, or states. Reduce an AC to a single TC only with a written trivially atomic justification.

Trigger in the AC Technique TCs produced
Any input (always) Equivalence Partitioning same-output inputs → one parameterized TC (Scenario Outline + Examples); different-output inputs → separate TCs
A range / limit / length / date-window Boundary Value Analysis TCs at min-1·min·min+1 … max-1·max·max+1 + zero / empty / null / overflow (EP alone misses off-by-one)
A status / lifecycle field State-Transition one TC per valid transition + per invalid transition
2+ interacting conditions Decision Table enumerate combos, collapse equivalents, one TC per surviving rule
3+ combinable factors Pairwise all-pairs TC set (log the reduction)

These are candidate scenarios derived by technique — not yet TMS work items. ROI (Phase 2) then decides which become persistent regression TCs (Candidate → automated, Manual → manual) and which stay Deferred (recorded in the prioritization report, NOT created in the TMS). Deriving widely is free; persisting is ROI-gated — most scenarios are Deferred. You document a scenario because it will be re-run, never to hit a count.

Improvement bridge (agentic-qa-core/references/defect-management-doctrine.md Part 1). When a test-beyond-AC exposes a gap because the AC was under-specified or absent — the system violated no defined criterion — the right artifact is an Improvement issue (filed per the doctrine, or delegated to /sprint-testing), NOT a regression TC and NOT a silent widening of the Story's ACs. Track the proposal as an Improvement; do not edit the Story's AC set after the fact.


Phase 2 — Prioritize (ROI)

Every scenario passes three gates in order. Fail any gate -> Deferred.

Phase 0: The three filter questions

  1. Does it protect against FUTURE regressions? If the bug was a one-time typo in a stable area, the answer is no. Defer.
  2. Are there PRIOR bugs in this area? Yes -> prioritize even with moderate ROI ("it failed once, it can fail again").
  3. Is it an APP-level concern or a FEATURE-level concern? XSS / a11y / performance / responsive are APP-level suites, not per-feature TCs. Defer from this scope.

ROI formula (load-bearing)

ROI = (Frequency x Impact x Stability) / (Effort x Dependencies) / 10

The trailing / 10 is a normalization constant, not a sixth factor. The raw quotient over 1-5 factors spans 0.04 .. 125, while every threshold and worked example in this skill reads on a 0.004 .. 12.5 scale — so divide by 10, always. A neutral all-3s scenario lands at (3x3x3)/(3x3)/10 = 0.3 → Deferred, which is the intended default (most scenarios should be Deferred).

Each factor is scored 1-5 independently:

Factor 1 2 3 4 5
Frequency (how often run) Yearly / rarely Every release Every sprint Daily Every PR / commit
Impact (if it fails) Cosmetic Minor inconvenience Degrades UX Blocks feature Revenue / core business
Stability (of the flow) Very volatile Unstable Moderate Stable, minor changes Unchanged for months
Effort (to automate) Trivial Low (hours) Moderate (1-2 days) High (several days) Very high (week+)
Dependencies None 1-2 simple 3-4 5+ Complex externals

Note: Effort and Dependencies are divisors — higher score = worse. The other three are multipliers.

Component value bonus

If a TC is reusable across multiple E2E flows:

Component Value = Base ROI x (1 + 0.2 x N)

where N = number of E2E flows that consume it. A moderate-ROI atomic like authenticateSuccessfully can cross out of the defer bands purely through reuse. N is a qualitative estimate, capped at 3 (max multiplier x1.6): no tool counts call-sites, so read it off the ATP / feature map and record the estimate in the ROI comment. Full rule: references/tms-conventions.md §9 "Component value bonus".

Three outcomes (load-bearing)

Every scenario ends in exactly one of these buckets. There is no fourth.

Outcome Triggers it Where it goes next TMS status flow
Candidate ROI > 3.0, OR (ROI 1.5-3.0 AND prior bug), OR critical happy path Feeds test-automation skill Draft -> In Design -> READY -> In Review -> Candidate
Manual ROI 0.5-1.5 AND not automatable (human judgment, visual inspection), OR explicitly manual-only Terminal: manual regression suite Draft -> In Design -> READY -> MANUAL
Deferred ROI < 0.5, OR failed Phase-0 filter, OR one-time validation, OR it matched neither row above (Deferred is the default bucket: ROI under 3.0 with no prior bug and no critical-path justification lands here) Terminal: not in regression. Can be revisited if system changes jira-native: do not create a TC in the TMS — document as Deferred in .context/reports/PRIORITIZATION-<scope>.md AND in the mirrored Jira comment (§"Reports — fixed filenames"; the local file is [LOCAL], the comment is the durable record). jira-xray: the sprint Test (created in /sprint-testing Stage 1) is not promoted to the Regression Test Plan (RTP) — it stays as a sprint execution artifact, not deleted.

Band authority: the three outcomes above are the TMS-action collapse of the 5-band table in references/tms-conventions.md §9 ("ROI decision thresholds (strict)"). That table is the authority on band boundaries and it resolves the middle bands explicitly — 1.5-3.0 is "Case by case: prior bug? critical flow? If no, defer", 0.5-1.5 is "Probably defer: include only if prior bug". Read it whenever a score falls between 0.5 and 3.0.

Rule of thumb: if more than 50% of candidates end up Candidate or Manual, re-apply Phase 0 more strictly. Most scenarios should be Deferred.

Modality changes the verb in Phase 3, not the verdict here. The ROI verdicts (Candidate / Manual / Deferred) are identical in both modalities. What differs is the action: jira-native — Phase 3 creates Test work items for Candidate + Manual only (Deferred is report-only). jira-xray — the Test work items already exist from /sprint-testing Stage 1 (Xray's Test is the execution unit); Phase 3 selects + promotes the Candidate/Manual ones into the RTP (re-derived canonical title, then label regression-candidate) and enriches them (rich Gherkin, parameterization, edge elaboration — the "specify much more" pass). Deferred sprint Tests are left as-is, unpromoted. See sprint-testing/SKILL.md §"TC creation timing (modality-aware)".


Phase 3 — Document in TMS

Preflight: Regression Epic

Every documented TC must have a parent Regression Epic (single test repository for the project).

This Regression Epic IS the QA Test Repository process epic (agentic-qa-core/references/defect-management-doctrine.md Part 4). Resolve it found-or-created by the configured name qa.qa_epics.test_repository_epic.name ("QA Test Repository"); on absence create it once, write the test-repository strategy into its description, and cache its key into .agents/project.yaml qa.qa_epics.test_repository_epic.key. It is a QA process epic — never a product/dev epic, never unparented. Per the three-axis model this parent says only "which QA bucket tracks the Test"; the Test's product area travels on components (Part 3) and its Story coverage travels on the issue link (Part 4) — never on this parent.

Prerequisite: Load /acli skill before executing commands below.

[ISSUE_TRACKER_TOOL] Search Issues:
  project: {{PROJECT_KEY}}
  query: type = Epic AND summary ~ "QA Test Repository"      # resolve by configured name qa.qa_epics.test_repository_epic.name

If none exists, ask the user before creating one with name QA Test Repository (the value of qa.qa_epics.test_repository_epic.name) and labels QA-Artifact, regression (QA-Artifact is the mandatory identity label on every QA process epic).

Preflight: Test Sets — ATS (mandatory per-Story) + TS (optional feature grouping)

Two Set altitudes — do not conflate:

  • ATS (Acceptance Test Set) — ATS: {US_ID}: {story title} — mandatory per Story, even when the Story has a single TC. Holds ALL the Story's TCs and anchors coverage: the ATS→Story is tested by link is what fills the Xray coverage panel (ATP/ATR links do NOT — live-verified 2026-08-21, see .session/artifact-ladder-refactor/scoping.md §Verificación). Parented to QA Test Artifacts; components inherited from the Story — mandatory (the components exemption applies to feature-level TS: only). Phase 3 is Set-first: find-or-create the Story's ATS, add the TCs to it, THEN derive the ATP's and the Execution's test lists from the ATS membership.
  • TS (feature-level Test Set) — TS: <EPIC_KEY|module>: Validate <feature> — optional grouping (smoke / regression / feature suite), 1:1 with the Epic/module. components optional here — a feature Set spans modules by design. Ask the user before creating one (mirror the Regression-Epic ask-before-create rule — creation is otherwise async/manual; the AI only creates it lazily here when a promotion needs it). Only promoted, regression-worthy Tests (Candidate/Manual) are added to the feature TS — Deferred sprint Tests are NOT added.

Containers: Regression Epic = repository umbrella · ATS = per-Story coverage set · TS = optional feature grouping · Test Plan = execution/regression scope.

  • Modality jira-xray: resolve/create Sets via [TMS_TOOL]; TC∈Set membership is Xray-internal (GraphQL) — NEVER a Jira issue link. The ATS→Story is tested by edge IS a Jira issue link and is mandatory.
  • Modality jira-native: instance has the Test Set work type → create the ATS item and express membership as TC→ATS issue links (explicit carve-out: the "membership is never a link" rule is xray-only) plus the ATS→Story link. Work type absent → no ATS: link each TC to the Story directly (is tested by — the cascade's last-resort path) and keep feature grouping via the Regression Epic + a feature/Epic label (e.g. epic-<EPIC_KEY> or the feature slug).

Entity model: ATP / ATR / ATS / TC

Five entities. Traceability model: the Story links to its ATS, ATP and ATR ("is tested by"), but only one of those edges carries coverage — the ATS→Story link is what fills the Xray coverage panel; the ATP→Story and ATR→Story links are administrative traceability and contribute ZERO coverage (live-verified 2026-08-21, .session/artifact-ladder-refactor/scoping.md §Verificación). The ATP "designs" the TCs (TC "is designed by" ATP) and the ATR "executes" the TCs (TC "is executed by" ATR). A direct TC→Story link is the cascade's LAST RESORT (used when no ATS exists — e.g. jira-native without the Test Set work type), not the default: TCs normally aggregate through the ATS. The defect is a TC with NO path to its Story, not the direct link itself. Full doctrine: agentic-qa-core/references/traceability-linking.md + references/tms-architecture.md.

Entity Created Naming Main content
US (Story) Pre-existing {{PROJECT_KEY}}-{n} The requirement
ATP Content pre-sprint in {{jira.acceptance_test_plan}} (shift-left); the Test Plan ITEM by /sprint-testing Stage 1 from that field — or by this phase (find-or-create) when running module-driven and no Story ATP item exists ATP: {STORY-KEY}: {story title} Test Analysis + AC-to-TC coverage
ATR Stage 1 (or now, if missing) ATR: {STORY-KEY}: Story Testing Test Report + execution results
TC Stage 4 (this phase) {US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>] Precondition + Action + Expected
ATS Stage 1 (or now, find-or-create — MANDATORY per Story) ATS: {US_ID}: {story title} ALL the Story's TCs (even one). Coverage anchor: ATS→Story is tested by fills the coverage panel. Components inherited from the Story (mandatory). Parent: QA Test Artifacts.
TS (optional) Lazily in Stage 4 if a promotion needs it (ask first); else pre-existing (async) TS: {EPIC-KEY\|module}: Validate {feature} OPTIONAL feature-level grouping (1:1 Epic) of promoted regression Tests — smoke/regression suites. Components optional: a feature Set spans modules by design. Native without the work type: replaced by a feature/Epic label, no entity.

Read references/tms-architecture.md when creating ATP/ATR/TC for a ticket, checking required links, or validating that a story is fully documented.

Linking order (always — Set-first)

1. Find-or-create the Story's ATS -> link to US (Story "is tested by" ATS — the coverage-panel link)
2. Find-or-create ATP (pre-sprint content lives in {{jira.acceptance_test_plan}}; the item usually
   exists from /sprint-testing Stage 1 — create here only when module-driven and no ATP item exists)
   -> link to US (Story "is tested by" ATP — administrative, no coverage)
3. Create ATR -> link to US (Story "is tested by" ATR — administrative, no coverage)
4. Update ATP -> link to ATR (bidirectional plan/results)
5. For each TC:
     Create TC -> add to the ATS (jira-xray: Xray-internal membership; jira-native with the
                  Test Set work type: TC->ATS issue link)
               -> link to ATP (TC "is designed by" ATP) + ATR (TC "is executed by" ATR)
     # Do NOT link the TC directly to the Story when an ATS exists — TCs aggregate via the ATS.
     # Direct TC->Story is the cascade's LAST RESORT (no ATS available — e.g. jira-native
     # without the Test Set work type). The defect is a TC with NO path, not the direct link.
     # AC coverage is recorded in the ATP's AC-to-TC matrix, not as a Story<->TC issuelink.
6. Derive the ATP's and the ATR's test lists FROM the ATS membership (Set-first: the ATS holds
   ALL the Story's TCs; Plan and Execution consume that list).
7. For each PROMOTED (regression-worthy) TC:
     FIRST -> re-derive the canonical title and, if the live summary differs, rewrite it
              ([ISSUE_TRACKER_TOOL] Update Issue — summary is a Jira field, not an Xray one),
              THEN verify it matches before anything else touches the TC (see §"Title on
              promotion"). A wrongly-titled TC must never reach the RTP or carry the label.
     jira-xray  -> [TMS_TOOL] add TC to the OPTIONAL feature TS (resolve/create per Preflight) + [TMS_TOOL] add to the RTP
                   + [ISSUE_TRACKER_TOOL] label `regression-candidate` (labels are a Jira field; xray-cli has no update-label for existing Tests)
     jira-native -> [ISSUE_TRACKER_TOOL] apply the feature/Epic label (or add to a feature TS item when the work type exists)

Every artifact this skill CREATES carries assignee = the authenticated session user, set at create time — the RTP, the ATS, the optional feature TS, every Test, every Precondition (agentic-qa-core/references/artifact-lifecycle.md §2). This is load-bearing, not bookkeeping: Xray refuses membership edits on a Test Plan the caller does not own, so an unassigned RTP cannot have promoted Tests added to it, and the failure surfaces as a mid-flow blocker long after the Plan exists. If the find-or-create step RETURNS an artifact owned by someone else, do not reassign it silently — ask the user first.

Plan and Set lifecycle (agentic-qa-core/references/artifact-lifecycle.md §1):

Artifact Born This skill moves it to Then
RTP (Regression Test Plan) {{jira.status.test_plan.planning}} {{jira.status.test_plan.ready}} via {{jira.transition.test_plan.designed}} on the first promotion stays ready forever — the RTP is long-lived. NEVER fire {{jira.transition.test_plan.complete}} on it
ATS (per-Story Set) {{jira.status.test_set.designing}} closed by /sprint-testing Reporting, not here —
TS (optional feature Set) {{jira.status.test_set.designing}} stays designing for the life of the feature {{jira.transition.test_set.done}} only when its Epic closes
Precondition {{jira.status.precondition.active}} nothing — the workflow has no transition out of active stays active; that is correct, not a gap

Per-op tool resolution + the Gherkin-enrichment CLI gap: references/jira-test-management.md §"Stage-4 promote + enrich — tool resolution map". Load /xray-cli for command syntax — never hardcode it here.

Creating a TC before the ATS, ATP and ATR exist leaves orphaned references. Fix any broken links with references/tms-architecture.md §Traceability Rules.

Where candidates go — the RTP handoff

The question this answers is the one a team asks the first time Phase 2 produces a verdict: those Candidates have to end up in a general regression suite — what is the procedure? It is this, and it is the last thing Phase 3 does:

  1. Find-or-create the project's Regression Test Plan (RTP) — one long-lived Test Plan item per project, titled RTP: {PROJECT_KEY|module}: Regression Test Plan, parented to the QA Master Test Plan epic, assignee = self at create time (§the lifecycle table above — Xray refuses membership edits on a Plan the caller does not own, so an unassigned RTP cannot accept promotions later). Ask the user before creating it, same as the Regression Epic.
  2. Every Candidate TC lands in it. Title re-derived and verified (§"Title on promotion"), then regression-candidate applied, then added to the RTP. Manual TCs go to the manual regression suite — the same RTP under jira-xray, distinguished by the manual-only label and the {{jira.status.test_case.manual}} status, since a manual regression pass runs from the same plan. Deferred TCs never enter it; that is the whole point of the verdict.
  3. The RTP moves to {{jira.status.test_plan.ready}} on the first promotion and stays there — a regression run never completes the plan it ran from.
  4. Downstream consumers read it from there, not from this session. /test-automation picks up the TCs at {{jira.status.test_case.candidate}} carrying regression-candidate; /regression-testing executes the RTP's membership and writes its STR against it. Neither reads .context/reports/ — both of those files are [LOCAL] and exist only on this machine. If a Candidate is not in the RTP, it does not exist downstream.

Grouping Candidates into e2e regression flows

A regression suite is not a bag of independent TCs: the same authentication or checkout TC is consumed by several end-to-end journeys, and that reuse is what the Component value bonus (§Phase 2) already scores. Group the Candidates explicitly, at the same altitude /test-automation will:

  • One group = one e2e flow (a user journey that a spec file will run end to end), named for the journey, not the module: Checkout — guest purchase, not Checkout tests.
  • A TC reused by 2+ flows is an atomic component — in KATA terms it becomes a Steps module rather than being duplicated per flow (test-automation/references/kata-architecture.md). Name it once, list it under every flow that consumes it, and let the N in the Component value bonus equal that count.
  • Record the grouping in TWO places: (a) the RTP description, as a ## Regression flows section listing each flow with its member TC keys — this is the durable copy, readable by /test-automation and /regression-testing without this session; (b) COVERAGE-MATRIX-<scope>.md, as a flow column beside the AC → scenario → TC → verdict grid, for the local read.
  • A Candidate that belongs to no flow is a smell, not a category. Either it is an atomic component (say which flows consume it) or its journey was never identified — surface it rather than filing it under a catch-all.

Creating TCs — modality matrix

TMS stack Manual test Automation-candidate test
Xray on Jira Two-step (Xray Cloud silently drops inline steps): (1) [TMS_TOOL] Create Test: type=Manual without inline steps, (2) [TMS_TOOL] Add Test Step per step (optionally verify with [TMS_TOOL] Get Test), then [ISSUE_TRACKER_TOOL] Update Issue to paste the complete Description template [TMS_TOOL] Create Test: type=Cucumber, gherkin=<high-quality gherkin> then [ISSUE_TRACKER_TOOL] Update Issue with the Description template
Native Jira (no Xray) [ISSUE_TRACKER_TOOL] Create Issue: issueType=Test, description=<steps table> [ISSUE_TRACKER_TOOL] Create Issue: issueType=Test, description=<gherkin in Description>

Always populate Description with the full TC template (Related Story, Priority, ROI, Prior bugs, Test Design gherkin/steps, Variables table, Implementation Code table, Architecture, Available Test IDs, Preconditions, Expected Results). Read references/jira-test-management.md when choosing between Xray and native Jira, or when the Description must be filled.

Dispatch: Use the dispatch defined in §Subagent Dispatch Strategy: Parallel when N > 10 TCs (cap = 10 subagents), inline otherwise. The full briefings for both Modality jira-xray (via /xray-cli) and Modality jira-native (via /acli) live in references/tms-architecture.md §"Parallel TC creation". The sharding rule, error protocol, and aggregation contract are documented there. The serial flow below is the canonical procedure each subagent runs internally for its assigned chunk.

High-quality Gherkin (for Candidates)

@{priority} @regression @automation-candidate @{US_ID}
Scenario Outline: should <outcome> <connector> <condition>
  """
  Bugs covered: BUG-1, BUG-2
  Related Story: {US_ID}
  """

  # === PRECONDITIONS (tester / script builds them) ===
  Given <entity> exists with <identifier>
  And <entity> has <quantity> <elements> where <quantity> <condition>

  # === ACTION ===
  When the user navigates to "<route>"
  And the user <main_action>

  # === VALIDATIONS ===
  Then <ui_element> is displayed with format "<expected_format>"
  And <additional_validation>

  # === EQUIVALENT PARTITIONS ===
  Examples: Happy path
    | ... |
  Examples: Edge case
    | ... |

Rules that always apply:

  • Variables, never hardcoded data: {mentor_id} not 550e8400-.... Include a Variables table with how to obtain each.
  • Tags always include: priority (@critical|@high|@medium|@low), suite (@regression, @smoke if critical path), automation flag (@automation-candidate), traceability (@{US_ID}).
  • Structured comments: # === PRECONDITIONS ===, # === ACTION ===, # === VALIDATIONS ===, # === EQUIVALENT PARTITIONS ===.
  • Docstring with metadata: related story, bugs covered, ROI.

Workflow transitions

**Substrate refe

Files (agentic-qa-boilerplate)
  • evals
    • evals.json 1.8 KB
      {
        "evals": [
          {
            "name": "should-trigger-roi-analysis",
            "prompt": "Analyze the tests for ticket UPEX-300 and decide which ones should be automated. Use the ROI framework.",
            "expected_behavior": "Activates test-documentation. Calculates ROI per scenario and classifies each as Candidate, Manual, or Deferred.",
            "category": "positive"
          },
          {
            "name": "should-trigger-create-tcs-in-jira",
            "prompt": "Create the test cases in Jira for the scenarios we designed. Use Gherkin format.",
            "expected_behavior": "Activates test-documentation. Creates TCs in Jira via [TMS_TOOL] with the correct naming convention and Gherkin in the Description.",
            "category": "positive"
          },
          {
            "name": "should-trigger-fix-traceability",
            "prompt": "The traceability links between the ATP and the TCs are broken. Fix them.",
            "expected_behavior": "Activates test-documentation. Identifies and repairs ATP/ATR/TC links in the TMS per the linking order rules.",
            "category": "positive"
          },
          {
            "name": "should-not-trigger-manual-exploration",
            "prompt": "Manually test the login flow in staging.",
            "expected_behavior": "Does NOT activate test-documentation. Should route to sprint-testing.",
            "category": "negative"
          },
          {
            "name": "should-not-trigger-writing-test-code",
            "prompt": "Write the automated test code for the login flow.",
            "expected_behavior": "Does NOT activate test-documentation. Should route to test-automation.",
            "category": "negative"
          },
          {
            "name": "should-not-trigger-commit-conventions",
            "prompt": "What are the naming conventions for commits?",
            "expected_behavior": "Does NOT activate test-documentation. No skill needed; the answer is in AGENTS.md.",
            "category": "negative"
          }
        ]
      }
      
  • references
    • jira-setup.md 10 KB
      # Jira TMS Setup Reference
      
      Configuration checklist for Jira projects used by this boilerplate. Covers both modalities:
      
      - **Modality jira-xray** — Xray install + project config. Primary content lives in this doc's §2.
      - **Modality jira-native (no Xray)** — custom fields + Test issue type configuration so that ATP/ATR as Story customfields and Test issues work with the skills. Primary content in §3.
      
      Which modality is active is resolved by `test-documentation/SKILL.md` §Phase 0. Run the applicable section(s) once per project as part of `/project-discovery` onboarding.
      
      Skills that depend on this setup: `sprint-testing`, `test-documentation`, `regression-testing`, `fix-traceability`.
      
      > **Before publishing rich-text bodies to Jira fields configured below** (ATP, ATR, Test Case body, Test Plan body), read `../../agentic-qa-core/references/jira-publishing-gotchas.md` — covers the two ADF conversion gotchas (`md-to-adf` mark collision + MCP batched custom-field rejection) that silently fail HTTP 400.
      
      ---
      
      ## 1. Pre-setup checklist (both modalities)
      
      - [ ] Jira Cloud or DC instance
      - [ ] Jira Administrator permissions (required for Issue Type Scheme, Screens, Workflows, Custom fields)
      - [ ] Modules list known (e.g. Auth, Checkout, Billing)
      - [ ] Regression Epic created (or let `test-documentation` create it on first run)
      - [ ] `.env` populated with `ATLASSIAN_EMAIL`, `ATLASSIAN_API_TOKEN`, and `JIRA_PROJECT_KEY`
      - [ ] `.agents/project.yaml` -> `issue_tracker.atlassian_url` set (the site host is NOT in `.env`; verify with `bun run --silent jira:url`)
      - [ ] `/acli` skill loaded (primary) or Atlassian MCP available (fallback)
      
      ---
      
      ## 2. Modality jira-xray — Xray setup (only if Xray is licensed)
      
      ### 2.1 Install Xray
      
      **Jira Cloud**: Settings (gear) → Apps → Find new apps → "Xray Test Management" → Get it now.
      **Jira DC**: Settings → Manage apps → Find new apps → "Xray Test Management for Jira" → Install.
      
      Activate license. Verify new issue types appear: `Test`, `Test Set`, `Test Plan`, `Test Execution`, `Pre-Condition`.
      
      ### 2.2 Add Xray issue types to the project
      
      Project Settings → Issue types → Actions → Add Xray Issue Types. Select all five.
      
      ### 2.3 Configure Requirement Coverage
      
      Project Settings → Apps → Xray Settings → Test Coverage. Select `Story` and `Epic` as coverable issue types. Optionally add `Bug`. Save.
      
      Global: Settings → Apps → Xray → Issue Type Mapping → Requirement Issue Types = `Story, Epic`, Defect Issue Types = `Bug`.
      
      ### 2.4 Test workflow
      
      Settings → Issues → Workflows → Add workflow: `Test Lifecycle Workflow`. States and transitions from `tms-conventions.md` §5 (workflow state machine). Assign via Workflow Scheme to Test issue type.
      
      ### 2.5 API credentials
      
      Settings → Apps → Xray → API Keys → Create API Key. Save `Client ID` + `Client Secret` into `.env`:
      
      ```
      XRAY_CLIENT_ID=...
      XRAY_CLIENT_SECRET=...
      # NOTE: the Atlassian site HOST is not a .env variable. It lives in
      # .agents/project.yaml -> issue_tracker.atlassian_url (`bun run agents:setup`).
      ATLASSIAN_EMAIL=you@example.com
      ATLASSIAN_API_TOKEN=...
      JIRA_PROJECT_KEY=PROJ
      XRAY_TEST_PLAN_KEY=PROJ-300      # optional
      XRAY_ENVIRONMENT=staging         # optional
      ```
      
      Verify with `[TMS_TOOL] auth_status()` (load `/xray-cli` skill — it owns the literal command shape).
      
      Full reference: `xray-platform.md`.
      
      ---
      
      ## 3. Modality jira-native — setup (no Xray)
      
      Jira-native mode puts ATP/ATR on the Story itself via custom fields, and represents TCs as a custom `Test` issue type. The skills need three things configured before they can run: the `Test` issue type, an ATP customfield, and an ATR customfield.
      
      ### 3.1 Create a custom `Test` issue type
      
      Settings → Issues → Issue types → Add issue type. Name: `Test`. Description: "Manual or automated test case".
      
      Add it to the project's Issue Type Scheme: Project Settings → Issue types → Add existing → `Test`.
      
      ### 3.2 Configure fields on the Test issue type
      
      The skill writes into these fields when creating TCs. Add them to the Test issue type's **Create / Edit / View** screens via a Screen Scheme.
      
      | Field | Type | Required | Purpose |
      |-------|------|----------|---------|
      | Summary | Text (default) | Yes | TC title per naming convention |
      | Description | Rich text (default) | Yes | Full TC template (Gherkin or steps + metadata) |
      | Priority | Select (default) | Yes | Critical / High / Medium / Low |
      | Labels | Multi-select (default) | Yes | `regression`, `smoke`, `e2e`, `automation-candidate`, etc. |
      | Components | Multi-select (default) | Yes | Affected product module — mandatory on every Test (defect-management doctrine Part 3) |
      | Epic Link | Epic picker | Yes | Points to the Regression Epic |
      | Test Status | Select (custom) | Yes | `NOT RUN` / `PASSED` / `FAILED` / `BLOCKED` — the Execution Status per `tms-conventions.md` §IQL |
      | Workflow Status | (workflow) | Yes | `Draft` / `In Design` / `READY` / … / `AUTOMATED` / `DEPRECATED` |
      | Automation Candidate | Checkbox (custom) | Yes | Boolean flag — redundant with labels but easier to filter |
      | Linked Issues | Links (default) | Yes | "is tested by" → Story, "is blocked by" → Bug |
      
      Create the two custom fields:
      
      1. Settings → Issues → Custom fields → Add field → Select List (single choice) → Name `Test Status` → Options `NOT RUN`, `PASSED`, `FAILED`, `BLOCKED`. Associate with the Test issue type.
      2. Add field → Checkbox → Name `Automation Candidate`. Associate with the Test issue type.
      
      After creating the fields, run `bun run jira:sync-fields --force` so the numeric IDs Jira assigned are auto-discovered into `.agents/jira-fields.json` under their slug. Reference them from skills via `{{jira.<slug>}}` — never paste the raw `customfield_NNNNN` ID into a skill or doc (workspace-portability rule, AGENTS.md §1.12).
      
      ### 3.3 Configure ATP and ATR custom fields on the Story issue type
      
      These fields hold the Test Analysis and Test Report bodies for every Story.
      
      | Field | Type | On issue types | Purpose |
      |-------|------|----------------|---------|
      | Acceptance Test Plan | Long text (multi-line) | Story, Epic | Holds the full Test Analysis body written in Stage 1 Planning |
      | Acceptance Test Results | Long text (multi-line) | Story, Epic | Holds the full Test Report body written in Stage 3 Reporting |
      
      Steps:
      
      1. Settings → Issues → Custom fields → Add field → **Paragraph (supports rich text)** → Name `Acceptance Test Plan` → Associate with the Story (and Epic if the project uses epic-level ATPs).
      2. Add field → **Paragraph** → Name `Acceptance Test Results` → same associations.
      3. After running `bun run jira:sync-fields`, IDs are auto-discovered into `.agents/jira-fields.json` (slugs `acceptance_test_plan` for ATP and `acceptance_test_results` for ATR). Both are referenced via `{{jira.<slug>}}` from the skills.
      4. Add both fields to the Story's **View Screen** (Settings → Issues → Screens). Leave them off the Create screen (the skill populates them later, not the PM).
      5. Optionally add them to the Story's Edit Screen so PO/Dev can see them inline.
      
      Record the IDs in `.context/master-test-plan.md`:
      
      ```markdown
      ## TMS Modality: Jira-native
      
      | Artifact | Custom field ID |
      |----------|-----------------|
      | ATP      | {{jira.acceptance_test_plan}}
      | ATR      | {{jira.acceptance_test_results}}
      | Test Status (on Test) | {{jira.test_status}}
      | Automation Candidate (on Test) | {{jira.to_be_automated}}
      ```
      
      ### 3.4 Bug custom fields (UPEX reference, both modalities)
      
      The `sprint-testing/references/reporting-templates.md` §1.10 table lists the UPEX Galaxy workspace defaults for bug custom fields (Severity, Root Cause, Error Type, etc.). Re-create the equivalent fields in the project, or accept the skill's graceful degradation (bugs land with missing fields and a warning).
      
      ### 3.5 Issue links
      
      Add link types if missing: Settings → Issue linking → ensure `tests / is tested by` and `blocks / is blocked by` are present.
      
      ### 3.6 API access
      
      `/acli` skill uses an API token. Obtain one from `id.atlassian.com/manage-profile/security/api-tokens`. Populate `.env`:
      
      ```
      # NOTE: the Atlassian site HOST is not a .env variable. It lives in
      # .agents/project.yaml -> issue_tracker.atlassian_url (`bun run agents:setup`).
      ATLASSIAN_EMAIL=you@example.com
      ATLASSIAN_API_TOKEN=...
      JIRA_PROJECT_KEY=PROJ
      ```
      
      Verify with `[ISSUE_TRACKER_TOOL] auth_status()` (load `/acli` skill — it owns the literal command shape).
      
      ### 3.7 Workflow
      
      Same state machine as Modality jira-xray (`tms-conventions.md` §5). Build a Jira workflow with these states and attach it to the Test issue type via a Workflow Scheme.
      
      ---
      
      ## 4. Per-project configuration output
      
      At the end of setup, `.context/master-test-plan.md` must contain a TMS section that answers these five questions unambiguously:
      
      ```markdown
      ## TMS
      
      - Modality: Xray on Jira | Jira-native
      - TMS CLI: bun xray | acli (only)
      - Regression Epic: {KEY} — {title}
      - Custom field IDs (Modality jira-native only):
          ATP: {{jira.acceptance_test_plan}}
          ATR: {{jira.acceptance_test_results}}
          Test Status: {{jira.test_status}}
          Automation Candidate: {{jira.to_be_automated}}
      - Link types available: is tested by / tests, is blocked by / blocks
      ```
      
      If any answer is missing, the skills fall back to the Phase 0 resolution probes (`AGENTS.md` → `master-test-plan.md` → list issue types → ask the user). Making the answers explicit here is what saves every future session from re-asking.
      
      ---
      
      ## 5. Validation checklist
      
      After setup, both modalities should pass:
      
      - [ ] Can create a `Test` issue in the project (Modality jira-native) / all five Xray types appear (Modality jira-xray).
      - [ ] `[ISSUE_TRACKER_TOOL] List issue types` shows `Test` + (if A) `Test Plan`, `Test Execution`, `Test Set`, `Pre-Condition`.
      - [ ] Can update a Story's `{{jira.acceptance_test_plan}}` and `{{jira.acceptance_test_results}}` with a test string (Modality jira-native). Both fields persist and display.
      - [ ] `is tested by` link can be created from a Test to a Story.
      - [ ] Workflow transition `start design` is available on a Test in `Draft`.
      - [ ] `/xray-cli` (A) or `/acli` (B) authenticates against the project key.
      
    • jira-test-management.md 38.1 KB
      # Jira Test Management Reference
      
      How to create and maintain Test / ATP / ATR artifacts in Jira — both with and without Xray. Covers mode selection, field mapping, workflow, Description templates, and Jira-specific gotchas.
      
      ### Related references
      
      - `xray-platform.md` — dense Xray concepts (issue types, RTM, data flow, API). Load when in **Modality jira-xray** and you need the *what* of Xray.
      - `jira-setup.md` — one-time Jira / Xray project configuration checklist (issue types, custom fields, workflows, API access). Load before the first skill run on a new project.
      - `tms-architecture.md` §Container per modality — which issue type ATP/ATR/TC map to in each modality.
      - `tms-conventions.md` §IQL — Test Status (Workflow) vs Execution Status (Run) distinction.
      - `../../agentic-qa-core/references/jira-publishing-gotchas.md` — ADF rich-text publishing gotchas. **Read before publishing any Test / ATP / ATR body to Jira rich-text fields** — covers the two ADF conversion gotchas (`md-to-adf` mark collision + MCP batched custom-field rejection) that silently fail HTTP 400.
      
      ### Tool tags used here
      
      - `[ISSUE_TRACKER_TOOL]` — generic Jira operations (create issue, update fields, link issues, transition, search). Primary = `/acli` skill. Resolves per AGENTS.md Tool Resolution.
      - `[TMS_TOOL]` — Xray-specific operations (create Test, create Test Execution, import results). Only resolvable in **Modality jira-xray** via `/xray-cli`. In Modality jira-native falls through to `[ISSUE_TRACKER_TOOL]`.
      
      ---
      
      ## 1. Which mode: Jira Native or Jira + Xray?
      
      Pick once per project. Do not mix in the same repository.
      
      | Question | Jira Native | Jira + Xray |
      |----------|-------------|-------------|
      | Is Xray installed and licensed in the Jira instance? | No | Yes |
      | Do you need structured step-by-step execution with pass/fail per step? | No (Description only) | Yes |
      | Do you need native JUnit/Cucumber import from CI/CD? | No (custom script) | Yes |
      | Do you need Test Plan / Test Set / Test Execution hierarchies? | No | Yes |
      | Is the team comfortable with Jira issue types only? | Yes | Either |
      
      Decision rule:
      
      - **Xray present** -> use Jira + Xray. The extra issue types (Test Plan, Test Set, Test Execution) are worth the complexity.
      - **Xray absent** -> use Jira Native. Build a custom `Test` issue type and treat Description as the source of truth.
      
      Once chosen, stay consistent. The TC prefix is always the User Story key regardless of mode (see §5).
      
      ---
      
      ## 2. Entity models per mode
      
      ### Jira Native (no Xray)
      
      Core entities: User Story (pre-existing), Test (custom issue type), Epic (Regression Epic — parent of all Tests), plus the ATS when the Test Set work type exists.
      
      ```
      User Story (STORY-123)
          | is tested by
      ATS (ATS: STORY-123: <story title>)        <- when the Test Set work type exists
          | is tested by (TC->ATS membership links)
      Test (TEST-456)
          | parent epic
      Regression Epic (EPIC-001 — "QA Test Repository")
      
      # Without the Test Set work type: no ATS — the Test links to the Story directly
      # (is tested by, the cascade's last resort).
      ```
      
      **Items over fields (by excellence)**: ATP and ATR are real Jira issues even without Xray — a `Test Plan` issue titled `ATP: {STORY-KEY}: {story title}` (parented to **QA Master Test Plan**) and a `Test Execution` issue titled `ATR: {STORY-KEY}: Story Testing` (parented to **QA Test Artifacts**). These are native Jira work types; create them as such. ATP/ATR as Story custom fields (or a Task standing in) is a **degraded fallback ONLY**, used when those work types are unavailable in the instance. The same rule covers the **ATS**: Test Set work type present → an `ATS: {US_ID}: {story title}` item (parent **QA Test Artifacts**, components inherited from the Story) with membership as **TC→ATS issue links** (carve-out: the "membership is never a link" rule is xray-only); work type absent → no ATS, direct TC→Story links. Linking order (Set-first): (1) find-or-create the ATS and link to US (the coverage link); (2) find-or-create ATP and link to US; (3) create ATR and link to US; (4) update ATP to link to ATR; (5) for each TC, add to the ATS (or link to US directly when no ATS) + link to ATP + ATR + AC; (6) derive the Plan/Execution test lists from the ATS membership.
      
      ### Jira + Xray
      
      Five extra issue types available:
      
      | Issue Type | Purpose | Relationship |
      |------------|---------|--------------|
      | **Test** | Individual test case (Manual, Cucumber, Generic). | Child of Regression Epic; linked to User Story. |
      | **Test Plan** | Groups Tests for a release / sprint. Contains Tests. | Planning-level container. |
      | **Test Set** | Two altitudes: the per-Story **ATS** (`ATS: {US_ID}: {story title}` — MANDATORY, holds ALL the Story's TCs, its `is tested by` link to the Story fills the coverage panel) and the OPTIONAL feature-level `TS:` grouping (smoke, regression, domain). | Membership is Xray-internal state (managed via `/xray-cli`, read via `bun xray test enrich`), NEVER a Jira issue link and NEVER the TC prefix (prefix is always `{US_ID}`). |
      | **Test Execution** | One execution instance. Generates Test Runs. | Executes a Test Plan or ad-hoc set of Tests. |
      | **Precondition** | Reusable prerequisite for Tests. | Referenced by Tests that share setup. |
      
      Typical hierarchy (parents are the QA-process Epics — Plans under **QA Master Test Plan**; Executions / Sets / Preconditions under **QA Test Artifacts**; Tests under **QA Test Repository**):
      
      ```
      QA Master Test Plan (Epic)
          |
          +-- Test Plan: STP: Sprint#50: Payments hardening   (sprint plan)
          +-- Test Plan: ATP: PROJ-101: Pay with credit card  (story plan)
                  |
                  +-- (Test Set / Tests grouped via links)
      
      QA Test Artifacts (Epic)
          |
          +-- Test Set: ATS: PROJ-101: Pay with credit card       (MANDATORY per Story —
          |       +-- Test (TC1, TC2, ...)         ALL the Story's TCs; membership = Xray-internal,
          |                                        prefix stays {US_ID}; ATS->Story link = coverage)
          +-- Test Set: TS: Checkout: Validate checkout v2        (OPTIONAL feature grouping)
          |       +-- Test (TC3, TC4, ...)
          +-- Test Execution: ATR: PROJ-101: Story Testing
                  +-- Test Run per Test (PASS / FAIL / TODO)
      
      QA Test Repository (Epic)
          +-- Test (TC1, TC2, TC3, TC4, ...)       (the permanent test repository)
      ```
      
      ---
      
      ## 3. Custom Test issue type — Jira Native configuration
      
      Create a **Test** issue type in the Jira project with the following fields. This is admin work; do it once per project.
      
      | Field | Type | Purpose |
      |-------|------|---------|
      | Summary | Text | TC title per naming convention. |
      | Description | Long text (rich text) | Full TC documentation (Gherkin or steps + metadata). |
      | Test Status | Select list | `Draft`, `In Design`, `READY`, `MANUAL`, `In Review`, `Candidate`, `In Automation`, `Pull Request`, `AUTOMATED`, `DEPRECATED` — exact names from `.agents/jira-workflows.json` (`work_types.test_case`), the authoritative source. |
      | Automation Candidate | Checkbox | Redundant with labels but easier to filter in JQL. |
      | Priority | Select list | `Critical`, `High`, `Medium`, `Low`. |
      | Labels | Multi-select | `regression`, `smoke`, `e2e`, `integration`, `automation-candidate`, `manual-only`, etc. |
      | Components | Multi-select | Affected product module — **mandatory** on every Test (defect-management doctrine Part 3), not a filtering nicety. |
      | Epic Link | Epic picker | Must point to the Regression Epic. |
      | Linked Issues | Links | "tests" / "is tested by" -> User Story; "is blocked by" -> Bug (optional). |
      
      Jira admin caveats:
      
      - Add the Test issue type to the project's **Issue Type Scheme**, otherwise the type won't be selectable.
      - Add the above fields to the Test **Screen Scheme** (Create / Edit / View screens). Missing fields silently disappear.
      - Make `Test Status` available on the Edit screen so transitions do not require a separate workflow config.
      - If the project uses a shared workflow scheme, add a Test-specific workflow with the states from §6; otherwise new Tests inherit the default workflow.
      
      ---
      
      ## 4. Field mapping — Jira Native vs Xray
      
      Same concept, different storage. Use this when translating a TC design into actual TMS fields.
      
      | TC concept | Jira Native | Xray |
      |------------|-------------|------|
      | Title | `Summary` | `Summary` |
      | Steps (preconditions, action, expected) | Inside `Description` — as a table or Gherkin block | Xray `Test Steps` field (one row per step) OR `Cucumber` Gherkin field OR `Generic` text field |
      | Test type (Manual / Cucumber / Generic) | No native concept — infer from Description format | Xray `Test Type` field: Manual / Cucumber / Generic |
      | Preconditions | Inline at top of Description | Xray `Precondition` issue type, associated to the Test (Xray-internal association managed via `/xray-cli`, surfaced into the synced cache by its `test enrich` command — NOT a Jira issue link) |
      | Expected Result | Per-row column in Description steps table, or Gherkin `Then` | Per-step `Expected Result` column in Test Steps field |
      | Priority | `Priority` field | `Priority` field |
      | Labels | `Labels` field | `Labels` field |
      | Components | `Components` field | `Components` field |
      | Trace to User Story | Via the ATS when the Test Set work type exists (TC→ATS links + ATS→Story "is tested by"); direct TC→Story "is tested by" only without it (cascade last resort) | Via the ATS (Xray-internal membership + the ATS→Story "is tested by" link — the one that fills the coverage panel), plus TC "is designed by" ATP + "is executed by" ATR (administrative). No direct TC → Story link while the ATS exists. |
      | Execution result | `Test Status` custom field | Xray `Test Run` inside a Test Execution |
      
      Xray additionally exposes:
      
      - `Test Repository` folder (flat path under the project) — not required if all Tests are under a single Regression Epic.
      - `Test Sets` associated to the Test (Xray-internal membership — not a Jira issue link).
      - `Pre-Conditions` (dedicated issue type) — reusable across Tests (association is Xray-internal too).
      
      ---
      
      ## 5. Naming — prefix is always the User Story key
      
      The TC naming convention is identical in every modality — the prefix is **ALWAYS the User Story key** (`{US_ID}`), never the Test Set ID.
      
      ```
      {US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]
      ```
      
      | Modality | `PREFIX` |
      |------|----------|
      | **Jira Native** | User Story ID (`PROJ-101`) |
      | **Jira + Xray with Test Sets** | User Story ID (`PROJ-101`) — Test Set membership is Xray-internal, not a prefix |
      | **Jira + Xray without Test Sets** | User Story ID (`PROJ-101`) |
      
      The prefix never changes with mode. Under Modality jira-xray, Test Set association is **Xray-internal membership** (managed via `/xray-cli` add-to-set, read via `bun xray test enrich`) — NEVER a Jira issue link and NEVER in the TC title — so JQL by Story key stays reliable across the whole project. Jira-native carve-out: with a Test Set work type present, membership IS a TC→ATS issue link (still never in the TC title).
      
      Related naming — the unified planning-ladder grammar `{ACRONYM}: {scope-id}: {descriptor}` (full table: `tms-conventions.md` §3):
      
      | Entity | Jira work type | Pattern | Example |
      |--------|----------------|---------|---------|
      | Story Test Plan (ATP) | Test Plan | `ATP: {STORY-KEY}: {story title}` | `ATP: PROJ-101: Pay with credit card` |
      | Story Test Execution (ATR) | Test Execution | `ATR: {STORY-KEY}: Story Testing` | `ATR: PROJ-101: Story Testing` |
      | Feature Test Plan (FTP) | Test Plan | `FTP: {EPIC-KEY}: {feature}` | `FTP: PROJ-42: Checkout & Payments` |
      | Sprint Test Plan (STP) | Test Plan | `STP: Sprint#{N}: {objective}` | `STP: Sprint#50: Payments hardening` |
      | Sprint Test Results (STR) | Test Execution | `STR: Sprint#{N}: Regression Testing` | `STR: Sprint#50: Regression Testing` |
      | Acceptance Test Set (ATS — per-Story, **mandatory**) | Test Set | `ATS: {US_ID}: {story title}` | `ATS: PROJ-101: Pay with credit card` |
      | Test Set (TS — feature-level, **optional**) | Test Set | `TS: {EPIC-KEY\|module}: Validate {feature}` | `TS: PROJ-42: Validate credit card payment` |
      | ReTesting (bug fix) | Test Execution | `ReTest: {BUG-KEY}: {summary}` | `ReTest: PROJ-202: Wrong error on invalid password` |
      | Precondition | Precondition | `{COMPONENT}: {required state}` (no ladder acronym) | `Payment: Authenticated user with a saved card` |
      
      > **Precondition**: the **title states the required state**; the **content holds the setup steps** — kept distinct.
      
      ---
      
      ## 6. Workflow — states and transitions
      
      > **Substrate reference**: state and transition names below match the canonical UPEX Jira workflow declared in `.agents/jira-workflows.json` (see `.agents/jira-required.yaml` `work_types.test_case`). Skills resolve names via `{{jira.status.test_case.<slug>}}` and `{{jira.transition.test_case.<slug>}}`. Refresh with `bun run jira:sync-workflows` if your project renames any state.
      
      Both modes use the same state machine. Xray does not impose its own workflow; it respects the Jira workflow attached to the Test issue type.
      
      ```
      Draft
        | start design
      In Design <--+ back
        | ready to run
      READY
        +-- for manual -----------> MANUAL (manual regression branch)
        +-- automation review ----> In Review
                                       | approve to automate
                                       v
                                     Candidate
                                       | start automation
                                       v
                                     In Automation
                                       | create PR
                                       v
                                     Pull Request
                                       | merged
                                       v
                                     AUTOMATED (terminal-automated)
      ```
      
      Rules:
      
      - Status and transition names above come from `.agents/jira-workflows.json` (`work_types.test_case`) — the authoritative source. If a name is not in that file it does not exist in the instance.
      - Never skip a state. If a TC was wrongly moved to `READY`, transition back with `back` to `In Design`, don't edit the status field directly.
      - `MANUAL` and `AUTOMATED` are both terminal for day-to-day work. A MANUAL TC can re-enter `In Review`, `Candidate`, or `AUTOMATED` later if ROI changes.
      - `DEPRECATED` is reachable from any state and can be recovered to `Draft` (`recover`).
      
      ---
      
      ## 7. Description template (full TC documentation)
      
      The Description is load-bearing in Jira Native mode and still recommended in Xray mode (Xray's structured Steps field is minimal). Paste this after the Test is created with `[ISSUE_TRACKER_TOOL] Update Issue`. **Format per `../../acli/references/adf-authoring-style.md`**: prefer a table for the step → expected grid (more scannable than bullet lists), nested lists for multi-level preconditions, and a panel for a critical assumption — richness with purpose, not decoration.
      
      ```
      ## Related Story
      {{PROJECT_KEY}}-{n} — <Story Title>
      
      ## Priority / ROI
      - Priority: {Critical|High|Medium|Low}
      - ROI score: {number} (Frequency x Impact x Stability / Effort x Dependencies / 10 — the `/ 10` normalization, see `tms-conventions.md` §9)
      - Outcome: {Candidate|Manual|Deferred}
      
      ## Prior bugs covered
      - {BUG-ID} — <one-line summary>
      - (none) if first time
      
      ## Test Design
      
      ### Preconditions
      - <precondition 1>
      - <precondition 2>
      
      ### Action
      <single sentence: what the user does>
      
      ### Expected Results (assertions of this TC — same precondition+action)
      - <assertion 1>
      - <assertion 2>
      - <assertion 3>
      
      ### Gherkin (if Candidate)
      ```gherkin
      @{priority} @regression @automation-candidate @{US_ID}
      Scenario Outline: should <outcome> <connector> <condition>
        Given <entity> exists with <identifier>
        When the user <main_action>
        Then <assertion 1>
        And <assertion 2>
      
        Examples:
          | var1 | var2 |
          | ...  | ...  |
      ```
      
      ## Variables
      | Variable | How to obtain |
      |----------|---------------|
      | `{mentor_id}` | `SELECT id FROM mentors WHERE active = true LIMIT 1` |
      | `{session_token}` | From login response `.token` |
      
      ## Implementation Code (filled by test-automation)
      | Layer | File |
      |-------|------|
      | API component | `tests/components/api/MentorsApi.ts` |
      | UI component | `tests/components/ui/MentorsPage.ts` |
      | Test file | `tests/e2e/mentorsListing.test.ts` |
      | Fixture | `tests/components/TestFixture.ts` |
      
      ## Architecture
      {E2E / Integration / UI-only} — follows KATA layers.
      
      ## Available Test IDs (UI)
      - `[data-testid="mentor-list"]`
      - `[data-testid="mentor-card"]`
      - `[data-testid="review-count"]`
      
      ## Refinement Notes
      <Discrepancies found when grep'ing the code against the ATP. Empty if none.>
      ```
      
      Notes:
      
      - **Variables, not hardcoded data**: always `{mentor_id}`, never a literal UUID. The Variables table explains how to produce real values at runtime.
      - **Implementation Code** table is empty at documentation time; `test-automation` fills it after the code lands.
      - **Refinement Notes** captures ATP-vs-code discrepancies (routes renamed, text format changes, missing APIs). Mandatory when such discrepancies were found during source-code validation.
      
      ---
      
      ## 8. Creating a TC — pseudocode by mode
      
      > **Parenting + components (binding — `../../agentic-qa-core/references/defect-management-doctrine.md`).** In **both** modalities every created `Test` (TC) parents to the **QA Test Repository process epic** — found-or-created by `qa.qa_epics.test_repository_epic.name` (**"QA Test Repository"**), never a product/dev epic, never unparented (Part 4). Its `components` field is **mandatory** and names the affected product module (Part 3). Per the three-axis model the **parent says only "which QA bucket"**, while `components` carries the product area and the **Story coverage travels on the link graph** (the ATS→Story `is tested by` link — the coverage-panel link — with membership Xray-internal under jira-xray and TC→ATS links under jira-native; direct TC→Story `is tested by` only as the cascade's last resort when no ATS exists) — never on the parent. The `epic:` / `REGRESSION_EPIC_KEY` referenced in the blocks below resolves to this QA Test Repository epic.
      
      ### Jira Native (Manual or Gherkin)
      
      > **Prerequisite**: Load `/acli` skill before executing commands below.
      
      ```
      [ISSUE_TRACKER_TOOL] Create Issue:
        project: {{PROJECT_KEY}}
        issueType: Test
        summary: {per TC naming convention}
        priority: {Critical|High|Medium|Low}
        labels: [regression, {smoke?}, {automation-candidate|manual-only}, {e2e|integration}]
        components: [{module}]
        epic: {REGRESSION_EPIC_KEY}
      
      # With a Test Set work type (ATS exists — jira-native carve-out: membership IS a link):
      [ISSUE_TRACKER_TOOL] Link Issues:
        from: {TEST_KEY}
        to:   {ATS_KEY}
        linkType: {{jira.link_types.test.name}}   # ATS is tested by Test (TC -> ATS membership)
      
      # Without a Test Set work type (no ATS): direct Story link — cascade last resort
      [ISSUE_TRACKER_TOOL] Link Issues:
        from: {TEST_KEY}
        to:   {STORY_KEY}
        linkType: {{jira.link_types.test.name}}   # Story is tested by Test
      
      [ISSUE_TRACKER_TOOL] Update Issue:
        issue: {TEST_KEY}
        description: {full Description template from §7}
      
      [ISSUE_TRACKER_TOOL] Transition Issue:
        issue: {TEST_KEY}
        transition: start design
        # later: ready to run
        # later: for manual OR automation review -> approve to automate
      ```
      
      > Resolve the `test` link type by slug only and verify direction after creation — see `agentic-qa-core/references/traceability-linking.md` (§2 slug resolution, §4 directionality + mandatory verification).
      
      ### Jira + Xray (Cucumber)
      
      > **Prerequisite**: Load `/xray-cli` and `/acli` skills before executing commands below.
      
      ```
      [TMS_TOOL] Create Test:
        project: {{PROJECT_KEY}}
        type: Cucumber
        title: {per TC naming convention}
        gherkin: {from §7 Gherkin block}
        labels: [regression, automation-candidate, {scope}, {priority}]
        components: [{module}]          # mandatory — affected product module
      
      [ISSUE_TRACKER_TOOL] Update Issue:
        issue: {TEST_KEY}
        description: {full Description template from §7}
      
      # Set-first membership: add the TC to the Story's ATS. Test ↔ Test Set membership is
      # NOT a Jira issuelink under jira-xray — do NOT create it via [ISSUE_TRACKER_TOOL]
      # link create. It is Xray-internal state managed via the /xray-cli skill (add-to-set).
      # See traceability-linking.md §9. Coverage flows through the ATS->Story `is tested by`
      # link (already created in the Set-first preflight — the coverage-panel link).
      [TMS_TOOL] Add Test to Test Set:   # /xray-cli only — Xray-internal, NOT a Jira link
        test:    {TEST_KEY}
        testSet: {ATS_KEY}               # the Story's ATS; the optional feature TS: is a second add
      
      # Administrative edges: ATP designs TC, ATR executes TC. The Test is NOT linked to the
      # Story directly while the ATS exists — direct TC->Story is the cascade's last resort.
      [ISSUE_TRACKER_TOOL] Link Issues:
        from: {ATP_KEY}
        to:   {TEST_KEY}
        linkType: {{jira.link_types.test_design.name}}    # ATP designs TC / TC is designed by ATP
      [ISSUE_TRACKER_TOOL] Link Issues:
        from: {ATR_KEY}
        to:   {TEST_KEY}
        linkType: {{jira.link_types.test_execute.name}}   # ATR executes TC / TC is executed by ATR
      
      [ISSUE_TRACKER_TOOL] Transition Issue:
        issue: {TEST_KEY}
        transition: start design
      ```
      
      > Resolve the `test_design` / `test_execute` link types by slug only and verify direction after creation — see `agentic-qa-core/references/traceability-linking.md` (§2 slug resolution, §3 catalog, §4 directionality, §9 Test Set caveat). **Confirmed: the Xray-internal attach (`plan add-tests` / `exec add-tests`) creates NO Jira links** — the `designs`/`executes` Jira edges MUST be created explicitly via `[ISSUE_TRACKER_TOOL]` (`/acli`), SEPARATE from the Xray-internal membership. Membership goes through `/xray-cli`, never `acli link create`; the Jira links go through `/acli`, never `/xray-cli`. Do NOT link the Test to the Story directly under Modality jira-xray — coverage flows through the ATS→Story link (a direct TC→Story link is the cascade's last resort, for setups with no ATS).
      
      ### Stage-4 promote + enrich — tool resolution map (Modality jira-xray)
      
      When `/test-documentation` Stage 4 promotes a sprint Xray Test into regression, resolve each operation to its tool via pseudocode — load `/xray-cli` for the exact command (HOW lives there, never here). The `[TMS_TOOL]` operations below were verified to exist before this map was written:
      
      | Promote / enrich op | Resolves via | Coverage |
      |---|---|---|
      | Re-derive + rewrite the canonical **title** on an existing Test (runs FIRST) | `[ISSUE_TRACKER_TOOL]` (the summary is a Jira field) | ✓ (no `[TMS_TOOL]` summary update exists; route via the issue tracker) |
      | Add Test → feature **Test Set** | `[TMS_TOOL]` (Xray-internal membership) | ✓ supported |
      | Add Test → **Regression Test Plan (RTP)** | `[TMS_TOOL]` | ✓ supported |
      | Label `regression-candidate` on an **existing** Test | `[ISSUE_TRACKER_TOOL]` (labels are a Jira field) | ✓ (no `[TMS_TOOL]` update-label for an existing Test; route via the issue tracker) |
      | Enrich **Manual** Test steps | `[TMS_TOOL]` | ✓ supported |
      | Enrich **Gherkin** / definition / change **test type** on an existing Test | `[TMS_TOOL]` | ✓ supported (update-gherkin / update-definition / update-type) |
      
      **Implication for our flow**: every Stage-4 promote + enrich op now resolves through a tool — `[TMS_TOOL]` for Test Set / Test Plan membership, step + Gherkin/definition/type enrichment; `[ISSUE_TRACKER_TOOL]` for the title and the labels on an existing Test. You may either author rich Gherkin at creation time or enrich an existing sprint Test in place during promotion — both paths are supported. Load `/xray-cli` for the exact command.
      
      **Order is load-bearing**: the title row runs **before** membership and label. A sprint Test carries a sprint-era summary; promoting it untouched is what leaves the RTP full of non-canonical titles. Re-derive → rewrite if different → verify → then add to the RTP and apply `regression-candidate`. Full rule: `SKILL.md` §"Title on promotion".
      
      ### Jira + Xray (Manual)
      
      > **Prerequisite**: Load `/xray-cli` and `/acli` skills before executing commands below.
      
      ```
      [TMS_TOOL] Create Test:
        project: {{PROJECT_KEY}}
        type: Manual
        title: {per TC naming convention}
        components: [{module}]          # mandatory — affected product module
        # NO inline steps here — Xray Cloud drops steps passed on create. Create the
        # Test bare, then add each step in a follow-up call.
      
      [TMS_TOOL] Add Step:           # one call per step (Xray Cloud only registers steps added post-create)
        test:   {TEST_KEY}
        action: {step 1}
        data:   {step 1 data}
        result: {expected step 1}
      # ...repeat [TMS_TOOL] Add Step for each remaining step...
      
      [ISSUE_TRACKER_TOOL] Update Issue:
        issue: {TEST_KEY}
        description: {full Description template from §7}
      
      # Set-first membership: add the TC to the Story's ATS (Xray-internal, NOT a Jira link).
      # Coverage flows through the ATS->Story `is tested by` link.
      [TMS_TOOL] Add Test to Test Set:
        test:    {TEST_KEY}
        testSet: {ATS_KEY}
      
      # Administrative edges: ATP designs TC, ATR executes TC. The Test is NOT linked to the
      # Story directly while the ATS exists (direct TC->Story = cascade last resort). The
      # Xray-internal attach creates NO Jira links — these designs/executes edges are
      # SEPARATE and created explicitly here via /acli. (Slug + direction:
      # traceability-linking.md §3/§4/§9.)
      [ISSUE_TRACKER_TOOL] Link Issues:
        from: {ATP_KEY}
        to:   {TEST_KEY}
        linkType: {{jira.link_types.test_design.name}}    # ATP designs TC
      [ISSUE_TRACKER_TOOL] Link Issues:
        from: {ATR_KEY}
        to:   {TEST_KEY}
        linkType: {{jira.link_types.test_execute.name}}   # ATR executes TC
      ```
      
      The two-call pattern (Xray + Update Issue) is mandatory in Xray mode. Skipping the Update Issue call leaves a TC with no readable documentation in Jira — only the bare Xray Steps field. Manual-step gotcha: Xray Cloud drops any steps passed on `Create Test`; always create the Test without steps, then add each step via `[TMS_TOOL] Add Step` (one call per step).
      
      ---
      
      ## 9. Test Plan / Test Set / Test Execution
      
      > **Items over fields**: `Test Plan`, `Test Set`, and `Test Execution` are native Jira work types — create them as real issues in both modalities (Xray only adds the run/coverage engine and result import on top). Titles follow the unified ladder grammar (§5). Parent Plans to **QA Master Test Plan**; parent Executions / Sets / Preconditions to **QA Test Artifacts**.
      >
      > **Prerequisite**: Load `/xray-cli` and `/acli` skills before executing the commands in this section. `Test Plan` and `Test Set` are created via `[ISSUE_TRACKER_TOOL]` (acli); `Test Execution` result imports use `[TMS_TOOL]` (xray-cli).
      
      ### Test Plan
      
      Groups Tests for a release or sprint. One per release cadence.
      
      ```
      [ISSUE_TRACKER_TOOL] Create Issue:
        project: {{PROJECT_KEY}}
        issueType: Test Plan
        summary: STP: Sprint#50: Payments hardening
        labels: [regression, {release}]
        components: [{module}]          # mandatory — inherit the source Story's components
        # Parent Epic: QA Master Test Plan
      
      [ISSUE_TRACKER_TOOL] Update Issue:
        issue: {TP_KEY}
        field: Tests
        value: [{TEST_KEY_1}, {TEST_KEY_2}, ...]
      ```
      
      ### Test Set — ATS (mandatory per Story) + TS (optional feature grouping)
      
      Two Set altitudes. The **ATS** (`ATS: {US_ID}: {story title}`) is **mandatory per Story** — it holds ALL the Story's TCs (even one) and its `is tested by` link to the Story is **what fills the Xray coverage panel** (ATP/ATR links contribute zero coverage — live-verified); the ATP's and Execution's test lists derive from its membership (Set-first). The feature-level **TS** (`TS: {EPIC-KEY|module}: Validate {feature}`) is an **optional** grouping (smoke / regression / domain), reusable across sprints. The TC title prefix is **ALWAYS `{US_ID}`** (the User Story key) regardless of Set membership (see §5) — under jira-xray membership is **Xray-internal** (added via `/xray-cli`, read via `bun xray test enrich`), NEVER a Jira issue link and NEVER the TC prefix; jira-native carve-out: membership IS a TC→ATS issue link.
      
      ```
      # ATS — MANDATORY per Story (Set-first: created before the first TC)
      [ISSUE_TRACKER_TOOL] Create Issue:
        project: {{PROJECT_KEY}}
        issueType: Test Set
        summary: ATS: {{PROJECT_KEY}}-101: Pay with credit card
        labels: [regression]
        components: [{inherited from the source Story}]   # mandatory on the ATS — the
        # components exemption applies to the feature-level TS: only
        # Parent Epic: QA Test Artifacts
      
      [ISSUE_TRACKER_TOOL] Link Issues:
        from: {ATS_KEY}
        to:   {STORY_KEY}
        linkType: {{jira.link_types.test.name}}   # Story is tested by ATS — THE coverage-panel link
      
      # TS — OPTIONAL feature-level grouping
      [ISSUE_TRACKER_TOOL] Create Issue:
        project: {{PROJECT_KEY}}
        issueType: Test Set
        summary: TS: {EPIC-KEY|module}: Validate {feature}
        labels: [regression, sanity]
        # components: OPTIONAL on the feature-level TS: only — the sole TMS artifact exempt
        # from the components mandate (a feature Set can span modules; its member Tests and
        # the per-Story ATS carry them)
        # Parent Epic: QA Test Artifacts
      ```
      
      ### Test Execution
      
      One per execution run. Holds Test Runs with PASS / FAIL / TODO per Test.
      
      ```
      [TMS_TOOL] Create Execution:
        project: {{PROJECT_KEY}}
        title: ATR: {{PROJECT_KEY}}-101: Story Testing
        tests: [{TEST_KEY_1}, ...]
        components: [{module}]          # mandatory — inherit the source Story's components
        # Parent Epic: QA Test Artifacts
      
      [TMS_TOOL] Import Results:
        format: junit      # or cucumber, xray-json
        file:   ./test-results/junit.xml
        execution: {EXEC_KEY}
      ```
      
      Use `/xray-cli` skill for current CLI syntax. Import updates Test Runs automatically; no manual per-Test status updates needed.
      
      ---
      
      ## 10. CI/CD results flow
      
      ### Xray
      
      ```
      Playwright runs tests
             |
             v
      JUnit / Cucumber JSON report generated
             |
             v
      [TMS_TOOL] Import Results -> Xray creates/updates Test Runs
             |
             v
      Test Execution issue updated with pass/fail per Test
             |
             v
      Test Plan rolls up execution status across all Tests
      ```
      
      ### Jira Native
      
      > **Prerequisite**: Load `/acli` skill before executing commands below.
      
      ```
      Playwright runs tests
             |
             v
      Custom script parses JUnit output
             |
             v
      For each Test:
        [ISSUE_TRACKER_TOOL] Update Issue:
          issue: {TEST_KEY}
          fields:
            Test Status: {Passed|Failed|Blocked}
        [ISSUE_TRACKER_TOOL] Add Comment:
          issue: {TEST_KEY}
          comment: "Run {date}: {result}. Duration: {ms}. CI: {url}"
      ```
      
      Jira Native lacks run history per Test. If historical trend matters, store runs in a separate system (Allure, custom DB) and keep Jira as the latest-state view only.
      
      ---
      
      ## 11. Local cache — markdown per TC (synced, never hand-authored)
      
      After TMS creation, run `bun run jira:sync-issues get <STORY_KEY>` — `scripts/sync-jira-issues.ts` materializes every `Test` issue linked to the Story into `.context/PBI/epics/EPIC-<KEY>-<slug>/stories/STORY-<KEY>-<slug>/test-cases/TEST-<KEY>-<slug>.md`. The directory is a `[SYNC]` Jira mirror (gitignored — see `AGENTS.md` §9): this skill creates the `Test` issue, links it to the Story, syncs, and READS the materialized file — it never writes into `test-cases/`. This lets `test-automation` hand off without re-reading the TMS. So everything below (Gherkin, Variables table, Refinement Notes, the `outcome` / `labels` metadata) must land in the `Test` issue itself — the Description via the full §7 template, labels as Jira labels — because the synced file only mirrors what Jira holds. A generated file looks like this:
      
      ```markdown
      # TEST: PROJ-123: TC1: should grant access when credentials are valid
      
      **Jira Key:** [PROJ-456](https://.../browse/PROJ-456)
      **Status:** READY
      **Components:** Auth
      
      ---
      
      ## Test Description
      
      {the full §7 Description template as it stands in Jira — Preconditions, Action,
      Expected Results, Gherkin, Variables table, Refinement Notes}
      
      ---
      
      ## Related Issues
      
      - is designed by: [PROJ-441](...) - ATP: PROJ-123: ...
      - is executed by: [PROJ-442](...) - ATR: PROJ-123: Story Testing
      
      ---
      
      ## Metadata
      
      - **Created:** ... / **Updated:** ... / **Reporter:** ...
      ```
      
      A later `test-automation` run greps the synced files for `automation-candidate` (mirrored from the Jira labels) to find work to do — which is why the labels must be set on the `Test` issue, not annotated locally.
      
      ---
      
      ## 12. Jira-specific gotchas
      
      1. **Issue Type Scheme**: if the Test issue type is missing from the project, `[ISSUE_TRACKER_TOOL] Create Issue` fails with a generic "invalid issue type" error. Check project admin -> Issue Types.
      
      2. **Screen Scheme**: custom fields (`Test Status`, `Automation Candidate`) need to be on the Create/Edit/View screens. Otherwise they appear to "not save" — actually they are saved but hidden.
      
      3. **Required fields**: Jira can require `Components`, `Fix Version`, `Affects Version`. These block creation silently if missing — `Create Issue` returns validation errors that are easy to miss in batch runs. Always validate a single test creation works before bulk.
      
      4. **Permission schemes**: `Transition Issue` requires the transition permission. A user who can create Tests might not be able to transition them. Check the workflow's transition conditions before batch transitions.
      
      5. **Link types**: "is tested by" / "tests" may not exist by default. Add them in Jira admin -> Issue Linking. Without them, `[ISSUE_TRACKER_TOOL] Link Issues` fails with "invalid link type".
      
      6. **Xray + Jira Cloud API version**: Xray Cloud uses its own REST API separate from Jira's. The `[TMS_TOOL]` (xray-cli) handles this; do not try to create Xray Tests via `[ISSUE_TRACKER_TOOL]` directly — the resulting issue will not register in Xray's internal index.
      
      7. **Rate limits**: Jira Cloud rate-limits at around 10 requests/sec per user. Batch operations hitting 100+ TCs need throttling. Prefer bulk endpoints (Jira `/rest/api/3/issue/bulk`, Xray `/import` endpoints) where available.
      
      8. **Gherkin rendering**: Jira's rich-text editor mangles Gherkin indentation when pasted without a code block. Always wrap Gherkin in triple-backticks (``` ```gherkin ``` ```) inside the Description, or use Xray's dedicated Gherkin field.
      
      9. **Character limits**: Summary is capped at 255 chars. Long TC titles ("PROJ-101: TC14: should complete checkout when user has multiple cards and applies stacked discounts...") truncate silently. Keep CORE + CONDITIONAL tight.
      
      10. **Xray Test Type cannot change**: once a Test is created as `Manual`, converting it to `Cucumber` typically requires deletion and recreation. Pick the type correctly at creation time.
      
      11. **Test Execution closure**: Xray Test Executions do not auto-close. Old Executions accumulate and skew metrics. Close them via `[ISSUE_TRACKER_TOOL] Transition Issue` once results are imported.
      
      12. **Description overwrite**: `[ISSUE_TRACKER_TOOL] Update Issue` on Description replaces, it does not append. Always read the existing Description first if preserving earlier content matters.
      
      ---
      
      ## 13. Completeness checklist (per TC before moving to READY)
      
      - [ ] Summary follows `{US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]` — no anti-patterns. On a **promoted** sprint Test this is re-checked against the LIVE summary, not the one you intended at create time (`SKILL.md` §"Title on promotion")
      - [ ] Traced to the User Story via the cascade: member of the Story's ATS (jira-xray: Xray-internal; jira-native with the work type: TC→ATS link) + "is designed by" ATP + "is executed by" ATR; direct TC→Story "is tested by" ONLY when no ATS exists (jira-native without the Test Set work type)
      - [ ] Linked to Regression Epic (Epic Link)
      - [ ] Components set (affected product module — mandatory, defect-management doctrine Part 3)
      - [ ] Priority set
      - [ ] Labels include scope (regression/smoke/e2e/integration) and automation intent (automation-candidate or manual-only)
      - [ ] Description uses the full template from §7 (no skeletons or TODOs)
      - [ ] Variables table present if Gherkin references placeholders
      - [ ] Prior bugs covered section filled (or "none")
      - [ ] Refinement Notes filled if source-code validation found discrepancies
      - [ ] Xray mode: Test Type set (Manual / Cucumber / Generic)
      - [ ] Added to the Story's ATS (mandatory — Xray mode: Xray-internal membership via `/xray-cli`, never a Jira issue link; jira-native with the work type: TC→ATS issue link); optional feature `TS:` per promotion
      - [ ] Workflow state = READY (or MANUAL / Candidate once decision is made)
      - [ ] Local cache materialized (never hand-written) via `bun run jira:sync-issues get <STORY_KEY>` — one `TEST-<KEY>-<slug>.md` per Test under `.context/PBI/epics/EPIC-<KEY>-<slug>/stories/STORY-<KEY>-<slug>/test-cases/`
      
      ---
      
      ## 14. Anti-patterns to reject
      
      - **Summary**: `Login test`, `Login - error`, `TC1: Test form` — missing prefix, TC#, CORE, and CONDITIONAL.
      - **Description**: bullet list of actions without expected results. Every step needs an expected, or use Gherkin.
      - **Hardcoded data**: UUIDs, emails, passwords in Gherkin. Use `{variable}` + Variables table.
      - **Splitting assertions into separate TCs**: "TC1: check panel A appears", "TC2: check panel B appears", "TC3: check panel C appears" where precondition+action is identical. These are one TC with three assertions.
      - **Cross-cutting as TCs**: "Mobile responsive", "XSS prevention", "Performance", "Accessibility" as standalone TCs. These are validated inside other TCs or in an app-level suite.
      - **Creating TCs before ATS/ATP/ATR exist**: leaves orphaned references. Set-first: find-or-create the ATS (link it to the US — the coverage link), then ATP and ATR (link to the US, link ATP to ATR), and only then create each TC — added to the ATS, linked to ATP (`is designed by`) + ATR (`is executed by`) + AC. Jira-native without the Test Set work type only: link the TC to the US (`is tested by`) directly — the cascade's last resort.
      - **Linking every TC directly to the Story while its ATS covers it**: floods the Story panel with noise. The Story is linked to its ATS (coverage), ATP and ATR (administrative); TCs aggregate to the Story THROUGH the ATS. The direct Story↔TC link is NOT a defect in itself — it is the cascade's documented last resort (no ATS available); the defect is a TC with NO path to its Story.
      - **Summary > 255 chars**: truncates silently. Shorten CONDITIONAL if needed.
      - **Manual steps in Xray with no Description**: creating Xray Manual Tests but skipping `[ISSUE_TRACKER_TOOL] Update Issue` leaves a TC with minimal context. Always populate the full Description template.
      
    • repair-traceability.md 6.9 KB
      # Traceability Fix
      
      Repair broken TMS traceability between User Story, ATS, ATP, ATR, and Test Cases by rebuilding the canonical coverage cascade.
      
      **Input:** $ARGUMENTS
      (Ticket ID to fix, e.g. `UPEX-123`.)
      
      ---
      
      ## When to Use
      
      - Story shows UNCOVERED in the coverage panel despite having TCs
      - Story has no ATS, or the ATS is missing its `is tested by` link / its TC membership
      - TCs reachable only through ATP membership or through direct links that should ride the ATS
      - ATP/ATR not linked to the User Story
      - TC names do not follow the `{US_ID}: TC#: should ...` convention
      - Traceability audit shows broken or missing links
      
      ## Traceability Model — the Cascade
      
      Coverage resolves through an ordered cascade. Each TC must be reachable from its Story by AT LEAST one rung; the command verifies rungs in order and repairs toward rung ①, never by mass direct links.
      
      ```
      ① TC ∈ ATS  ->  ATS --is tested by--> Story     (primary: fills the coverage panel)
      ② TC ∈ ATP  ->  ATP --link--> Story             (placement-only: does NOT fill the panel)
      ③ TC --link--> Story (direct)                   (last-resort, VALID)
      ④ no path                                       (ORPHAN -> repair by building the ATS path)
      ```
      
      Two layers, never confused:
      
      - **Jira layer (issue links)**: container→coverable via the `Test` link type (inward `is tested by`; resolve the slug from `.agents/jira-required.yaml`, never hardcode the literal). `ATS→Story` is MANDATORY — it is what fills the coverage panel. `ATP→Story` / `ATR→Story` are administrative traceability only (verified: they contribute ZERO coverage). Direct `TC→Story` is a valid last-resort, not a defect — the defect is having NO path.
      - **Membership layer** (modality-dependent):
        - **jira-xray**: `TC ∈ ATS/ATP/ATR` is Xray-internal (GraphQL via `/xray-cli`: `addTestsToTestSet` / `getTestSet` etc.). NEVER expressed as an issue link in this modality.
        - **jira-native**: no Xray layer exists — membership IS expressed as `TC→ATS` issue links (explicit carve-out from the rule above). Instance without a Test Set work type → no ATS; direct `TC→Story` links are the fallback (the cascade still resolves at rung ③).
      
      Rung ② finding: TCs reachable via ATP alone are placed but NOT covered — flag that the coverage panel still needs the ATS path.
      
      ## Naming Conventions
      
      | Artifact | Format |
      |----------|--------|
      | ATS | `ATS: {US_ID}: {story title}` |
      | ATP | `ATP: {TICKET-ID}: {story title}` |
      | ATR | `ATR: {TICKET-ID}: Story Testing` |
      | TC | `{US_ID}: TC#: should ...` |
      
      Title grammar canon: `sprint-testing/references/acceptance-test-planning.md`.
      
      ---
      
      ## Workflow
      
      > **Prerequisite**: Load `/acli` skill (for `[ISSUE_TRACKER_TOOL]` commands). If the project is in TMS Modality jira-xray, additionally load `/xray-cli` (for `[TMS_TOOL]` commands — membership reads/writes go through GraphQL). In Modality jira-native, `/acli` alone covers both (membership = issue links).
      
      ### Step 1: Fetch Ticket and Current Artifacts
      
      ```
      [ISSUE_TRACKER_TOOL] Get Issue:
        - issueId: {from $ARGUMENTS}
      ```
      
      Extract the ticket's full title and current issue links (ATS, ATP, ATR, direct TCs).
      
      ```
      [TMS_TOOL] List Tests:
        - issue: {from $ARGUMENTS}
      ```
      
      List all TCs, the ATS, ATPs, and ATRs associated with this ticket. Modality jira-xray: read ATS/ATP membership via GraphQL (`getTestSet` / plan tests). Modality jira-native: read `TC→ATS` issue links instead.
      
      ### Step 2: Audit the Cascade
      
      Walk the cascade in order and classify every TC by its highest rung:
      
      | # | Check | Expected |
      |---|-------|----------|
      | ① | ATS exists, named `ATS: {US_ID}: {story title}`, linked to Story via `is tested by` | Yes (primary) |
      | ① | Every TC is a member of the ATS | Yes |
      | ② | TCs reachable ONLY via ATP membership | Flag: placed but not covered — panel needs the ATS |
      | ③ | TCs with only a direct `TC→Story` link | Valid last-resort; note as ATS-membership candidates |
      | ④ | TCs with no path at all | ORPHAN — repair required |
      | — | ATP exists and is linked to Story (administrative) | Yes |
      | — | ATR exists and is linked to ATP (administrative) | Yes |
      | — | Names match conventions (table above) | Yes |
      
      Report all issues found before making any changes.
      
      ### Step 3: Present Fix Plan
      
      List each issue and the proposed fix. Wait for user confirmation before proceeding.
      
      Repairs build the ATS path — create the missing ATS / link / membership. NEVER repair by mass-creating direct `TC→Story` links (that is the last-resort rung, not the target state).
      
      Common fixes:
      
      | Issue | Fix |
      |-------|-----|
      | No ATS for the Story | Create `ATS: {US_ID}: {story title}` (parent: "QA Test Artifacts" epic; components inherited from the Story), link to Story via `is tested by`, add all TCs as members |
      | ATS exists but not linked to Story | Add the `is tested by` link ATS→Story |
      | TC not a member of the ATS | Add membership (jira-xray: GraphQL `addTestsToTestSet`; jira-native: `TC→ATS` issue link) |
      | TC covered only via ATP (rung ②) | Add the TC to the ATS — ATP placement alone leaves the panel uncovered |
      | TC orphan (rung ④) | Add the TC to the ATS (create the ATS first if missing) |
      | ATP not linked to Story | Add Story link to ATP (administrative) |
      | ATP not linked to ATR | Add ATR link to ATP (administrative) |
      | Name does not follow convention | Rename the artifact |
      
      ### Step 4: Apply Fixes
      
      Execute each fix using the TMS tool:
      
      ```
      [TMS_TOOL] Update Test / Add To Test Set:
        - testId: {tc-id}
        - target: { ATS membership, links, name as needed }
      ```
      
      Modality jira-xray: membership mutations via `/xray-cli` GraphQL; issue links via `[ISSUE_TRACKER_TOOL]`. Modality jira-native: everything via `[ISSUE_TRACKER_TOOL]` issue links.
      
      ### Step 5: Verify
      
      Re-run the audit from Step 2 to confirm every TC now resolves at rung ① (or has an explicitly accepted rung-③ direct link) and the Story's coverage panel is filled.
      
      ### Step 6: Report
      
      Output a summary:
      
      ```markdown
      ## Traceability Fixed: {TICKET-ID}
      
      ### Issues Found
      - {issue 1}
      - {issue 2}
      
      ### Fixes Applied
      - {fix 1}
      - {fix 2}
      
      ### Current State
      | Artifact | ID | Name | Cascade rung / Links OK |
      |----------|----|------|-------------------------|
      | ATS | {id} | ATS: {US_ID}: {story title} | ① is tested by -> Story |
      | ATP | {id} | ATP: {TICKET-ID}: {story title} | administrative link OK |
      | ATR | {id} | ATR: {TICKET-ID}: Story Testing | administrative link OK |
      | TC | {id} | {US_ID}: TC1: should ... | ① member of ATS |
      ```
      
      ## Rules
      
      - Always audit before fixing -- never assume what is broken
      - Present the fix plan and wait for confirmation before modifying any TMS artifact
      - Repair toward the ATS path (rung ①); never mass-create direct TC→Story links
      - Resolve the `is tested by` link-type slug from `.agents/jira-required.yaml`, never hardcode it
      - Verify all links + membership after applying fixes
      - Tool references (`[TMS_TOOL]`, `[ISSUE_TRACKER_TOOL]`) resolve via the Tool Resolution table in `AGENTS.md`
      
    • tms-architecture.md 49.6 KB
      # TMS Architecture — Entity Model and Traceability
      
      Definitive reference for the four TMS entities, their fields, their links, and the order in which to create them. Read this when creating any artifact, validating traceability, or fixing broken links.
      
      > **Before publishing any TMS entity body (Test / TestPlan / TestExecution / TestRun) to Jira rich-text fields**, read `../../agentic-qa-core/references/jira-publishing-gotchas.md` — covers the two ADF conversion gotchas (`md-to-adf` mark collision + MCP batched custom-field rejection) that silently fail HTTP 400.
      
      ---
      
      ## 1. The five entities
      
      Every QA-tested user story produces five artifact types. The model is tool-agnostic: the same structure applies in Jira+Xray, native Jira, Coda, Azure DevOps, and TestRail. Only the implementing issue types differ.
      
      | Entity | Full name | Purpose | When created | Where the content lives |
      |--------|-----------|---------|--------------|-------------------------|
      | **US** | User Story / Backlog item | The requirement under test | Pre-QA | Description + ACs |
      | **ATP** | Acceptance Test Plan | Approach, risk analysis, AC-to-TC coverage. Contains the Test Analysis. | Content pre-sprint in the Story field `{{jira.acceptance_test_plan}}` (shift-left); the Test Plan ITEM by `/sprint-testing` Stage 1 from that field (find-or-create in Stage 4 only when module-driven and no item exists) | ATP issue body |
      | **ATR** | Acceptance Test Results | Execution results, findings, evidence. Contains the Test Report. | Stage 1 (created early), filled Stage 3 | ATR issue body |
      | **ATS** | Acceptance Test Set | Per-Story Test Set holding ALL the Story's TCs (even one). **Coverage anchor**: the ATS→Story `is tested by` link is what fills the Xray coverage panel. Mandatory per Story. | Stage 1 / Stage 4 (find-or-create, Set-first) | ATS issue (membership + link graph) |
      | **TC** | Test Case | Individual test: precondition + action + expected. Lives in a test repository. | Stage 4 (Documentation) | TC issue body |
      
      ### Container per modality (load-bearing)
      
      The entity model is tool-agnostic, but the **container** each entity lives in changes with the TMS modality. Resolve modality via `test-documentation/SKILL.md` §Phase 0 before using these mappings.
      
      > **Items over fields (by excellence).** Every Plan is a **Test Plan** issue and every Run is a
      > **Test Execution** issue — in BOTH modalities. These are native Jira work types (Xray-independent),
      > so the standard does NOT branch on modality for *structure*; Xray only adds the run/coverage engine.
      > The Story custom field for ATP/ATR is a **degraded fallback ONLY**, used when the Test Plan /
      > Test Execution work types are unavailable in the instance. The column below labelled "field
      > fallback" is that degraded mode, not the default.
      
      | Entity | Items first (both modalities) | Degraded fallback (work type unavailable) |
      |--------|-------------------------------|--------------------------------------------|
      | **US** | Jira `Story` | — |
      | **ATP** | A native Jira `Test Plan` issue, titled `ATP: {STORY-KEY}: {story title}`. Parented to **QA Master Test Plan**, linked to the Story via "tests". Real, queryable, JQL-filterable. Under Xray it is also the coverage anchor. | Story's `{{jira.acceptance_test_plan}}` field; else a `## Acceptance Test Plan (ATP)` comment. **No separate issue** — used only when the work type is absent. |
      | **ATR** | A native Jira `Test Execution` issue, titled `ATR: {STORY-KEY}: Story Testing`. Parented to **QA Test Artifacts**. Under Xray it holds `Test Runs` per TC, plus Environment, Begin/End Date, and is the target of `[TMS_TOOL] Import Results` at the end of every CI run. | Story's `{{jira.acceptance_test_results}}` field; else a `## Acceptance Test Results (ATR)` comment. **No separate issue.** CI updates the Test Status field on each TC directly. |
      | **TC** | Xray `Test` issue (type Manual / Cucumber / Generic), or a Jira-native `Test` custom issue type (set up per `references/jira-setup.md`) / `Task` with a `Test Type` custom field. Parented to **QA Test Repository**. | — |
      | **ATS** | A `Test Set` issue titled `ATS: {US_ID}: {story title}`, **mandatory per Story**, parented to **QA Test Artifacts**, `components` inherited from the Story (**mandatory**), linked to the Story via `is tested by` (the coverage-panel link). Membership: Xray-internal under jira-xray; **TC→ATS issue links** under jira-native (carve-out — the "membership is never a link" rule is xray-only). | Work type absent → **no ATS**: direct TC→Story `is tested by` links (the cascade's last resort). |
      | **TS (feature Test Set) / Precondition** | Native Jira work types, parented to **QA Test Artifacts** (first-class under Xray; selectable plain Jira issue types otherwise). The feature-level `TS:` is an **OPTIONAL** grouping (smoke / regression); `components` is OPTIONAL on the feature-level `TS:` **only** — the per-Story ATS inherits the Story's components (mandatory). | Group by labels + the QA Test Repository / QA Test Artifacts Epic when the work type is absent. |
      
      Key consequences:
      
      - **By excellence the Test Plan and Test Execution issues exist in both modalities** — they are real, queryable, filterable by JQL, carry real issue-links (Plan→scope, Run→Plan, Run→TC) and an independent status lifecycle. The Test Execution is the target of `[TMS_TOOL] Import Results` at the end of every CI run.
      - **Only in the degraded fallback** (the work type is unavailable in the instance) does ATP/ATR content live on the Story custom field. There, traceability from a TC back to the plan/results walks via the "is tested by" link to the Story, then reads the Story's custom fields.
      - The title grammar (`ATP: {STORY-KEY}: {story title}` / `ATR: {STORY-KEY}: Story Testing`) is identical in both modalities — in the fallback it identifies the section header in the Story comment, not an issue key.
      
      ---
      
      ## 2. Required fields per entity
      
      ### User Story (pre-existing)
      
      | Field | Required | Notes |
      |-------|----------|-------|
      | ID | Yes | `{{PROJECT_KEY}}-{n}` auto-assigned |
      | Title | Yes | |
      | Acceptance Criteria | Yes | Testable conditions |
      | Test Set link (ATS) | Yes (mandatory) | `is tested by` ATS — **the coverage-panel link** (live-verified: ATP/ATR links contribute zero coverage) |
      | Test Plan link (ATP) | Yes (once ATP exists) | `is tested by` ATP (administrative traceability, no coverage) |
      | Test Results link (ATR) | Yes (once ATR exists) | `is tested by` ATR (administrative traceability, no coverage) |
      | Test Cases links | Last resort only | TCs reach the Story THROUGH the ATS (primary) or ATP (secondary, placement-only); a direct Story↔TC link is the cascade's last resort when no ATS exists — the defect is a TC with NO path, not the direct link |
      
      ### ATP
      
      | Field | Required | Value source |
      |-------|----------|--------------|
      | Name | Yes | `ATP: {STORY-KEY}: {story title}` |
      | User Story link | Yes | Back-link to US |
      | Test Coverage | Yes | AC-to-TC mapping table |
      | Test Analysis | Yes | Rich text: approach, risks, test data, scenarios |
      | Test Results link | Yes (after ATR exists) | Link to ATR |
      | Complete flag | Yes | Set when filled |
      
      ### ATR
      
      | Field | Required | Value source |
      |-------|----------|--------------|
      | Name | Yes | `ATR: {STORY-KEY}: Story Testing` |
      | User Story link | Yes | Back-link to US |
      | Test Coverage | Yes | Same AC-to-TC view as ATP (shared or mirrored) |
      | Test Report | Yes | Rich text: session summary, env, findings, evidence |
      | Complete flag | Yes | Set when filled |
      
      ### ATS
      
      | Field | Required | Value source |
      |-------|----------|--------------|
      | Name | Yes | `ATS: {US_ID}: {story title}` |
      | User Story link | Yes | `is tested by` — the coverage-panel link |
      | Tests (membership) | Yes | ALL the Story's TCs (even one). Xray-internal under jira-xray; TC→ATS issue links under jira-native |
      | Components | Yes | Inherited from the Story (mandatory — the exemption is feature-level `TS:` only) |
      | Parent | Yes | QA Test Artifacts epic |
      
      ### TC
      
      | Field | Required | Value source |
      |-------|----------|--------------|
      | ID | Yes | Auto-generated (e.g., `{{PROJECT_KEY}}-456`) |
      | Name | Yes | `{US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]` |
      | Acceptance Criterion | Yes | Which AC this TC covers (1:N from TC side) |
      | ATS membership | Yes | Member of the Story's ATS (Xray-internal under jira-xray; TC→ATS issue link under jira-native) |
      | User Story link | Last resort only | TC reaches the US through the ATS (primary) / ATP (secondary); a direct link is used only when no ATS exists (cascade step 3) |
      | Test Plan link (ATP) | Yes | `is designed by` ATP (`test_design`) |
      | Test Results link (ATR) | Yes | `is executed by` ATR (`test_execute`) |
      | Precondition | Yes | Environment, login state, test data, DB state |
      | Specification | Yes | Step-by-step verification (Gherkin or table) |
      | Test Status | Yes | `NOT RUN` / `PASSED` / `FAILED` |
      | Workflow Status | Yes | `Draft` → `In Design` → `READY` → `In Review` → `Candidate` → `In Automation` → `Pull Request` → `AUTOMATED`, plus the `MANUAL` branch and `DEPRECATED` (any state). Exact names + full state machine in §8 — authoritative source `.agents/jira-workflows.json` (`work_types.test_case`) |
      | Priority | Yes | `Critical` / `High` / `Medium` / `Low` |
      | Labels | Yes | At least one scope label (`regression` almost always) |
      | Components | Yes | Affected product module (defect-management doctrine Part 3) |
      | Automation Candidate | Yes (boolean) | True when Candidate path |
      | Parent | Yes | Regression Epic / test repository |
      
      ---
      
      ## 3. Entity relationships
      
      ```
      +----------------------------------------------------------------------+
      |                                                                      |
      |   User Story ({{PROJECT_KEY}}-123)                                   |
      |     |                                                                |
      |     +--- is tested by ---> ATS (ATS: ...-123: <story title>)         |
      |     |                        |    <- THE coverage-panel link         |
      |     |                        +-- membership: ALL the Story's TCs     |
      |     +--- is tested by ---> ATP (ATP: ...-123: <story title>)         |
      |     |                        |    <- administrative, no coverage     |
      |     +--- is tested by ---> ATR (ATR: ...-123: Story Testing)          |
      |                              |    <- administrative, no coverage     |
      |         ATP designs (test_design)   ATR executes (test_execute)      |
      |                  \                          /                        |
      |                   v                        v                         |
      |                  [ TC-1, TC-2, TC-3, ... TC-N ]  <- all members of the ATS |
      |                                                                      |
      |   Coverage truth (live-verified): the ATS->Story `is tested by` link |
      |   is what fills the Xray coverage panel; the ATP->Story and          |
      |   ATR->Story links contribute ZERO coverage (administrative          |
      |   traceability only). TCs aggregate to the Story through the ATS.    |
      |   Resolution cascade: TC -> ATS -> Story (primary) ->                |
      |   TC -> ATP -> Story (secondary, placement-only) ->                  |
      |   TC -> Story direct (last resort) -> else ORPHAN.                   |
      |   Edges render bidirectionally:                                      |
      |     US <-> ATS <-> TC   (membership; coverage backbone)              |
      |     US <-> ATP <-> TC   (designs / is designed by)                   |
      |     US <-> ATR <-> TC   (executes / is executed by)                  |
      |     ATP <-> ATR         (plan / results)                             |
      +----------------------------------------------------------------------+
      ```
      
      ### Cardinality
      
      | From | To | Cardinality | Link direction |
      |------|----|-------------|----------------|
      | US | ATS | 1:1 | `is tested by` (`test`) — **the coverage-panel link** |
      | US | ATP | 1:1 | `is tested by` (`test`) — administrative, no coverage |
      | US | ATR | 1:1 | `is tested by` (`test`) — administrative, no coverage |
      | US | TC | 1:N | **via the ATS by default** (membership + ATS→Story link); direct `is tested by` only as the cascade's last resort (no ATS) |
      | ATS | TC | 1:N | Membership — Xray-internal (jira-xray) or TC→ATS issue link (jira-native) |
      | ATP | ATR | 1:1 | Bidirectional (plan / results) |
      | ATP | TC | 1:N | ATP `designs` TC / TC `is designed by` ATP (`test_design`) |
      | ATR | TC | 1:N | ATR `executes` TC / TC `is executed by` ATR (`test_execute`) |
      | TC | AC | N:1 (or N:M) | TC covers one or more ACs |
      
      Given any one of the five, you must be able to navigate to the other four. That is what "traceability" means. The US↔TC navigation resolves by the **cascade**: `TC → ATS → Story` (primary — fills coverage) → `TC → ATP → Story` (secondary, placement-only: does NOT fill the coverage panel) → `TC → Story` direct (last resort — valid, but only when no ATS exists) → else ORPHAN. Linking every TC to the Story directly is avoided by default because it floods the Story panel with noise; the ATS is the aggregation point. The direct link is NOT a defect — the defect is a TC with NO path to its Story.
      
      ---
      
      ## 4. Traceability rules
      
      ### Mandatory links
      
      | Entity | Required link | Type / direction | When to set |
      |--------|---------------|------------------|-------------|
      | **ATS** | User Story | `is tested by` (`test`) — **the coverage-panel link** | At creation (Set-first: before the first TC) |
      | **ATS** | each TC | Membership — Xray-internal (jira-xray) / TC→ATS issue link (jira-native) | At TC creation |
      | **ATP** | User Story | `is tested by` (`test`) — administrative, no coverage | At creation |
      | **ATP** | Test Results (ATR) | Bidirectional (plan / results) | After ATR is created |
      | **ATP** | each TC | ATP `designs` TC (`test_design`) | At TC creation |
      | **ATR** | User Story | `is tested by` (`test`) — administrative, no coverage | At creation |
      | **ATR** | each TC | ATR `executes` TC (`test_execute`) | At TC creation |
      | **TC** | ATS | Membership (see ATS row) | At creation |
      | **TC** | Test Plan (ATP) | `is designed by` ATP (`test_design`) | At creation |
      | **TC** | Test Result (ATR) | `is executed by` ATR (`test_execute`) | At creation |
      | **TC** | Acceptance Criterion | AC reference | At creation |
      
      **Coverage truth (live-verified 2026-08-21, `.session/artifact-ladder-refactor/scoping.md` §Verificación)**: the Xray coverage panel is filled ONLY by an `is tested by` link from a Test Set (the ATS) or a direct Test↔Story link — the ATP→Story and ATR→Story links contribute ZERO coverage. That is why the ATS is mandatory: it is the coverage backbone, while ATP/ATR links are administrative traceability.
      
      A TC is **NOT** linked to the User Story directly while an ATS exists — it reaches the Story through the ATS (membership + the ATS→Story link). The direct TC→Story link is the cascade's **last resort** (no ATS available — e.g. jira-native without the Test Set work type), not a defect; the defect is a TC with **no path at all**. A TC missing its ATS membership or its ATP/ATR links is broken — use `fix-traceability` to repair. **Under jira-xray, the Xray-internal attach (`plan add-tests` / `exec add-tests` / `set add-tests`) creates NO Jira links** — the `designs`/`executes` Jira edges MUST be created explicitly via `[ISSUE_TRACKER_TOOL]` (`/acli`). Jira-native carve-out: with a Test Set work type present, ATS membership IS expressed as TC→ATS issue links. (Slug-layer mechanics live in `agentic-qa-core/references/traceability-linking.md` §3/§9.)
      
      ### Validation checklist (before marking Complete)
      
      - [ ] ATS exists, links to the User Story (`is tested by` — coverage panel shows Covered), and holds ALL the Story's TCs
      - [ ] ATP links to User Story (`is tested by`) AND ATR
      - [ ] ATR links to User Story (`is tested by`)
      - [ ] Every TC is a member of the ATS and links to ATP (`is designed by`) and ATR (`is executed by`)
      - [ ] No direct Story↔TC links exist while the ATS covers them (direct links are valid ONLY as the cascade's last resort, when no ATS exists)
      - [ ] ATP Test Coverage maps all ACs to TCs
      - [ ] ATR Test Coverage reflects execution results
      - [ ] User Story panel shows references to ATS, ATP and ATR (TCs reachable one hop further, through the ATS)
      
      ---
      
      ## 5. Creation and linking order
      
      Artifacts must be created in a specific sequence. Creating TCs first, ATP second leaves orphaned references that are painful to repair.
      
      ### The sequence (Set-first)
      
      ```
      Step 1. Find-or-create the Story's ATS (mandatory — even for one TC)
              -> link ATS to User Story (Story `is tested by` ATS, `test`) — THE coverage-panel link
      
      Step 2. Find-or-create ATP
              (pre-sprint the ATP content lives in {{jira.acceptance_test_plan}}, written by
              shift-left; the ITEM is normally created by /sprint-testing Stage 1 from that
              field — create here only when module-driven and no Story ATP item exists)
              -> link ATP to User Story (Story `is tested by` ATP, `test`) — administrative
              (ATR link left empty for now)
      
      Step 3. Create ATR
              -> link ATR to User Story (Story `is tested by` ATR, `test`) — administrative
      
      Step 4. Update ATP
              -> link ATP to ATR (bidirectional plan/results)
      
      Step 5. For each TC (as Stage 4 progresses):
              Create TC
              -> add TC to the ATS (jira-xray: Xray-internal membership; jira-native: TC→ATS issue link)
              -> link TC to ATP (ATP `designs` TC / TC `is designed by` ATP, `test_design`)
              -> link TC to ATR (ATR `executes` TC / TC `is executed by` ATR, `test_execute`)
              -> link TC to AC
              # Do NOT link TC to the User Story directly while the ATS exists — it aggregates
              # via the ATS. Direct TC→Story is the cascade's last resort (no ATS available).
      
      Step 6. Derive the ATP's and the ATR's test lists FROM the ATS membership
              (the ATS holds ALL the Story's TCs; Plan and Execution consume that list).
      ```
      
      ### Why this order
      
      1. **ATS first**: the coverage backbone must exist before any TC — its membership is the source the ATP and ATR test lists derive from, and its Story link is the only one the coverage panel counts.
      2. **ATP second**: the plan must exist before execution results can reference it. Its content usually pre-exists (field-first from shift-left, item from sprint-testing Stage 1); find-or-create.
      3. **ATR third**: created early so the ATP can reference it. Test Report content is filled after execution.
      4. **ATP <-> ATR fourth**: once both exist, wire up the bidirectional link.
      5. **TCs last**: by the time a TC is created, the ATS, ATP and ATR exist, so the membership, `designs` (ATP) and `executes` (ATR) edges are set at creation. The TC is bound to the Story's graph through the ATS — a direct Story↔TC link only when no ATS exists.
      
      ### Pseudocode — full sequence
      
      > **Prerequisite**: Load `/xray-cli` skill (Modality jira-xray) — in Modality jira-native these `[TMS_TOOL]` calls fall through to `[ISSUE_TRACKER_TOOL]`, so load `/acli` instead. See §9 for the per-modality split.
      
      ```
      [TMS_TOOL] Create ATS:                      # find-or-create — Set-first, MANDATORY per Story
        name: ATS: {US_ID}: {story title}
        story: {from User Story title}            # Story `is tested by` ATS (test) — THE coverage-panel link
        components: {inherited from the source Story}   # mandatory (exemption is feature-level TS: only)
        # Parent Epic: QA Test Artifacts
      
      [TMS_TOOL] Create ATP:                      # find-or-create — item usually exists from /sprint-testing
        name: ATP: {STORY-KEY}: {story title}     # Stage 1 (pre-sprint content: {{jira.acceptance_test_plan}})
        story: {from User Story title}            # Story `is tested by` ATP (test) — administrative, no coverage
        components: {inherited from the source Story}   # mandatory
        # Parent Epic: QA Master Test Plan
      
      [TMS_TOOL] Create ATR:
        name: ATR: {STORY-KEY}: Story Testing
        story: {from User Story title}            # Story `is tested by` ATR (test) — administrative, no coverage
        components: {inherited from the source Story}   # mandatory
        # Parent Epic: QA Test Artifacts
      
      [TMS_TOOL] Update ATP:
        id: {from ATP created above}
        results: {from ATR name created above}    # ATP <-> ATR (plan / results)
      
      [TMS_TOOL] Create TC:
        name: {per TC naming convention}
        test-set: {from ATS name}                 # membership — ALL the Story's TCs live in the ATS
        test-plan: {from ATP name}                # ATP `designs` TC (test_design)
        test-result: {from ATR name}              # ATR `executes` TC (test_execute)
        ac: {from the Acceptance Criterion this TC covers}
        components: [{module}]                    # mandatory — affected product module
        project: {{PROJECT_KEY}}
        # NO `story:` link while the ATS exists — the TC aggregates to the Story through
        # the ATS (coverage) plus the ATP (`designs`) and ATR (`executes`). Direct TC→Story
        # is the cascade's last resort (no ATS available).
        # The Xray-internal attach creates NO Jira links — the designs/executes edges
        # are created explicitly via [ISSUE_TRACKER_TOOL] (/acli). Slug layering:
        # traceability-linking.md §3/§9.
      
      # Set-first closure: derive the ATP's and ATR's test lists FROM the ATS membership.
      ```
      
      ---
      
      ## 6. Naming conventions (canonical)
      
      | Entity | Pattern | Example |
      |--------|---------|---------|
      | User Story | `{{PROJECT_KEY}}-{n}` | `PROJ-123` |
      | ATP | `ATP: {STORY-KEY}: {story title}` | `ATP: PROJ-123: Apply discount at checkout` |
      | ATR | `ATR: {STORY-KEY}: Story Testing` | `ATR: PROJ-123: Story Testing` |
      | ATS | `ATS: {US_ID}: {story title}` | `ATS: PROJ-123: Apply discount at checkout` |
      | TS (optional, feature-level) | `TS: {EPIC-KEY\|module}: Validate {feature}` | `TS: PROJ-42: Validate checkout` |
      | TC (TMS title) | `{US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]` | `PROJ-101: TC1: should grant access when credentials are valid` |
      | TC (code / ATC) | `{US_ID}: should <behavior> when <condition>` | `PROJ-101: should display error when password is incorrect` |
      
      Rules:
      
      1. ATP, ATR and ATS names always include the User Story ID. This makes them searchable, unique per story, and impossible to confuse across stories. The feature-level `TS:` is the only Set that scopes to an Epic/module instead.
      2. TC names follow the pattern `{US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]`, where `CORE` is the expected outcome (verb + object phrased after `should`, e.g., `grant access`, `reject login`) and `CONDITIONAL` is the optional connector clause (`when …` / `if …`, e.g., `when credentials are valid`, `if password is incorrect`) plus an optional `given …` precondition. The prefix is ALWAYS the User Story ID, in every modality; Test Set membership is never baked into the title. Under Modality jira-xray it is also **not** a Jira issue link — membership is Xray-internal, managed through `/xray-cli`, never `acli link create` (see `.agents/jira-required.yaml` → `link_types`); jira-native carve-out: with a Test Set work type present, membership IS expressed as TC→ATS issue links. A consequence worth knowing: `bun run jira:sync-issues` talks to the Jira REST API, so under jira-xray it cannot see Test Set membership or Precondition associations at all — only the Xray GraphQL API exposes them.
      3. Code-side IDs match the TMS-generated key exactly. The `@atc('PROJ-456')` decorator uses the TMS issue key, not an invented module prefix.
      4. Module prefixes (e.g., `AUTH-`, `ORD-`) are a TMS-display convention only (Test Set names, TMS folders) — they are not the canonical ID, and they never appear in file names: the sync materializes each Test as `test-cases/TEST-<KEY>-<slug>.md`.
      
      ---
      
      ## 7. Completed User Story view
      
      When all In-Sprint Testing stages are complete, the User Story panel in the TMS should look like this:
      
      ```
      User Story: PROJ-123 — <Story Title>
      
      | Test Set (is tested by)     | ATS: PROJ-123: Apply discount at checkout | Coverage: Covered |
      | Test Plan (is tested by)    | ATP: PROJ-123: Apply discount at checkout | Complete |
      | Test Results (is tested by) | ATR: PROJ-123: Story Testing              | Complete |
      (No direct Test Case links on the Story — TCs are reached through the ATS; the
       ATS→Story link is the one filling the coverage panel.)
      
      ATS (ATS: PROJ-123: Apply discount at checkout)
        User Story:    PROJ-123 (tests / is tested by)  <- coverage-panel link
        Tests:         TC-1, TC-2, TC-3, TC-4           (membership — ALL the Story's TCs)
      
      ATP (ATP: PROJ-123: Apply discount at checkout)
        User Story:    PROJ-123 (tests / is tested by)
        Test Analysis: [filled]
        Designs:       TC-1, TC-2, TC-3, TC-4        (test_design)
        Test Coverage: AC1 -> TC-1; AC2 -> TC-2; AC3 -> TC-3, TC-4
        Test Results:  ATR: PROJ-123: Story Testing
        Complete:      Yes
      
      ATR (ATR: PROJ-123: Story Testing)
        User Story:    PROJ-123 (tests / is tested by)
        Test Report:   [filled]
        Executes:      TC-1, TC-2, TC-3, TC-4        (test_execute)
        Test Coverage: AC1 -> TC-1 PASSED; AC2 -> TC-2 PASSED; AC3 -> TC-3 PASSED, TC-4 FAILED
        Complete:      Yes
      
      Test Cases (each: member of the ATS, is designed by ATP, is executed by ATR — no direct US link needed)
        TC-1 | PASSED | AC1 | should <behavior> when <condition>
        TC-2 | PASSED | AC2 | should <behavior> when <condition>
        TC-3 | PASSED | AC3 | should <behavior> when <condition>
        TC-4 | FAILED | AC3 | should <behavior> when <condition>
      ```
      
      ### Completeness criteria
      
      A User Story is fully documented when:
      
      0. ATS exists, is linked to the Story (`is tested by` — the coverage panel shows Covered), and holds ALL the Story's TCs.
      1. ATP exists, is linked, and is marked Complete.
      2. ATR exists, is linked, and is marked Complete.
      3. Every TC has a Test Status (`PASSED`, `FAILED`, or `NOT RUN`).
      4. Every AC has either at least one **documented** TC OR an explicit Deferred note in the prioritization report. The documented TC set is intentionally sparse — only the regression-worthy scenarios (Candidate + Manual) are persisted; the wide 1:N derivation happened upstream (in `/sprint-testing` planning + exploration) and most of it is correctly Deferred (no TMS TC). Do NOT inflate documentation to "N TCs per AC" — that is a design/execution concern, not a documentation one.
      5. Where a regression-worthy scenario IS persisted, its TC is technique-shaped: a documented boundary TC uses BVA values, a documented state TC covers the transition, etc. (`agentic-qa-core/references/test-design-doctrine.md`). Technique governs the SHAPE of what you document, not how MUCH you document.
      6. ATP and ATR are bidirectionally linked, and both are linked to the US via `is tested by` (administrative — coverage comes from the ATS link).
      7. Every TC is a member of the ATS and links to the ATP (`is designed by`) and ATR (`is executed by`); no direct US link while the ATS covers it.
      
      Any failing criterion -> the story is not ready to close QA.
      
      ---
      
      ## 8. TC workflow state machine
      
      > **Substrate reference — AUTHORITATIVE**: `.agents/jira-workflows.json` (`work_types.test_case`) is the source of truth for every status and transition name in this section; `.agents/jira-required.yaml` declares which are required. A status that is not in that JSON does not exist in the instance — never write one from memory (`Approved`, `Automating`, `Merge Request` and `Triaged` are common inventions and none of them exist). Skills resolve names via `{{jira.status.test_case.<slug>}}` / `{{jira.transition.test_case.<slug>}}`. Rename detection runs via `bun run jira:sync-workflows`.
      
      The TC workflow spans three IQL stages. Key transitions: `start_design` (Draft -> In Design), `ready_to_run` (In Design -> READY), `for_manual` (READY -> MANUAL), `automation_review_from_ready` (READY -> In Review), `approve_to_automate` (In Review -> Candidate), `start_automation` (Candidate -> In Automation), `create_pr` (In Automation -> Pull Request), `merged` (Pull Request -> AUTOMATED). Never skip states; use `back_from_ready` / `back_from_in_design` for rework, `deprecated` (any -> DEPRECATED) to retire a TC, `recover` (DEPRECATED -> Draft) to revive one.
      
      ```
      Stage 2 (Execution)     Stage 4 (Documentation)     Stage 5 (Automation)
      -----------------       -----------------------     ---------------------
      
      Draft -> In Design -> READY -+-- for manual --> MANUAL        (manual regression branch)
                                   |
                                   +-- automation review --> In Review
                                                               |
                                                               +-- approve to automate --> Candidate
                                                                                               |
                                                                                               +-- start automation --> In Automation
                                                                                                                           |
                                                                                                                           +-- create PR --> Pull Request
                                                                                                                                                |
                                                                                                                                                +-- merged --> AUTOMATED
      
      MANUAL -- automation review --> In Review   |   MANUAL -- for automation --> Candidate   |   MANUAL -- automated --> AUTOMATED
      Any state -> DEPRECATED (when feature is removed) -- recover --> Draft
      ```
      
      Rules:
      - No state can be skipped. Draft must go through In Design before READY; READY cannot go straight to AUTOMATED.
      - Backward transitions are the `back_*` family (one step back per state) plus "any state to DEPRECATED".
      - MANUAL is not a dead end: a MANUAL TC can later re-enter In Review, Candidate, or AUTOMATED if ROI changes.
      
      ---
      
      ## 9. Pseudocode — common entity operations
      
      All operations use `[TMS_TOOL]` for TMS-specific actions and `[ISSUE_TRACKER_TOOL]` for generic issue operations. Resolution via AGENTS.md Tool Resolution (Xray CLI, Jira CLI, or MCP fallback).
      
      ### List and read
      
      > **Prerequisite**: Load `/xray-cli` skill (Modality jira-xray). In Modality jira-native, load `/acli` — these calls map to JQL/search via `[ISSUE_TRACKER_TOOL]`.
      
      ```
      [TMS_TOOL] List ATPs:
        project: {{PROJECT_KEY}}
        ticket: {from User Story ID}
      
      [TMS_TOOL] List ATRs:
        project: {{PROJECT_KEY}}
        ticket: {from User Story ID}
      
      [TMS_TOOL] List TCs:
        project: {{PROJECT_KEY}}
        ticket: {from User Story ID}
      
      [TMS_TOOL] Get TC:
        id: {from TC ID}
      ```
      
      ### Create
      
      Pseudocode splits by TMS modality — pick the block matching the resolution from SKILL.md §Phase 0. Full per-modality reference in SKILL.md §Quick reference.
      
      #### Parallel TC creation (default for N > 10)
      
      When the candidate list has more than 10 TCs, creating them serially burns the orchestrator's context with raw API responses. Shard the list into chunks of ~5-10 TCs per subagent, cap total subagents at 10. The orchestrator pre-creates the ATS / ATP / ATR (Phase 3 §Linking order — Set-first, steps 1-4) **before** dispatching — only the per-TC writes (step 5) are parallelised; the Set-first closure (deriving the Plan/Execution test lists from the ATS membership) runs after aggregation. See SKILL.md §Subagent Dispatch Strategy for the per-phase pattern table.
      
      **Sharding rule**: `ceil(N / 10)` subagents, each handling roughly equal-sized chunks. If `N > 100`, chunks must be larger than 10 each (cap is on subagent count, not chunk size). Each dispatch follows the 7-component briefing format in `.agents/skills/agentic-qa-core/references/briefing-template.md`.
      
      ##### Modality jira-xray (subagent loads `/xray-cli`)
      
      Briefing (7 components per `agentic-qa-core/references/briefing-template.md`):
      
      ```
      Goal: Create <K> Xray Test issues in Jira project <PROJECT_KEY> for chunk <I>/<TOTAL>, add each to the Story's ATS <ATS_KEY> (membership), link each to ATP <ATP_KEY> (designs) and ATR <ATR_KEY> (executes), and return their issue keys. Do NOT link the Tests to the Story <STORY_KEY> directly — coverage flows through the ATS→Story link (direct TC→Story is the cascade's last resort, only when no ATS exists).
      
      Context docs:
        - .session/test-documentation/<scope>/ (session contract artifact — the TC designs Phase 1-2 wrote; the definitions for this chunk live here, NOT in test-specs/, which holds keys only)
        - .agents/jira-fields.json (custom field IDs)
        - .agents/skills/test-documentation/references/tms-architecture.md (TC body shape, naming, linking order)
        - .agents/skills/test-documentation/references/jira-test-management.md §7 (Description template)
      
      Project Standards (auto-resolved): pulled from .agents/skills/REGISTRY.md per skill-resolver protocol
      
      Skills to load: /xray-cli, /acli
      
      Exact instructions:
        1. For each TC in the chunk:
           a. [TMS_TOOL] Create Test: project=<PROJECT_KEY>, type={Cucumber|Manual}, title="{per TC naming convention}", components=[{module}] (mandatory — affected product module). For Manual: create WITHOUT inline steps (Xray Cloud drops steps on create), then add each step via [TMS_TOOL] add-step. For Cucumber: pass gherkin={from the session design artifact}.
           b. Capture the returned issue key as <TEST_KEY>.
           c. [ISSUE_TRACKER_TOOL] Update Issue: issue=<TEST_KEY>, description={full Description template per jira-test-management.md §7}.
           d. [TMS_TOOL] AddTests: testSet=<ATS_KEY>, tests=[<TEST_KEY>].    # Set-first — ATS membership; Xray-internal, creates NO Jira link
           e. [TMS_TOOL] AddTests: testPlan=<ATP_KEY>, tests=[<TEST_KEY>].   # Xray-internal membership only — creates NO Jira link
           f. [TMS_TOOL] AddTests: execution=<ATR_KEY>, tests=[<TEST_KEY>].  # Xray-internal membership only — creates NO Jira link
           g. Jira-layer design/execute edges (SEPARATE from steps d/e/f): the Xray attach creates NO Jira links (confirmed, traceability-linking.md §9), so create them explicitly via [ISSUE_TRACKER_TOOL] (/acli): [ISSUE_TRACKER_TOOL] Link Issues linkType={{jira.link_types.test_design.name}} (ATP `designs` TC) and linkType={{jira.link_types.test_execute.name}} (ATR `executes` TC), then verify direction per traceability-linking.md §2/§4.
           h. Do NOT link the Test to the Story <STORY_KEY> directly — coverage aggregates to the Story through the ATS→Story link (the ATP/ATR links are administrative only).
        2. Apply labels per the methodology naming convention (see `tms-conventions.md` §Labels) and verify components landed on every created Test (mandatory field — never leave one empty).
      
      Report format:
        JSON array per TC:
        [
          {
            "tc_local_id": "<spec id>",
            "issue_key": "<PROJ>-<N>",
            "in_ats": true,
            "linked_to_atp": true,
            "linked_to_atr": true,
            "designs_link": true,
            "executes_link": true,
            "linked_to_story": false,
            "errors": []
          },
          ...
        ]
        Trailing summary: { "chunk": <I>, "created": K, "failed": 0|N, "duration_seconds": <int> }
      
      Rules:
        - Do NOT modify the ATS, ATP or ATR — only add/link new tests to them.
        - Do NOT exceed 10 sustained writes/sec inside the subagent (xray-cli already throttles, but be aware).
        - On 429 or 5xx: retry with exponential backoff up to 3 times, then mark the TC as failed and continue with the rest of the chunk.
        - On 4xx (excluding 429): stop the chunk and report partial state.
        - Critical Rule #8 (File Operations): never overwrite an existing TC silently — if the summary already exists, report and skip.
      ```
      
      ##### Modality jira-native (no Xray plugin; subagent loads `/acli`)
      
      Briefing (7 components per `agentic-qa-core/references/briefing-template.md`):
      
      ```
      Goal: Create <K> Jira Test issues in project <PROJECT_KEY> for chunk <I>/<TOTAL>, link each to the Story's ATS <ATS_KEY> via "is tested by" (TC→ATS membership link — jira-native carve-out), and return their issue keys. Only when NO ATS exists (Test Set work type absent from the instance): link each Test to the parent Story <STORY_KEY> directly via "is tested by" (the cascade's last resort).
      
      Context docs:
        - .session/test-documentation/<scope>/ (session contract artifact — the TC designs Phase 1-2 wrote; the definitions for this chunk live here, NOT in test-specs/, which holds keys only)
        - .agents/jira-fields.json (custom field IDs auto-discovered by `bun run jira:sync-fields`)
        - .agents/jira-required.yaml (custom-field manifest)
        - .agents/skills/test-documentation/references/jira-setup.md §3 (Modality jira-native field layout)
        - .agents/skills/test-documentation/references/jira-test-management.md §7 (Description template)
      
      Project Standards (auto-resolved): pulled from .agents/skills/REGISTRY.md per skill-resolver protocol
      
      Skills to load: /acli
      
      Exact instructions:
        1. For each TC in the chunk:
           a. [ISSUE_TRACKER_TOOL] Create Issue: project=<PROJECT_KEY>, issueType=Test, summary="{per TC naming convention}", priority={Critical|High|Medium|Low}, labels=[regression, ...], components=[{module}] (mandatory — affected product module), epic=<REGRESSION_EPIC_KEY>.
           b. Capture the returned issue key as <TEST_KEY>.
           c. [ISSUE_TRACKER_TOOL] Update Issue: issue=<TEST_KEY>, description={full Description template per jira-test-management.md §7}, fields={ {{jira.test_status}}: Draft, {{jira.to_be_automated}}: <bool> }.
           d. With ATS: [ISSUE_TRACKER_TOOL] Link Issues: linkType={{jira.link_types.test.name}}, outward=<TEST_KEY>, inward=<ATS_KEY>.   # ATS is tested by Test (membership link)
              Without ATS (work type absent): [ISSUE_TRACKER_TOOL] Link Issues: linkType={{jira.link_types.test.name}}, outward=<TEST_KEY>, inward=<STORY_KEY>.   # Story is tested by Test (last resort)
        2. Do NOT recreate ATP/ATR custom fields on the Story — those were already populated by the orchestrator before dispatch. Do NOT create the ATS — the orchestrator pre-created it (Set-first).
      
      Report format:
        JSON array per TC:
        [
          {
            "tc_local_id": "<spec id>",
            "issue_key": "<PROJ>-<N>",
            "linked_to_story": true,
            "errors": []
          },
          ...
        ]
        Trailing summary: { "chunk": <I>, "created": K, "failed": 0|N, "duration_seconds": <int> }
      
      Rules:
        - Custom-field IDs come from .agents/jira-fields.json — do NOT hardcode `customfield_*` numbers.
        - On 429 or 5xx: retry with exponential backoff up to 3 times.
        - On 4xx (excluding 429): stop the chunk and report partial state.
        - Critical Rule #8 (File Operations): never overwrite an existing TC silently — if the summary already exists, report and skip.
        - Critical Rule #1 (Login Credentials): ATLASSIAN_API_TOKEN comes from .env, never hardcode.
      ```
      
      ##### Aggregation in the main thread
      
      After all parallel subagents return, the orchestrator:
      
      1. Concatenates the JSON arrays into a single creation report.
      2. Sums totals (created / failed) and computes per-chunk duration.
      3. Feeds the issue-key list into the Traceability linking step (this section §4 + §5 step "for each TC").
      4. If any chunk reported `failed > 0`, surface the failed TCs to the user before proceeding to traceability linking. Do NOT auto-retry across chunks; let the user decide retry / skip / abort per the error protocol in `agentic-qa-core/references/orchestration-doctrine.md`.
      
      ##### Fallback to serial (N <= 10)
      
      For N <= 10 TCs, classify inline — the dispatch overhead is not justified. The serial flows below (Modality jira-xray and Modality jira-native) remain canonical. They also describe the procedure each parallel subagent runs internally for its assigned chunk.
      
      #### Modality jira-xray
      
      > **Prerequisite**: Load `/xray-cli` and `/acli` skills before executing commands below.
      
      ```
      # Set-first: the ATS comes FIRST — it is the coverage backbone.
      [TMS_TOOL] Create TestSet:                        # find-or-create — MANDATORY per Story
        project: {{PROJECT_KEY}}
        title: ATS: {US_ID}: {story title}
        components: {inherited from the source Story}   # mandatory (exemption is feature-level TS: only)
        # Parent Epic: QA Test Artifacts
      
      [ISSUE_TRACKER_TOOL] Link Issues:
        linkType: {{jira.link_types.test.name}}   # Story is tested by Test Set (ATS) — THE coverage-panel link
        outward: {ATS_KEY}
        inward:  {STORY_KEY}
      
      [TMS_TOOL] Create TestPlan:                 # find-or-create — the item usually exists from
        project: {{PROJECT_KEY}}                  # /sprint-testing Stage 1 (pre-sprint content lives in
        title: ATP: {STORY-KEY}: {story title}    # the Story field {{jira.acceptance_test_plan}})
        components: {inherited from the source Story}   # mandatory
        # Parent Epic: QA Master Test Plan
      
      [TMS_TOOL] Create Execution:
        project: {{PROJECT_KEY}}
        title: ATR: {STORY-KEY}: Story Testing
        testPlan: {ATP_KEY}
        environment: {from session context}
        components: {inherited from the source Story}   # mandatory
        # Parent Epic: QA Test Artifacts
      
      [ISSUE_TRACKER_TOOL] Link Issues:
        linkType: {{jira.link_types.test.name}}   # Story is tested by Test Plan (ATP) — administrative, no coverage
        outward: {ATP_KEY}
        inward:  {STORY_KEY}
      
      [ISSUE_TRACKER_TOOL] Link Issues:
        linkType: {{jira.link_types.test.name}}   # Story is tested by Test Execution (ATR) — administrative, no coverage
        outward: {ATR_KEY}
        inward:  {STORY_KEY}
      
      [TMS_TOOL] Create Test:
        project: {{PROJECT_KEY}}
        type: Cucumber | Manual | Generic
        title: {per TC naming convention}
        components: [{module}]                      # mandatory — affected product module
        # Cucumber/Generic: pass gherkin/definition here.
        # Manual: create WITHOUT inline steps (Xray Cloud drops steps on create),
        #         then add each step via [TMS_TOOL] add-step.
      
      [TMS_TOOL] AddTests:                          # Set-first — ATS membership (Xray-internal, NO Jira link)
        testSet: {ATS_KEY}
        tests: [{TEST_KEY}]
      [TMS_TOOL] AddTests:                          # Xray-internal membership only — creates NO Jira link
        testPlan: {ATP_KEY}                         # test list derived from the ATS membership
        tests: [{TEST_KEY}]
      [TMS_TOOL] AddTests:                          # Xray-internal membership only — creates NO Jira link
        execution: {ATR_KEY}                        # test list derived from the ATS membership
        tests: [{TEST_KEY}]
      
      # Jira-layer coverage edges (ATP designs TC, ATR executes TC). The AddTests
      # calls above create NO Jira links (confirmed, traceability-linking.md §9) — these
      # are SEPARATE from the Xray-internal membership and MUST be created explicitly:
      [ISSUE_TRACKER_TOOL] Link Issues:
        linkType: {{jira.link_types.test_design.name}}    # ATP designs TC / TC is designed by ATP
        outward: {ATP_KEY}
        inward:  {TEST_KEY}
      [ISSUE_TRACKER_TOOL] Link Issues:
        linkType: {{jira.link_types.test_execute.name}}   # ATR executes TC / TC is executed by ATR
        outward: {ATR_KEY}
        inward:  {TEST_KEY}
      # Do NOT link the Test to {STORY_KEY} directly while the ATS exists — coverage flows
      # through the ATS->Story link. Direct TC->Story is the cascade's last resort (no ATS).
      # Resolve slugs + verify direction per traceability-linking.md §2/§4.
      ```
      
      #### Modality jira-native — DEGRADED FALLBACK ONLY (Test Plan / Test Execution work types unavailable)
      
      > **Items first**: by excellence a native Jira `Test Plan` issue (`ATP: {STORY-KEY}: {story title}`)
      > and `Test Execution` issue (`ATR: {STORY-KEY}: Story Testing`) are created in jira-native too —
      > use the `[TMS_TOOL] Create TestPlan` / `Create Execution` blocks above, since both are native
      > Jira work types. The Story-field path below is the **degraded fallback**, used ONLY when those
      > work types are absent from the instance.
      >
      > **ATS in jira-native**: instance **has the Test Set work type** → create the ATS item
      > (`ATS: {US_ID}: {story title}`, parent QA Test Artifacts, components inherited from the
      > Story), link it to the Story (`is tested by`), and express membership as **TC→ATS issue
      > links** (carve-out: the "membership is never a link" rule is xray-only). Work type
      > **absent** → **no ATS**: link each TC directly to the Story (the cascade's last-resort
      > edge, as in the block below).
      >
      > **Prerequisite**: Load `/acli` skill before executing commands below.
      
      ```
      # ATP — fallback only: lives on the Story when no Test Plan work type
      [ISSUE_TRACKER_TOOL] Update Issue:
        issue: {STORY_KEY}
        fields:
          {{jira.acceptance_test_plan}}: {Test Analysis body}
        labels: +shift-left-reviewed
      
      [ISSUE_TRACKER_TOOL] Add Comment:
        issue: {STORY_KEY}
        body: "=== ATP: {STORY-KEY}: {story title} ===\n{Test Analysis body}"
      
      # ATR — fallback only: lives on the Story when no Test Execution work type
      [ISSUE_TRACKER_TOOL] Update Issue:
        issue: {STORY_KEY}
        fields:
          {{jira.acceptance_test_results}}: {Test Report body}
      
      [ISSUE_TRACKER_TOOL] Add Comment:
        issue: {STORY_KEY}
        body: "=== ATR: {STORY-KEY}: Story Testing ===\n{Test Report body}"
      
      # TC — Jira-native Test issue
      [ISSUE_TRACKER_TOOL] Create Issue:
        project: {{PROJECT_KEY}}
        issueType: Test                              # or Task + a Test Type custom field
        summary: {per TC naming convention}
        epic: {REGRESSION_EPIC_KEY}
        labels: [regression, ...]
        components: [{module}]                       # mandatory — affected product module
      
      [ISSUE_TRACKER_TOOL] Update Issue:
        issue: {TEST_KEY}
        description: {full TC template}
        fields:
          Test Status: Draft
      
      # With a Test Set work type (ATS exists): membership is a TC→ATS issue link
      [ISSUE_TRACKER_TOOL] Link Issues:
        linkType: {{jira.link_types.test.name}}   # ATS is tested by Test (membership link)
        outward: {TEST_KEY}
        inward:  {ATS_KEY}
      
      # Without a Test Set work type (no ATS): direct Story link — the cascade's last resort
      [ISSUE_TRACKER_TOOL] Link Issues:
        linkType: {{jira.link_types.test.name}}   # Story is tested by Test
        outward: {TEST_KEY}
        inward:  {STORY_KEY}
      ```
      
      ### Update
      
      > **Prerequisite**: Load `/xray-cli` skill (Modality jira-xray). In Modality jira-native, load `/acli` — these update calls become `[ISSUE_TRACKER_TOOL] Update Issue` on the Story or Test customfields.
      
      ```
      [TMS_TOOL] Update ATP:
        id: {from ATP ID}
        results: {from ATR name}
        analysis: {from test analysis content}
        complete: true
      
      [TMS_TOOL] Update ATR:
        id: {from ATR ID}
        report: {from test report content}
        complete: true
      
      [TMS_TOOL] Update TC:
        id: {from TC ID}
        status: PASSED
        workflow-status: Candidate
        precondition: {from test environment details}
        spec: {from step-by-step specification}
      ```
      
      ### Verify traceability
      
      > **Prerequisite**: Load `/xray-cli` skill (Modality jira-xray). In Modality jira-native, load `/acli` and walk the links manually via `[ISSUE_TRACKER_TOOL] Search Issues`.
      
      ```
      [TMS_TOOL] Verify Traceability:
        issue: {from ticket ID}
      ```
      
      Expected output: all links verified — US `is tested by` ATS (coverage), ATP and ATR (administrative); each TC a member of the ATS, `is designed by` ATP and `is executed by` ATR; no direct US↔TC link needed while the ATS covers them (a direct link is valid only as the cascade's last resort, when no ATS exists). If any link is missing, apply the fixes in §10.
      
      ---
      
      ## 10. Fixing broken traceability
      
      Common failure modes and their fixes:
      
      | Issue | Fix |
      |-------|-----|
      | TC has NO path to its Story (not in an ATS, not in an ATP, no direct link) | **This is the actual defect** — it is an ORPHAN. Resolve by the cascade: add it to the Story's ATS (create the ATS if missing); else no ATS possible → link TC→Story directly (`is tested by`, last resort) |
      | Story has no ATS | Create `ATS: {US_ID}: {story title}` (parent QA Test Artifacts, components from the Story), link it to the Story (`is tested by`), add ALL the Story's TCs |
      | TC not a member of the Story's ATS | Add it (jira-xray: Xray-internal via `/xray-cli`; jira-native: TC→ATS issue link) |
      | TC linked directly to Story WHILE an ATS covers it | Redundant, not fatal — prefer moving the TC into the ATS and dropping the direct link. A direct TC→Story link on its own is the cascade's documented last resort (no ATS), NOT a defect to remove |
      | TC not designed-by ATP | Link ATP `designs` TC (`test_design`) |
      | TC not executed-by ATR | Link ATR `executes` TC (`test_execute`) |
      | ATP not linked to ATR | Update ATP with ATR reference |
      | ATS not linked to Story | Link Story `is tested by` ATS (`test`) — without it the coverage panel shows Not Covered |
      | ATP not linked to Story | Link Story `is tested by` ATP (`test`) |
      | ATR not linked to Story | Link Story `is tested by` ATR (`test`) |
      | TC name doesn't follow convention | Rename TC to `{US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]` |
      | ATP name wrong | Rename to `ATP: {STORY-KEY}: {story title}` |
      | ATR name wrong | Rename to `ATR: {STORY-KEY}: Story Testing` |
      | ATS name wrong | Rename to `ATS: {US_ID}: {story title}` |
      | TC has no AC link | Identify which AC it covers and add the reference |
      
      Procedure:
      
      1. Run `[TMS_TOOL] Verify Traceability` — read the gap list.
      2. For each issue, apply the fix above.
      3. Re-run `[TMS_TOOL] Verify Traceability` to confirm all links are resolved.
      4. Log what was fixed in a comment on the User Story for audit trail.
      
      ---
      
      ## 11. Reference implementation — Jira + Xray
      
      The canonical implementation this file was derived from uses Jira with Xray. Mapping:
      
      | Generic concept | Jira/Xray implementation |
      |-----------------|-------------------------|
      | Test Case ID | Jira issue key (e.g., `PROJ-123`) |
      | Test Case issue type | Xray Test |
      | Test Plan | Jira `Test Plan` issue (items first; Story custom field = degraded fallback only) |
      | Test Execution (ATR) | Jira `Test Execution` issue (Xray adds the run engine) |
      | Test Set (ATS) | Jira `Test Set` issue — mandatory per Story; its `is tested by` link to the Story is the coverage-panel anchor |
      | Regression Epic | Jira Epic resolved by configured name (`qa.qa_epics.test_repository_epic.name` — "QA Test Repository"), then cached key; carries the `QA-Artifact` label |
      | Results import | Xray REST API (JUnit / Cucumber formats) |
      | CLI | `bun xray` (load `/xray-cli` skill) |
      
      Other TMS tools (Coda, Azure DevOps, TestRail) implement the same five-entity model with different issue types. The naming conventions, linking order, and traceability rules above apply unchanged.
      
    • tms-conventions.md 38.8 KB
      # TMS Conventions — Naming, Formats, Fields, Labels, ROI
      
      The rulebook for documenting tests in any TMS. Read this when naming a TC, picking a format (Gherkin vs Traditional), setting fields, choosing labels, transitioning states, or scoring ROI.
      
      ---
      
      ## 1. Central principle
      
      Document only tests that are already validated. The TMS is a tracking and regression-protection tool, not an exploration tool.
      
      ```
      Explore (validate feature)   ->   Analyze (classify scenarios)   ->   Document (create TMS artifacts)
           ^                                                                        |
           |                                                                        v
           +--- NEVER document here                                 Document ONLY stable tests here
      ```
      
      ### When to create a TC
      
      | Situation | Action | Reason |
      |-----------|--------|--------|
      | Feature explored and stable | Create TC | Behavior confirmed; documentation is reliable |
      | Feature has critical open bugs | Wait for fixes | Documenting unstable behavior creates maintenance debt |
      | Before any exploration | Do NOT document | You do not know what the system actually does yet |
      | Bug fix verified | Create regression TC | Prevent recurrence |
      | Hotfix deployed | Create smoke TC | Critical path must be continuously validated |
      
      Decision rule: if you cannot confidently describe the expected behavior, the feature is not ready for TMS documentation.
      
      ---
      
      ## 2. TC naming convention (mandatory)
      
      ### Format (all tools, all modalities)
      
      The prefix is **ALWAYS the User Story key** (`{US_ID}`) — never the Test Set ID — in every modality (Jira-native, Xray with Test Sets, Xray without Test Sets).
      
      ```
      {US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]
      ```
      
      > Under Modality jira-xray, Test Set membership is **Xray-internal state** (managed via `/xray-cli`, read via `bun xray test enrich`) — NEVER a Jira issue link and NEVER baked into the TC title. Jira-native carve-out: with a Test Set work type present, membership IS expressed as TC→ATS issue links (still never in the TC title).
      
      ### Components
      
      | Component | What it is | Examples |
      |-----------|-----------|----------|
      | `US_ID` | User Story ID (always the prefix) | `GX-101` |
      | `TC#` | Sequential TC number | `TC1`, `TC2`, `TC3` |
      | `CORE` | Expected outcome (verb + object), phrased after `should` | `grant access`, `reject login`, `cap input` |
      | `CONDITIONAL` | Optional connector clause (`when …` / `if …`) plus optional `given …` | `when credentials are valid`, `if password is incorrect`, `when cart is empty given a logged-in user` |
      
      ### Examples by test type
      
      | Type | CORE | CONDITIONAL | Full title |
      |------|------|-------------|-----------|
      | Positive | grant access | when credentials are valid | `GX-101: TC1: should grant access when credentials are valid` |
      | Negative | reject login | if password is incorrect | `GX-101: TC2: should reject login if password is incorrect` |
      | Boundary | cap input | when exceeding 50 chars | `GX-101: TC3: should cap input when exceeding 50 chars` |
      | Edge | block checkout | when cart is empty given a logged-in user | `GX-101: TC4: should block checkout when cart is empty given a logged-in user` |
      
      ### Anti-patterns (reject)
      
      | Wrong | Right | Why |
      |-------|-------|-----|
      | `Login test` | `GX-101: TC1: should grant access when credentials are valid` | Missing ID, TC#, outcome, condition |
      | `Login - error` | `GX-101: TC2: should show auth error when password is incorrect` | Too vague |
      | `TC1: Test form` | `GX-101: TC1: should submit form when all fields are filled` | Missing ID; outcome not specific |
      | `should work correctly` | `GX-101: TC1: should grant access when credentials are valid` | No concrete outcome, no condition — vague, NOT because of the word "should" |
      
      ### Code-side naming (KATA)
      
      The same TC, when implemented in code, uses:
      
      ```
      test('PROJ-101: should <behavior> when <condition>', ...)
      ```
      
      The prefix is the TMS-generated key (e.g., `PROJ-101`), not an invented convention. The `@atc('PROJ-101')` decorator carries the same key. This is what makes traceability work end-to-end.
      
      ---
      
      ## 3. Naming for other TMS artifact types
      
      All Plans and Runs follow one **unified grammar** — the QA planning ladder:
      
      ```
      {ACRONYM}: {scope-id}: {descriptor}
      ```
      
      - **ACRONYM** — `FTP` · `STP` · `ATP` (Plans) · `STR` · `ATR` (Runs — FTR retired: feature results are read from the per-Story ATRs and reviewed at sprint close next to the STR; the results side has NO aggregation edge) · `ATS` (Acceptance Test Set, per-Story — mandatory) · `TS` (feature-level Test Set — optional grouping) · `ReTest` (bug re-test Run). A reader / JQL sees altitude + plan-vs-run in the first token, and Plan pairs with Run visually.
      - **scope-id** — the key of the thing under test at that altitude: feature-Epic key, `Sprint#{N}`, or Story key.
      - **descriptor** — human-readable; embeds the testing term where required (`Story Testing`, `Feature Testing`, `Regression Testing`).
      
      | Artifact | Jira work type | Format | Example |
      |----------|----------------|--------|---------|
      | User Story | Story | `{{PROJECT_KEY}}-{n}` | `PROJ-123` |
      | ATP — Story Test Plan | Test Plan | `ATP: {STORY-KEY}: {story title}` | `ATP: PROJ-123: Apply discount at checkout` |
      | ATR — Story Test Execution | Test Execution | `ATR: {STORY-KEY}: Story Testing` | `ATR: PROJ-123: Story Testing` |
      | FTP — Feature Test Plan | Test Plan | `FTP: {EPIC-KEY}: {feature}` | `FTP: PROJ-42: Checkout & Payments` |
      | STP — Sprint Test Plan | Test Plan | `STP: Sprint#{N}: {objective}` | `STP: Sprint#30: Payments hardening` |
      | STR — Sprint Test Results | Test Execution | `STR: Sprint#{N}: Regression Testing` | `STR: Sprint#30: Regression Testing` |
      | ATS — Acceptance Test Set (per-Story, **mandatory**) | Test Set | `ATS: {US_ID}: {story title}` | `ATS: GX-101: Pay with credit card` |
      | Test Set (TS — feature-level, **optional**) | Test Set | `TS: {EPIC-KEY\|module}: Validate {feature}` | `TS: GX-42: Validate credit card payment` |
      | ReTesting (RTX) | Test Execution | `ReTest: {BUG-KEY}: {summary}` | `ReTest: GX-202: Does not show error when entering incorrect password` |
      | Precondition | Precondition | `{COMPONENT}: {required state}` (no ladder acronym) | `Payment: Authenticated user with a saved card` |
      
      Notes:
      
      - **Items over fields (by excellence).** Every Plan is a **Test Plan** issue and every Run is a **Test Execution** issue — in BOTH modalities (these are native Jira work types, Xray-independent). The Story custom field for ATP/ATR is a **degraded fallback ONLY**, used when those work types are unavailable in the instance. See `tms-architecture.md` §Container per modality.
      - **QA-process Epic homes** (3-axis model): every **Test Plan** (FTP/STP/ATP) parents to **QA Master Test Plan**; every **Test Execution** (STR/ATR), **Test Set** (ATS and TS), and **Precondition** parents to **QA Test Artifacts**; every **Test** (TC) parents to **QA Test Repository**. The parent says only which QA bucket; scope (Story / feature / Sprint) travels on an issue link, product area on `components` — mandatory on Tests, Test Plans, Test Executions AND the per-Story **ATS** (all inherit the source Story's components); **OPTIONAL on the feature-level `TS:` only** (a feature Set can span modules; its member Tests carry them).
      - **`ReTest:`** is already prefix-style and stays as-is. It is a Test Execution under **QA Test Artifacts**.
      - **Precondition**: the **title states the required state**, the **content holds the setup steps** — the two are kept distinct (`Payment: Authenticated user with a saved card` titles the state; the steps to reach it live in the issue body).
      - **ATS is mandatory per Story** (even with a single TC) and holds ALL the Story's TCs; the ATP's and the Execution's test lists derive from its membership (Set-first). Its ATS→Story `is tested by` link is what fills the Xray coverage panel — ATP/ATR links do not (live-verified). The feature-level `TS:` survives as an **optional** grouping (smoke / regression / feature suite).
      - `Validate` stays the feature-level Test Set grouping word (consistent with the code `describe()` law); the `TS:` prefix adds the work-type / altitude signal on top. The per-Story `ATS:` mirrors the Story title instead.
      
      ---
      
      ## 4. TC required fields
      
      Every TC in the TMS must have these fields populated. Exact field names vary by tool; the information must be present.
      
      ### Always required
      
      | Field | Type | Purpose | Example |
      |-------|------|---------|---------|
      | ID | Auto-generated | Unique identifier | `PROJ-101` |
      | Summary / Title | Text | TC name following naming convention | `GX-101: TC1: should ...` |
      | Description / Steps | Long text | Gherkin or traditional step table | See §6 |
      | Test Status | Select | Execution state | `NOT RUN` / `PASSED` / `FAILED` |
      | Workflow Status | Select | Lifecycle state | `Draft`, `In Design`, `READY`, `In Review`, `Candidate`, `In Automation`, `Pull Request`, `AUTOMATED`, `MANUAL`, `DEPRECATED` (§5) |
      | Priority | Select | Business risk priority | `Critical` / `High` / `Medium` / `Low` |
      | Labels | Multi-select | Classification tags | `regression`, `smoke`, `e2e` |
      | Components | Multi-select | Affected product module — mandatory (defect-management doctrine Part 3) | `Payments` |
      | Automation Candidate | Boolean | Automation flag | true / false |
      | Parent | Link | Regression Epic | Epic: `QA Test Repository` |
      | Linked Story | Link | Traceability to requirement — **cascade**: primary through the Story's ATS (membership + ATS→Story `is tested by`, the coverage-panel link); jira-xray adds ATP (`is designed by`) / ATR (`is executed by`) administrative edges; jira-native without a Test Set work type links the TC to the Story directly (`is tested by` — the cascade's last resort) | `PROJ-100` (direct, last resort) |
      
      ### Conditional
      
      | Field | When required | Purpose |
      |-------|--------------|---------|
      | Linked Bug | When the TC is blocked by a bug | "is blocked by" |
      | Automation Comment | When Automation Candidate = Yes | Justification: ROI score, reasoning |
      | Test Data | When the test needs specific data | Inputs, preconditions, DB state |
      
      ### IQL: Test Status (Workflow) vs Execution Status (Run) — load-bearing
      
      These are **two independent fields** with two independent lifecycles. Mixing them is the most common cause of bad dashboards, bad JQL, and stale triage decisions.
      
      | Dimension | **Test Status (Workflow)** | **Execution Status (Run)** |
      |-----------|----------------------------|-----------------------------|
      | Lives on | The Test issue itself | A single Test Run inside a Test Execution (Xray) or a Test Status custom field on the Test issue (Jira-native) |
      | Answers | "Where is this TC in its documentation / automation lifecycle?" | "Did the TC pass the last time we ran it?" |
      | Values | `Draft` / `In Design` / `READY` / `MANUAL` / `In Review` / `Candidate` / `In Automation` / `Pull Request` / `AUTOMATED` / `DEPRECATED` | `TODO` / `EXECUTING` / `PASS` / `FAIL` / `ABORTED` / `BLOCKED` |
      | Changed by | QA analyst, QA engineer (manual transitions) | Execution — either a human runner or `[TMS_TOOL] Import Results` in CI |
      | Persists across runs | Yes (workflow is the long-lived state) | No (each Test Run carries its own status; history lives in the Test Execution) |
      | Used by | Planning, ROI prioritization, automation intake | Regression reporting, GO / NO-GO, CI health |
      
      **Canonical Execution Status values** (used in every TMS):
      
      | Value | Icon | Meaning | Next action |
      |-------|------|---------|-------------|
      | `TODO` | gray | Not yet executed in this run | Execute or skip |
      | `EXECUTING` | blue | Currently running | Wait for completion |
      | `PASS` | green | Passed in this run | Keep in regression |
      | `FAIL` | red | Failed in this run | Investigate / file bug |
      | `ABORTED` | orange | Execution stopped (crash, timeout, user-abort) | Review environment, retry |
      | `BLOCKED` | yellow | Could not execute (missing data, dep down) | Resolve blocker, retry |
      
      **What this means for reporting**:
      
      - "TC is `AUTOMATED`" (workflow) is compatible with "last Test Run was `FAIL`" (run). The TC is live in CI, but it failed today.
      - ATR's "PASSED / FAILED / PASSED WITH ISSUES" rollup comes from the **Execution Status** across all TCs in the ATR, not from the Test Status.
      - A TC in `Draft` (workflow) never has an Execution Status — it has not been executed yet.
      - When the legacy / current skill says "Test Status: NOT RUN / PASSED / FAILED", that refers to the **Execution Status** field in Jira-native mode (where there is no separate Test Run entity); in Xray mode, the equivalent lives on the Test Run and `NOT RUN` maps to `TODO`.
      
      ---
      
      ## 5. Workflow state machine
      
      > **Substrate reference — AUTHORITATIVE**: `.agents/jira-workflows.json` (`work_types.test_case`) is the source of truth for every status and transition name below; a status absent from that file does not exist in the instance (`Approved`, `Automating`, `Merge Request` are common inventions and none of them exist). Names below are copied from the canonical UPEX Jira workflow declared in `.agents/jira-workflows.json` (see `.agents/jira-required.yaml` `work_types.test_case` for the methodology's required slugs). Skills resolve these via `{{jira.status.test_case.<slug>}}` and `{{jira.transition.test_case.<slug>}}`. If your project's Jira renames any state or transition, run `bun run jira:sync-workflows` to refresh the substrate so slug -> literal-name mapping stays correct.
      
      ### The full lifecycle
      
      ```
                                                          +------------+
                                                          | DEPRECATED |
                                                          +------------+
                                                                ^
                                                                | Any state
                                                                |
        Draft -> In Design -> READY -+-- for manual --> MANUAL -+
                               ^     |                          |
                    back       |     +-- automation review --> In Review
                               |                                   |
                               |                                   +-- approve to automate --> Candidate
                               |                                                                   |
                               |                                                                   +-- start automation --> In Automation
                               |                                                                                                |
                               |                                                                                                +-- create PR --> Pull Request
                               |                                                                                                                      |
                               |                                                                                                                      +-- merged --> AUTOMATED
                               |                                                                                                                                        |
                               +---------------------------------------------------------------------------------------------------------- back (rework) ---------------+
      ```
      
      ### State definitions
      
      | State | Description | Entry | Exit |
      |-------|-------------|-------|------|
      | **Draft** | Newly created, placeholder | TC artifact created | Steps / Gherkin writing begins |
      | **In Design** | Steps being written | Draft + linked story | Steps reviewable |
      | **READY** | Documented and complete | Steps reviewed | Manual or automation decision |
      | **MANUAL** | Manual regression only | Not an automation candidate | Can be reconsidered later |
      | **In Review** | Automation ROI under evaluation | Marked as candidate | Approved or rejected |
      | **Candidate** | Approved for automation | Positive ROI | Automation begins |
      | **In Automation** | ATC being implemented | Developer starts coding | PR created |
      | **Pull Request** | Code submitted, awaiting merge | PR opened | PR merged |
      | **AUTOMATED** | Running in CI/CD | PR merged | Final (unless deprecated) |
      | **DEPRECATED** | Obsolete | Feature removed | Can be recovered (`recover` -> Draft) |
      
      ### Rules
      
      1. **No skipping** — Draft cannot jump to AUTOMATED.
      2. **Backward transitions are limited** — the `back_*` family (one step back per state) plus "any state to DEPRECATED".
      3. **MANUAL is not a dead end** — MANUAL can later move to In Review, Candidate, or AUTOMATED if ROI changes.
      4. **AUTOMATED is the goal** — move as many as reasonable into AUTOMATED.
      
      ### Transition names (used in `[ISSUE_TRACKER_TOOL] Transition Issue`)
      
      | Transition | From -> To | Trigger |
      |-----------|-----------|---------|
      | `start design` | Draft -> In Design | Documentation begins |
      | `ready to run` | In Design -> READY | Documentation complete |
      | `for manual` | READY -> MANUAL | Not a candidate |
      | `automation review` | READY -> In Review | Evaluate ROI |
      | `approve to automate` | In Review -> Candidate | Positive ROI |
      | `start automation` | Candidate -> In Automation | Stage 5 begins |
      | `create PR` | In Automation -> Pull Request | PR created (often auto) |
      | `merged` | Pull Request -> AUTOMATED | PR merged (often auto) |
      | `Deprecated` | Any -> DEPRECATED | TC retired |
      | `recover` | DEPRECATED -> Draft | TC revived |
      
      ---
      
      ## 6. TC formats — Gherkin vs Traditional
      
      Two formats are supported. Pick based on the automation path.
      
      ### Format selection rule
      
      | Criterion | Gherkin | Traditional |
      |-----------|---------|-------------|
      | Automation candidate | Yes | No |
      | Steps deterministic | Yes | May vary |
      | Expected results exact | Yes | Subjective |
      | Requires human judgment | No | Yes |
      
      ### Gherkin (for Candidates — high-quality pattern)
      
      ```gherkin
      Feature: User Login
      
        Background:
          Given the system is in initial state
      
        @critical @smoke @regression @automation-candidate @{US_ID}
        Scenario Outline: should <outcome> <connector> <condition>
          """
          Bugs covered: {BUG-ID1}, {BUG-ID2}
          Related Story: {US_ID}
          Priority: Critical
          ROI Score: 5.2
          """
      
          # === PRECONDITIONS (tester / script builds them) ===
          Given a <entity> exists with <identifier> in the database
          And <entity> has <quantity> <elements> where <quantity> <condition>
          And the user <authentication_state>
      
          # === ACTION ===
          When the user navigates to "<route>"
          And the user <main_action>
      
          # === VALIDATIONS ===
          Then <ui_element> is displayed with format "<expected_format>"
          And <additional_validation>
      
          # === EQUIVALENT PARTITIONS ===
          Examples: Happy path
            | entity | identifier | quantity | elements | condition | authentication_state | route | main_action | ui_element | expected_format | additional_validation |
            | ...    | ...        | ...      | ...      | ...       | ...                  | ...   | ...         | ...        | ...             | ...                   |
      
          Examples: Edge case
            | ... |
      
          Examples: Singular vs plural
            | ... |
      ```
      
      Required elements:
      
      | Element | Purpose |
      |---------|---------|
      | `Background` | Common context reused across scenarios |
      | `Scenario Outline` + `Examples` | Parameterization; one per equivalence partition |
      | Named `Examples:` | Clear partition labels (Happy path, Edge case, ...) |
      | `<variables>` | Placeholders; never hardcoded values |
      | `# === comments ===` | Visual structure (Preconditions / Action / Validations / Partitions) |
      | `"""` docstring | Metadata: bugs, story, priority, ROI |
      | Multi-tag | Priority + scope + automation + story ID |
      
      ### Traditional (for Manual TCs)
      
      ```
      | Step | Action                | Test Data        | Expected Result         |
      |------|----------------------|------------------|--------------------------|
      | 1    | Navigate to /login    | -                | Login form visible       |
      | 2    | Enter email           | user@example.com | Field shows entered val  |
      | 3    | Enter password        | Password123!     | Field is masked          |
      | 4    | Click Submit          | -                | Redirect to dashboard    |
      | 5    | Verify welcome message| -                | "Welcome, User" visible  |
      ```
      
      Use Traditional when: visual/subjective verification, exploratory elements, or explicitly marked `manual-only`.
      
      ### When to use which Gherkin construct
      
      | Construct | Use when |
      |-----------|----------|
      | Simple `Scenario` | Only 1 case, no variations |
      | `Scenario Outline` + `Examples` | Multiple equivalence partitions |
      | `Background` | Several scenarios share preconditions |
      
      ---
      
      ## 7. Variable pattern (mandatory for Gherkin)
      
      Never hardcode real data in TCs. Tests are executed repeatedly throughout the project's life; production/staging data changes. Use variables that describe the **type** of data.
      
      ### Placeholder style (mandatory)
      
      Variable placeholders in scenario steps are **`{snake_case}` in curly braces** — `{user_id}`, `{order_amount}`, `{discount_code}`. The only exception is a short uppercase symbol for a count or index (`{N}`), kept terse by convention. No hardcoded values in scenario steps; every value a step consumes is referenced by its `{snake_case}` name and resolved through the Variables table below. (This is distinct from the `<column>` angle-bracket syntax a `Scenario Outline` binds to its `Examples:` columns — angle brackets name a per-row Examples value, curly braces name a Variables-table lookup; see the `Examples:` vs `Variables` note below.)
      
      ### When to use a specific value
      
      Only when the acceptance criterion itself defines the value:
      
      ```gherkin
      # CORRECT - business rule defines the limit
      Then the field must accept maximum 500 characters
      
      # CORRECT - format is part of the requirement
      Then the rating is displayed in "X.X/5.0" format
      ```
      
      ### Before vs after
      
      ```gherkin
      # WRONG - hardcoded
      Given a mentor exists with user_id "550e8400-e29b-41d4-a716-446655440000"
      And the mentor has 23 reviews with average rating 4.7/5.0
      
      # CORRECT - variable pattern
      Given a verified mentor exists with {mentor_id} in the database
      And the mentor has {N} reviews where {N} > 0
      And the average rating {average} = sum of ratings / {N}
      ```
      
      ### Variables table (mandatory in TC Description)
      
      > **`Examples:` vs `Variables` — two different tables, do not conflate.** The
      > `Examples:` table (in the Gherkin §"Gherkin") supplies the **varying data values
      > per equivalence partition** — *what* changes each parameterized run (the
      > artifact-economy lever, doctrine §"Part 2.5"). The `Variables` table (here, in
      > the Description) explains **how to OBTAIN each variable at runtime** (the SQL /
      > source query) — it does not vary per run. Rule of thumb: a value that *changes
      > the case* → an `Examples` column; a value you must *look up to run the case* → a
      > `Variables` row. A parameterized TC typically has BOTH.
      
      Every TC with variables must include a table explaining how to obtain each one:
      
      ```
      | Variable     | Description                  | How to obtain                                                              |
      |--------------|------------------------------|----------------------------------------------------------------------------|
      | {mentor_id}  | Verified mentor UUID         | SELECT id FROM profiles WHERE role='mentor' AND is_verified=true LIMIT 1   |
      | {N}          | Review count                 | SELECT COUNT(*) FROM reviews WHERE subject_id = {mentor_id}                |
      | {average}    | Average rating               | SELECT AVG(rating) FROM reviews WHERE subject_id = {mentor_id}             |
      ```
      
      ### Benefits
      
      - **Durability**: the TC does not need updates when data changes.
      - **Portability**: works in local, staging, QA.
      - **Clarity**: the tester understands what they need.
      - **Automation**: scripts can parameterize dynamically.
      
      ---
      
      ## 8. Labels and tagging
      
      ### Required (scope — at least one)
      
      | Label | Meaning | When to apply |
      |-------|---------|--------------|
      | `smoke` | Critical path, must always pass | Core user journeys: login, checkout, main navigation. Aim for 10-20% of the suite. |
      | `regression` | Full regression suite | Any stable, documented TC |
      | `e2e` | End-to-end user journey | Tests spanning multiple features/modules |
      | `integration` | API-level integration | Tests validating API contracts between services |
      | `functional` | Isolated functional | Form validation, single-unit behavior |
      
      ### Automation status (applied during workflow)
      
      | Label | Meaning | When applied |
      |-------|---------|--------------|
      | `automation-candidate` | Marked for automation | After positive ROI |
      | `manual-only` | Cannot or should not be automated | Human judgment / visual / physical |
      | `automated` | Implemented in code | After PR merged and test runs in CI |
      
      ### Priority (optional)
      
      | Label | Maps to |
      |-------|---------|
      | `critical` | P1 |
      | `high` | P2 |
      | `medium` | P3 |
      | `low` | P4 |
      
      ### Rules
      
      1. Every TC gets `regression` unless it is explicitly throwaway or exploratory-only.
      2. `smoke` is exclusive — only critical business path TCs.
      3. `e2e` and `integration` describe **type**, not priority. A TC can be both `smoke` and `e2e`.
      4. `manual-only` and `automated` are mutually exclusive.
      5. `automation-candidate` is removed once the TC becomes `automated` or returns to `manual-only`.
      
      ---
      
      ## 9. ROI formula and automation decision
      
      ### The formula
      
      ```
      ROI = (Frequency x Impact x Stability) / (Effort x Dependencies) / 10
      ```
      
      The trailing `/ 10` is a **normalization constant, not a sixth factor**. Raw, the quotient over 1-5 factors spans `0.04 .. 125`; normalized it spans `0.004 .. 12.5`, which is the scale every threshold and worked example below reads on. Divide by 10, always. A neutral all-3s scenario scores `(3x3x3)/(3x3)/10 = 0.3` → Defer, consistent with "most scenarios should be Deferred".
      
      Each factor scored 1-5:
      
      | Factor | 1 | 2 | 3 | 4 | 5 |
      |--------|---|---|---|---|---|
      | **Frequency** (how often run) | Yearly / rarely | Every release | Every sprint | Daily | Every PR / commit |
      | **Impact** (if it fails) | Cosmetic | Minor inconvenience | Degrades UX | Blocks feature | Revenue / core business |
      | **Stability** (of the flow) | Very volatile, active dev | Unstable | Moderate, changes every sprint | Stable, minor changes | Unchanged for months |
      | **Effort** (to automate) | Trivial (minutes) | Low (hours) | Moderate (1-2 days) | High (several days) | Very high (week+) |
      | **Dependencies** | None / self-contained | 1-2 simple | 3-4 | 5+ | Complex externals |
      
      Effort and Dependencies are divisors — higher score = worse.
      
      ### ROI decision thresholds (strict)
      
      | Score | Decision | Action |
      |-------|----------|--------|
      | > 5.0 | **Automate** | Excellent ROI; include in regression |
      | 3.0 - 5.0 | **Automate with caution** | Evaluate if a simpler alternative exists |
      | 1.5 - 3.0 | **Case by case** | Prior bug? Critical flow? If no, defer |
      | 0.5 - 1.5 | **Probably defer** | Include only if prior bug |
      | < 0.5 | **Defer** | Not worth the maintenance cost |
      
      These thresholds are strict by design:
      
      1. Every test has maintenance cost.
      2. Most bugs do not recur after the first fix.
      3. Fewer well-chosen tests > many low-value tests.
      
      ### Component value bonus (reusability)
      
      ```
      Component Value = Base ROI x (1 + 0.2 x N)
      ```
      
      where `N` = number of E2E flows that reuse the TC. A moderate-ROI atomic like `authenticateSuccessfully` can cross out of the defer bands purely through reuse (base ROI 2.0, reused in 3+ flows: `2.0 x 1.6 = 3.2` -> Automate with caution).
      
      **`N` is a qualitative heuristic, not a measurement.** Nothing tracks it: `kata-manifest.json` registers Components and ATCs but records no call-sites, and no other tool in this repo counts how many E2E flows consume a given TC. So the formula above is an **illustration of the shape of the bonus**, not an arithmetic you can look up. Rules:
      
      1. **Estimate `N` qualitatively** from the ATP and the feature map — how many documented flows plausibly pass through this step — never from a grep or a manifest field that does not exist.
      2. **Cap the bonus at `N = 3`** (max multiplier `x1.6`). An estimate you cannot verify must not be able to triple a score.
      3. **Record the estimate in the ROI comment** alongside the five factors, e.g. `Reuse: N~3 (estimated from ATP: login, checkout, profile-edit). Bonus x1.6.` An unrecorded bonus is an unauditable one.
      
      > Future work: a manifest field (e.g. ATC call-site counts emitted by `bun run kata:manifest`) would make `N` measurable and let this bonus drop the cap.
      
      ### Phase 0 filter (applied BEFORE ROI)
      
      For every candidate, answer three questions:
      
      1. **Does it protect against FUTURE regressions?** If it was a one-time validation (typo, pluralization, rarely-touched code), defer.
      2. **Are there PRIOR bugs?** If yes, prioritize even at moderate ROI.
      3. **Is it APP-level or FEATURE-level?** XSS, a11y, performance, responsive are APP-level suites, not per-feature TCs.
      
      Phase 0 fails -> Deferred. Phase 0 passes -> apply ROI.
      
      ### Risk matrix (sanity cross-check)
      
      |                       | High probability | Medium | Low |
      |-----------------------|------------------|--------|-----|
      | **High impact** | P1 Critical | P2 High | P3 Medium |
      | **Medium impact** | P2 High | P3 Medium | P4 Low |
      | **Low impact** | P3 Medium | P4 Low | P5 Optional |
      
      | Priority | Meaning | Automation urgency | CI/CD behavior |
      |----------|---------|---------------------|----------------|
      | P1 Critical | System unusable if this fails | Automate immediately | Runs on every commit (smoke) |
      | P2 High | Major feature broken | Automate this sprint | Runs on PR merge |
      | P3 Medium | Feature degraded, workaround exists | When capacity allows | Runs nightly or pre-release |
      | P4 Low | Minor inconvenience | Evaluate ROI first | Runs weekly / on-demand |
      | P5 Optional | Nice-to-have | Keep manual unless trivial | Manual regression only |
      
      ### Marking a Candidate in the TMS
      
      > **Prerequisite**: Load `/xray-cli` skill (Modality jira-xray). In Modality jira-native, load `/acli` — the `[TMS_TOOL] Update test` call becomes `[ISSUE_TRACKER_TOOL] Update Issue` on the Test issue.
      
      ```
      [TMS_TOOL] Update test:
        test: {TEST_KEY}
        fields:
          automationCandidate: true
          labels: add "automation-candidate"
        comment: "ROI assessment: Frequency=4, Impact=5, Stability=4, Effort=2, Dependencies=1. ROI=4.0. Prior bug: BUG-XYZ. High-frequency critical path, low effort to automate."
      ```
      
      ---
      
      ## 10. TC identity — one TC, multiple assertions
      
      A TC is defined by **Precondition + Action**. All expected results from the same (precondition, action) pair belong to the **same TC**.
      
      ```
      Same TC (multiple assertions):
        Precondition: valid credentials + active account
        Action:       submit login
        Expected:     - redirect to dashboard
                      - auth token in response
                      - user profile accessible via /auth/me
                      - session cookie set
                      - welcome message shows user's name
      
      Different TCs (preconditions differ):
        TC-A: Precondition = valid credentials      -> Action = submit login -> Expected = success
        TC-B: Precondition = locked account         -> Action = submit login -> Expected = 423 error
        TC-C: Precondition = invalid credentials    -> Action = submit login -> Expected = 401 error
      ```
      
      Splitting one (precondition, action) into 5 "check panel A" / "check panel B" / ... TCs is a canonical anti-pattern.
      
      ### Equivalence Partitioning
      
      Inputs producing the **same output** -> one parameterized TC (Scenario Outline + Examples).
      Inputs producing **different outputs** -> separate TCs.
      
      Example: all invalid credentials (wrong email, wrong password, empty fields) producing 401 -> one parameterized TC `loginWithInvalidCredentials`. Locked account producing 423 -> separate TC.
      
      ### Boundary Value Analysis (REQUIRED wherever a range/limit exists)
      
      Test at the edges of equivalence classes: `min-1 · min · min+1` and `max-1 · max · max+1`, plus zero / empty / null / overflow. 7 chars (just below an 8-min) and 65 chars (just above a 64-max) are interesting; 30 chars in the middle of the valid range is not. EP without BVA misses off-by-one defects — when an AC names any numeric range, string length, collection size, date window, quota, or pagination limit, boundary TCs are mandatory, not optional.
      
      ### State-Transition (REQUIRED for stateful entities)
      
      When an entity has a status / lifecycle (draft → submitted → approved; cart → paid → shipped; active → locked → closed), derive one TC per **valid transition** AND one per **invalid transition** (a trigger fired in a state that should reject it — e.g. "approve an already-closed item → rejected"). The invalid transitions are where defects concentrate; testing only the target state is insufficient.
      
      ### Decision Tables (REQUIRED when 2+ conditions interact)
      
      When the outcome depends on a combination of conditions (role × feature-flag × account-status), build a decision table: enumerate the condition combinations, collapse impossible/equivalent columns, and derive one TC per surviving rule. Do not test only the combinations the AC happens to mention.
      
      ### Pairwise / combinatorial (REQUIRED when 3+ combinable factors)
      
      When 3+ independent factors each have multiple values (browser × locale × plan × payment-method), the full grid explodes. Use all-pairs selection — cover every pair of factor-values at least once — and **log that pairwise was applied** so the reduction is visible, not a silent cap.
      
      > Full canon + worked example: `agentic-qa-core/references/test-design-doctrine.md`. The techniques decide the TC set; ROI (SKILL.md Phase 2) then decides which TCs are Candidate / Manual / Deferred.
      
      ---
      
      ## 11. Traceability links
      
      ### Every TC must link to
      
      | Link | Type | When |
      |------|------|------|
      | ATS (Acceptance Test Set) | Membership — Xray-internal (jira-xray) or TC→ATS issue link (jira-native with the Test Set work type) | Always — the ATS holds ALL the Story's TCs; its ATS→Story `is tested by` link is what fills the coverage panel |
      | User Story | "tests" / "is tested by" | **Last resort only** (cascade step 3): jira-native WITHOUT a Test Set work type — no ATS possible, so the direct TC→Story link carries traceability. Never needed while an ATS covers the TC |
      | ATP (Test Plan) | Parent / reference | Always, after ATP exists (administrative — contributes no coverage) |
      | ATR (Test Results) | Reference | Always, after ATR exists (administrative — contributes no coverage) |
      | Regression Epic | Parent | Always |
      | Acceptance Criterion | Reference | Always |
      | Bug (if blocked) | "is blocked by" | When a bug prevents execution |
      
      ### Regression Epic (test repository)
      
      All TCs must belong to a Regression Epic — the permanent repository for the project. Before creating any TC:
      
      > **Prerequisite**: Load `/acli` skill before executing the commands in this section.
      
      ```
      [ISSUE_TRACKER_TOOL] Search Issues:
        project: {{PROJECT_KEY}}
        query: type = Epic AND summary ~ "{qa.qa_epics.test_repository_epic.name}"
        # Resolve by the configured name (qa.qa_epics.test_repository_epic.name — "QA Test Repository"),
        # then fall back to the cached epic key. Identity is NOT a label lookup — the
        # QA-Artifact label marks QA-process epics but the configured name is the resolver.
      ```
      
      If none exists, ask the user before creating:
      
      ```
      [ISSUE_TRACKER_TOOL] Create Issue:
        project: {{PROJECT_KEY}}
        issueType: Epic
        title: "QA Test Repository"   # configured name qa.qa_epics.test_repository_epic.name
        description: "Container epic for all {{PROJECT_KEY}} regression tests."
        labels: QA-Artifact, regression, qa   # QA-Artifact is mandatory on QA-process epics; `test-repository` is retired as an identity label
      ```
      
      Typical structure:
      
      ```
      EPIC: QA Test Repository
        |-- TC-001: [Smoke] Basic login
        |-- TC-002: [Smoke] Main navigation
        |-- TC-003: [Regression] Complete checkout
        |-- TC-004: [Regression] User profile update
        |-- TC-005: [E2E] Complete purchase flow
        +-- ... (added incrementally)
      ```
      
      ---
      
      ## 12. CI/CD sync rules
      
      Automated results flow from CI to the TMS:
      
      ```
      1. EXECUTE — Playwright runs tests with @atc decorators
      2. REPORT  — Generate results (JUnit XML / JSON / Cucumber JSON)
      3. SYNC    — CLI pushes results to TMS
      4. UPDATE  — TMS Test Status + execution records updated
      5. NOTIFY  — Team sees results in TMS dashboard
      ```
      
      ### Rules
      
      1. **Sync only from CI** — never from local runs (they pollute the TMS).
      2. **Sync on main/staging only** — feature branch results are ephemeral.
      3. **Include build context** — every sync carries build ID, environment, timestamp.
      4. **Handle failures gracefully** — a sync failure must not break the CI pipeline.
      
      ### Pseudocode
      
      > **Prerequisite**: Load `/xray-cli` skill (Modality jira-xray). In Modality jira-native, load `/acli` — result sync loops over `[ISSUE_TRACKER_TOOL] Update Issue` per TC instead.
      
      ```
      [TMS_TOOL] Import results:
        format: junit | cucumber
        file: {from CI test results path}
        project: {{PROJECT_KEY}}
        execution: {from execution key or auto-create}
      
      [TMS_TOOL] Create execution:
        project: {{PROJECT_KEY}}
        title: {per execution naming convention}
        tests: {from test plan or label filter}
      
      [TMS_TOOL] Update test status:
        test: {TEST_KEY}
        status: PASS | FAIL | BLOCKED
        comment: "Build: {CI build ID}, Env: {environment}"
      ```
      
      ---
      
      ## 13. Best practices
      
      ### Do
      
      - Create TCs **after** the feature is stable and validated.
      - Add every TC to its Story's ATS (the coverage backbone) and link it to the ATP, ATR, and AC — a direct Story link only as the cascade's last resort (no ATS).
      - Use Gherkin for automatable TCs; Traditional for manual.
      - Evaluate ROI before marking candidates.
      - Keep the Regression Epic as the single source of truth.
      - Transition states sequentially — follow the workflow.
      - Include test data and variables in the Description.
      - Review TCs periodically and deprecate obsolete ones.
      - Think of TCs as reusable components (atomic TCs compose into E2E flows).
      
      ### Don't
      
      - Create TCs before exploring the feature.
      - Create TCs without a parent (Regression Epic).
      - Create TCs without traceability to a requirement.
      - Skip workflow states (e.g., Draft directly to AUTOMATED).
      - Automate without evaluating ROI first.
      - Duplicate TCs for the same scenario (same precondition + action = same TC).
      - Leave status stale after automating (update the TMS when the PR merges).
      - Use generic summaries like `"Login test"` — follow the naming convention.
      - Sync local test runs to the TMS.
      
      ---
      
      ## 14. Reference implementation — Jira + Xray
      
      | Convention | Jira/Xray implementation |
      |------------|-------------------------|
      | TC ID | Jira issue key |
      | TC issue type | Xray Test |
      | Test Status field | Xray Test Status or Jira custom field |
      | Workflow Status | Jira custom workflow or Xray Test Status |
      | Regression Epic | Jira Epic resolved by configured name (`qa.qa_epics.test_repository_epic.name` — "QA Test Repository"), then cached key; carries the `QA-Artifact` label |
      | Test Execution | Xray Test Execution |
      | Results import | Xray REST API (JUnit / Cucumber) |
      | CLI | `bun xray` (load `/xray-cli` skill) |
      
      Other TMS tools (Coda, Azure DevOps, TestRail) apply the same naming, labeling, workflow, and ROI conventions — only the underlying issue types differ.
      
    • xray-platform.md 15.1 KB
      # Xray Platform Reference (Modality jira-xray)
      
      Dense reference for Xray on Jira — issue types, traceability matrix, data flow, environment vars, and CI integration. Use when the project is in **Modality jira-xray** (per `SKILL.md` §Phase 0). For CLI syntax, load `/xray-cli` skill. For Jira-native fallback, see `jira-setup.md`.
      
      This document describes *what Xray is*; it does not describe *how to write tests* — that is `test-automation`'s job.
      
      ---
      
      ## 1. What Xray adds to Jira
      
      Xray is a native Test Management app for Jira. Tests, executions, and plans are **Jira issues** with full access to workflows, screens, JQL, custom fields, and REST API. Coverage links between tests and requirements are built-in.
      
      Trade-offs:
      
      | | Advantage | Cost |
      |-|-----------|------|
      | Jira-native | Use Jira workflows, permissions, JQL | Requires Jira Cloud or DC license |
      | Built-in traceability | Links from Test → Story → Bug are first-class | Extra issue types to learn |
      | CI/CD support | JUnit, Cucumber, Xray-JSON importers + REST API | Cloud and Server/DC have different APIs |
      | BDD support | Native Cucumber Gherkin field | Test Type is fixed at creation (cannot convert Manual → Cucumber) |
      
      ---
      
      ## 2. Issue types (six)
      
      Every TMS artifact becomes one of these:
      
      | Issue type | Purpose | Notes |
      |------------|---------|-------|
      | **Test** | Individual test case (Manual / Cucumber / Generic) | Child of Regression Epic; member of its Story's ATS (coverage reaches the Story via the ATS→Story link; a direct Test↔Story link is the cascade's last resort). |
      | **Test Set** | Two altitudes: **ATS** (per-Story, MANDATORY — holds ALL the Story's TCs, even one; its `is tested by` link to the Story fills the coverage panel) and **TS** (feature-level, OPTIONAL grouping: smoke / regression / domain) | Membership is Xray-internal (manage via `/xray-cli`, read via `bun xray test enrich`) — NEVER a Jira issue link, NEVER the TC prefix (the TC prefix is always `{US_ID}`); the ATS→Story `is tested by` edge IS a Jira link and is mandatory. Titles: `ATS: {US_ID}: {story title}` / `TS: {EPIC-KEY\|module}: Validate {feature}`. Components: inherited from the Story on the ATS (mandatory); optional on the feature-level `TS:` only (a feature Set spans modules by design). Both parented to **QA Test Artifacts**. |
      | **Test Plan** | Strategic planning for a release / sprint | Planning-level container. Holds **FTP / STP / ATP** Plans (titles `FTP: …` / `STP: Sprint#{N}: {objective}` / `ATP: {STORY-KEY}: {story title}` — the `Regression Testing` suffix belongs to the STR, not the STP). Parented to **QA Master Test Plan**. |
      | **Test Execution** | One execution cycle; holds Test Runs | Holds **STR / ATR** Runs (titles `STR: Sprint#{N}: Regression Testing` / `ATR: {STORY-KEY}: Story Testing`; FTR retired — feature results are read from the per-Story ATRs; the STR is a sibling sprint recap, not an aggregate of them). Carries Environment, Begin/End Date. Target of CI result import. Parented to **QA Test Artifacts**. |
      | **Pre-Condition** | Reusable prerequisites | Associated to Tests that share setup — an Xray-internal association (manage via `/xray-cli`, read via `bun xray test enrich`), NEVER a Jira issue link. Title: `{COMPONENT}: {required state}` (no ladder acronym) — the **title states the required state**, the **content holds the setup steps** (kept distinct), e.g. `Auth: User logged in as Admin`. Parented to **QA Test Artifacts**. |
      | **Test Run** | *Not a Jira issue* — internal entity inside a Test Execution | One per Test per Execution. Carries PASS/FAIL/TODO/BLOCKED/ABORTED/EXECUTING. |
      
      Typical hierarchy (parents are the QA-process Epics):
      
      ```
      QA Master Test Plan (Epic)
        +-- Test Plan: ATP: {STORY-KEY}: {story title}   (= ATP)
        +-- Test Plan: STP: Sprint#{N}: {objective}      (sprint plan)
      
      QA Test Artifacts (Epic)
        +-- Test Set: ATS: {US_ID}: {story title}             (= ATS, MANDATORY per Story —
        |       +-- Test (TC1, TC2, ...)                       ALL its TCs; ATS->Story link = coverage)
        +-- Test Set: TS: Checkout: Validate checkout v2      (optional feature grouping)
        |       +-- Test (TC3, TC4, ...)
        +-- Test Execution: ATR: {STORY-KEY}: Story Testing   (= ATR)
               +-- Test Run per Test (PASS / FAIL / TODO)
      
      QA Test Repository (Epic)
        +-- Test (TC1, TC2, TC3, TC4, ...)               (permanent test repository)
      ```
      
      ---
      
      ## 3. Test types (three)
      
      The `Test Type` field is set at creation and **cannot be changed** afterwards without delete + recreate.
      
      | Type | Use when | Steps field |
      |------|----------|-------------|
      | **Manual** | Human-executed test with structured steps | `Manual Steps` (step / data / expected per row) |
      | **Cucumber** | BDD, automation-candidate | `Gherkin Definition` (Feature / Scenario Outline) |
      | **Generic** | Automated test with a reference ID | `Generic Test Definition` (a free-form text that matches the test file's ATC ID) |
      
      Rule of thumb: use **Cucumber** for all automation-candidates (high-quality Gherkin per `jira-test-management.md` §7). Use **Generic** only when the automation framework already has its own test spec and you just need a TMS pointer.
      
      ---
      
      ## 4. Status fields (IQL: two of them)
      
      See `tms-conventions.md` §IQL for the full treatment. One-liner here:
      
      - **Test Status** (Workflow on the Test issue): `Draft` / `In Design` / `READY` / `MANUAL` / `In Review` / `Candidate` / `In Automation` / `Pull Request` / `AUTOMATED` / `DEPRECATED` — exact names from `.agents/jira-workflows.json` (`work_types.test_case`), the authoritative source. Long-lived lifecycle.
      - **Execution Status** (per Test Run inside a Test Execution): `TODO` / `EXECUTING` / `PASS` / `FAIL` / `ABORTED` / `BLOCKED`. Per-run, resets each execution.
      
      These are different fields. `AUTOMATED` (Test Status) + `FAIL` (Execution Status of last run) is a valid, common combination — the TC is live in CI, and it failed today.
      
      ### Test Plan roll-up: latest status wins
      
      A **Test Plan aggregates the LATEST status of each of its Tests, across every Execution.** `PROJ-101` passing in yesterday's ATR and failing in today's STR reads **FAIL** on the Plan; a re-run flips it back. The Plan owns no Test Run of its own.
      
      The consequence is the load-bearing part: **results are never written INTO a Test Plan** — its status is *derived*, not stored. So the plan-altitude items (**FTP / STP / ATP**) carry the **plan** (description) plus **human observations** (comments), and the Execution-altitude items (**ATR / STR**) carry the **results**: the per-Story ATRs as the sprint runs, then the closing regression days before sprint close, which adds ONE more Execution over the plan's Tests — that Execution is the **STR**. The STP's roll-up updates itself as they accumulate; nobody maintains it.
      
      This is also why `STP_EXECUTION_KEY` (`.env` / CI) names the *plan* but must hold the **STR** key — the Test Execution linked to that STP, never the STP itself. `tests/utils/jiraSync.ts` reads the target's issue type and refuses a Test Plan outright.
      
      ---
      
      ## 5. Requirements Traceability Matrix (RTM)
      
      Xray exposes bidirectional links between Requirements and Tests:
      
      ```
      REQUIREMENT (Story/Epic)           TEST                     DEFECT
            |            "covers"         |       "is tested by"    |
            v                             v                         v
       +----------+                 +-----------+             +-----------+
       | STORY-1  | <-------------- | PROJ-101  | ----------> | BUG-456   |
       +----------+                 +-----------+             +-----------+
      
      Forward:  "Does every requirement have test coverage?"
      Backward: "Which requirement does this test verify?"
      ```
      
      ### Coverage Status per requirement
      
      | Status | Meaning |
      |--------|---------|
      | Covered & Passing | All linked tests' last run = PASS |
      | Covered & Failing | At least one linked test's last run = FAIL |
      | Covered & Not Executed | Tests exist but no runs yet (TODO) |
      | Not Covered | No tests linked to this requirement |
      
      **Which link fills this panel (live-verified 2026-08-21, `.session/artifact-ladder-refactor/scoping.md` §Verificación)**: only an `is tested by` edge from a **Test Set** (the Story's ATS) or a **direct Test↔Story link** counts as coverage. A Story linked `is tested by` to a Test Plan and a Test Execution — even ones holding all its Tests — shows **UNCOVERED, 0 tests**: ATP/ATR links are administrative traceability, not coverage. This is why the per-Story ATS is mandatory: its ATS→Story link is the coverage anchor.
      
      The QA completeness checklist in `tms-architecture.md` §Completeness criteria is the application of this view at the User Story level.
      
      ---
      
      ## 6. Data flow: Playwright → JUnit → Xray
      
      ```
      PLAYWRIGHT TEST EXECUTION
         test('PROJ-101 | login flow', async ({ fixture }) => {
           await fixture.api.auth.loginWithValidCredentials({...});
         });
                |
                | generates
                v
      JUNIT XML (or Cucumber JSON)
         <testcase name="PROJ-101 | login flow" time="1.234">
           <system-out>Passed</system-out>
         </testcase>
                |
                | [TMS_TOOL] Import Results
                |   OR CI step (curl POST /api/v2/import/execution/junit)
                v
      XRAY API PROCESSING
         PARSE junit.xml
         MATCH "PROJ-101" to existing Test issue
         CREATE Test Execution PROJ-400 (if not pre-existing)
         UPDATE Test Runs with statuses
                |
                v
      XRAY ENTITIES UPDATED
         Test Execution PROJ-400:
           Test Plan: PROJ-300
           Environment: staging
           Test Runs:
             PROJ-101 -> PASS (1.234s)
             PROJ-102 -> FAIL (2.1s) "Timeout after 5000ms"
         Test Plan PROJ-300:
           Progress: 43/45 passing (95.5%)
      ```
      
      Matching rules (how Xray finds which Test issue a result belongs to):
      
      1. **By Jira key in test name**: `test('PROJ-101 | ...', ...)` — most reliable.
      2. **By Generic Test Definition**: match on `testKey` field — for Generic tests.
      3. **By Test Summary**: exact match — least reliable, avoid.
      
      The KATA convention `@atc('PROJ-101')` + `test('PROJ-101: should ...', ...)` ensures rule 1 always applies. See `test-automation/references/atc-tracing.md`.
      
      ---
      
      ## 7. Environment variables
      
      | Variable | Purpose | Required |
      |----------|---------|----------|
      | `XRAY_CLIENT_ID` | API client ID (Cloud) | Cloud only |
      | `XRAY_CLIENT_SECRET` | API client secret (Cloud) | Cloud only |
      | `XRAY_TOKEN` | Personal Access Token (Server/DC) | Server only |
      | _(site host)_ | `.agents/project.yaml` -> `issue_tracker.atlassian_url` — NOT an env var; read with `bun run --silent jira:url` | Always |
      | `ATLASSIAN_EMAIL` | Atlassian account email | Always |
      | `ATLASSIAN_API_TOKEN` | Atlassian API token | Always |
      | `JIRA_PROJECT_KEY` | Default project key | Optional (fallback to `{{PROJECT_KEY}}`) |
      | `XRAY_TEST_PLAN_KEY` | Default Test Plan for imports | Optional |
      | `XRAY_ENVIRONMENT` | Default test environment label | Optional |
      | `STP_EXECUTION_KEY` | Target of the automated write-back: the **STR** Test Execution linked to the sprint STP — **never the STP's own key** (`tests/utils/jiraSync.ts` reads the issue type and refuses a Test Plan; see §4). Unset → each run mints a new, unparented Execution. | Xray only; required for write-back |
      
      Never hardcode these — always from `.env`. The `/xray-cli` skill reads them from the environment automatically.
      
      ---
      
      ## 8. API quick reference
      
      Only the endpoints the skill needs. Full reference: [docs.getxray.app/display/XRAYCLOUD/REST+API](https://docs.getxray.app/display/XRAYCLOUD/REST+API).
      
      | Operation | Endpoint (Cloud) | Endpoint (Server/DC) |
      |-----------|------------------|----------------------|
      | Authenticate | `POST /api/v2/authenticate` | n/a (basic auth or PAT header) |
      | Import JUnit | `POST /api/v2/import/execution/junit` | `POST /rest/raven/2.0/import/execution/junit` |
      | Import Cucumber | `POST /api/v2/import/execution/cucumber` | `POST /rest/raven/2.0/import/execution/cucumber` |
      | Import Xray JSON | `POST /api/v2/import/execution` | `POST /rest/raven/2.0/import/execution` |
      | Multipart import with test info | `POST /api/v2/import/execution/junit/multipart` | same pattern |
      
      Cloud rate limit: ~10 req/s per user (plan-dependent). Batch imports > 100 tests should use bulk or multipart variants.
      
      ---
      
      ## 9. CI/CD integration (reference pattern)
      
      GitHub Actions snippet — adapt the secret names to the project. The `/regression-testing` skill handles the full CI lifecycle.
      
      ```yaml
      - name: Run tests
        run: bun run test
        env:
          CI: true
      
      - name: Get Xray token
        if: always()
        id: xray-auth
        run: |
          TOKEN=$(curl -s -X POST \
            https://xray.cloud.getxray.app/api/v2/authenticate \
            -H "Content-Type: application/json" \
            -d "{\"client_id\":\"${XRAY_CLIENT_ID}\",\"client_secret\":\"${XRAY_CLIENT_SECRET}\"}" \
            | tr -d '"')
          echo "token=$TOKEN" >> $GITHUB_OUTPUT
      
      - name: Import results to Xray
        if: always()
        run: |
          curl -X POST \
            "https://xray.cloud.getxray.app/api/v2/import/execution/junit?projectKey=${{ vars.JIRA_PROJECT_KEY }}&testPlanKey=${{ vars.XRAY_TEST_PLAN_KEY }}" \
            -H "Authorization: Bearer ${{ steps.xray-auth.outputs.token }}" \
            -H "Content-Type: application/xml" \
            --data-binary @test-results/junit.xml
      ```
      
      Alternative: Playwright reporter `playwright-xray` posts results directly, no curl step. Use whichever the project already has configured.
      
      ---
      
      ## 10. Dual reporting: Allure vs Xray
      
      Automation reports (Allure, CI logs, screenshots) and the TMS reports serve different audiences. Keep both; do not collapse into one.
      
      | | Automation reports (Allure / CI) | TMS reports (Xray) |
      |-|----------------------------------|--------------------|
      | Where | Allure server / S3 / CI artifacts | Jira + Xray |
      | What | All executions (smoke, sanity, regression) | Regression cycles + manual + automated, linked to requirements |
      | Audience | Dev team, DevOps, QA automation | QA team, PMs, stakeholders, management |
      | Question it answers | "Is the pipeline healthy? Where is the flake?" | "Is the product ready? Are the requirements verified?" |
      
      Rule: sync only from CI to the TMS (never from local runs). Feature branch results are ephemeral; only main/staging results belong in the TMS.
      
      ---
      
      ## 11. Common errors
      
      | Error | Cause | Fix |
      |-------|-------|-----|
      | `401 Unauthorized` | Token expired or wrong credentials | Regenerate; verify `XRAY_CLIENT_ID` / `XRAY_CLIENT_SECRET` |
      | `404 Not Found` | Wrong project or Test Plan key | Verify the key exists in Jira via `[ISSUE_TRACKER_TOOL]` |
      | `400 No valid tests` | Test IDs in JUnit don't match any Test issue | Make sure test names include the Jira key (`@atc('PROJ-101')`) |
      | `403 Forbidden` | Xray project permissions | User needs "Edit Tests" + "Import Executions" in the Xray permission scheme |
      | Test Type change rejected | Cannot convert Manual ↔ Cucumber | Delete the Test and recreate with the correct type |
      | Test Execution never closes | Xray does not auto-close Executions | Transition manually via `[ISSUE_TRACKER_TOOL] Transition Issue` after import |
      
      ---
      
      ## 12. External resources
      
      - Xray Cloud docs: `docs.getxray.app/display/XRAYCLOUD`
      - Xray Server/DC docs: `docs.getxray.app/display/XRAY`
      - Xray REST API: `docs.getxray.app/display/XRAYCLOUD/REST+API`
      - Atlassian Jira REST API: `developer.atlassian.com/cloud/jira/platform/rest/v3/`
      - Playwright Xray reporter: `github.com/inluxc/playwright-xray`
      
  • SKILL.md 91.5 KB
    ---
    name: test-documentation
    description: "Analyze, prioritize, and document test cases in TMS (Jira/Xray), or repair an existing Story-ATS-ATP-ATR-TC cascade through a sealed explicit mode. Use for Test/ATP/ATR artifacts, ROI and automation verdicts, maintaining traceability, fix-traceability, or broken TMS links. The repair-traceability mode audits, plans, waits for explicit approval, applies, and verifies without launching the general documentation workflow. Do NOT use for writing test code (test-automation) or running suites (regression-testing)."
    license: MIT
    compatibility: [claude-code, copilot, cursor, codex, opencode]
    complementary_categories: [tms, issue-tracker]
    # compact_rules is consumed VERBATIM by scripts/build-skill-registry.ts (frontmatter-first,
    # no truncation). Keep in sync with the binding doctrine below and in references/.
    compact_rules: |
      - Documenting an AC→TC map is the FLOOR (≥1 TC per AC is a minimum, never a target). Coverage = AC-conformance + risk-beyond-AC; the TC set must include boundary / negative / state / anomaly cases the AC is silent on. (Canon: `agentic-qa-core/references/test-design-doctrine.md`.)
      - 1:N applies to DERIVATION (consider many cases by technique), not to the REGRESSION repository. Only regression-worthy scenarios (Candidate/Manual) are persisted there; most are Deferred. jira-native: Stage 4 CREATES `Test`s for those only (Deferred = report-only). jira-xray: sprint `Test`s already exist (Stage 1) — Stage 4 PROMOTES the regression-worthy into the Test Plan + enriches them. Document because it will be re-run, never to hit a count.
      - Apply techniques by trigger: EP always; BVA wherever a range/limit/length/date-window exists; State-Transition for stateful entities; Decision Table when 2+ conditions interact; Pairwise when 3+ combinable factors.
      - Parametrize for artifact economy: same-behavior data variants → ONE Test (`Scenario Outline` + `Examples` rows) per partition, NOT N separate Tests; split only when action / outcome / status / state differs. (Canon: doctrine §"Part 2.5".)
      - Cross-cutting characteristics (XSS, perf, a11y) deferred to app-level suites are an EXPLICIT handoff, not a silent drop — name the receiving suite or file the gap.
      - Documents already-validated behavior only — not an exploration tool (exploration belongs to `/sprint-testing`).
      - TC identity = Precondition + Action + verifiable outcome. Naming (TC): `{US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]`; `Validate <feature>` is reserved for the GROUPING layer (Test Set summary / `describe()`). Reject `"Login test"`, `"Login - error"`, `"TC1: Test form"`.
      - ROI formula → one of three verdicts per TC: Candidate (feeds test-automation), Manual, Deferred. Prioritize by risk.
      - Cardinality: US→TC is 1:N; AC→TC is N:1 or N:M. Resolve TMS modality (Xray vs Jira-native) in Phase 0 before documenting.
      - Bug-driven (GOLDEN RULE): not every bug is a regression TC, but a regression-worthy bug MUST end with a Test — REUSE the existing failed Test if it came from one, else CREATE one (both modalities). A non-qualifying bug is treated like a failed test → Deferred, no new Test.
      - ATS is MANDATORY per Story (`ATS: {US_ID}: {story title}`, even with a single TC): a `Test Set` holding ALL the Story's TCs, parented to the QA Test Artifacts epic, `components` INHERITED from the Story (mandatory — the components exemption applies ONLY to the optional feature-level `TS:` grouping sets).
      - Set-first creation order: find-or-create the ATS, ATP and ATR BEFORE the first TC (module-driven pre-creates the containers because parallel TC sharding needs the targets to exist); add each TC to the ATS, THEN derive the ATP's and the Execution's test lists FROM the ATS membership — never three independent id lists.
      - Coverage truth (live-verified): coverage comes from the ATS→Story `is tested by` link (primary) OR a direct TC→Story link (last resort, valid only when no ATS can exist). Story↔ATP and Story↔ATR links are administrative traceability and contribute ZERO coverage — keep them, never count them as coverage.
      - Membership: Modality jira-xray → TC∈ATS/ATP/ATR is Xray-internal (GraphQL, via `/xray-cli`), NEVER a Jira issue link (and never in the TC title). Modality jira-native carve-out: with the Test Set work type present, membership IS expressed as TC→ATS issue links; work type absent → no ATS.
      - Direct TC→Story links are the cascade's LAST RESORT (valid only when no ATS can exist — e.g. jira-native without the Test Set work type), not the default. The defect is a TC with NO path to its Story, not the direct link itself.
    ---
    
    ## Forbidden invocations
    
    **NEVER invoke `/sdd-*` skills from this workflow.** SDD is an optional
    user-installed ceremony; this skill ships self-contained and does not chain
    SDD under any condition. If you need to refactor KATA, fixtures, cli/,
    scripts/, or api/schemas/ pipeline, exit this skill first and invoke
    `/framework-development` — which itself runs Plan → Code → Verify → Archive
    natively (no SDD required).
    
    This boundary is mechanical, not advisory: `scripts/lint-skills.ts` rejects
    any `/sdd-` mention outside this section. See:
    `.agents/skills/agentic-qa-core/references/skill-composition-strategy.md` §4
    (governs users who manually install SDD).
    
    # Test Documentation — QA Bridge
    
    Take already-validated tests and formalize them in the TMS (Jira, Xray, or equivalent) with full traceability, the right priority, and a clear automation verdict.
    
    Three phases, always in this order: **Analyze -> Prioritize (ROI) -> Document**. Never skip prioritization: most scenarios should end up Deferred, not automated.
    
    One hard prerequisite: the tests being documented must describe behavior that was **already validated** ({{jira.status.story.qa_approved}} story, closed bug, or finished exploratory session). The TMS is a documentation and regression-protection tool, not an exploration tool.
    
    ---
    
    ## Dependencies
    
    Requires `agentic-qa-core`. Loads on demand:
    
    - `agentic-qa-core/references/test-design-doctrine.md` — **MANDATORY before deriving TCs from acceptance criteria.** Governs the 1:N TC explosion, the formal-technique triggers, and the floor-not-ceiling coverage model. EP + BVA are operationalized here against the canon.
    - `agentic-qa-core/references/defect-management-doctrine.md` — **MANDATORY before parenting a Test or raising an Improvement.** Governs QA process-epic parenting (every `Test` hangs from the **QA Test Repository** epic, Part 4), the mandatory `components` axis (Part 3), and the Improvement bridge for under-specified ACs (Part 1). This skill files no Bugs.
    - `agentic-qa-core/references/briefing-template.md`, `agentic-qa-core/references/dispatch-patterns.md`, `agentic-qa-core/references/orchestration-doctrine.md`, `agentic-qa-core/references/session-management.md`, `agentic-qa-core/references/preflight-gate.md`, `agentic-qa-core/references/traceability-linking.md` — cited inline by the sections that use them.
    
    ## Compact Rules
    
    **Test-design doctrine (binding — full canon: `agentic-qa-core/references/test-design-doctrine.md`):**
    
    - Documenting an AC→TC map is the FLOOR (≥1 TC per AC is a minimum, never a target). Coverage = AC-conformance + risk-beyond-AC; the TC set must include boundary / negative / state / anomaly cases the AC is silent on.
    - 1:N applies to DERIVATION (consider many cases by technique), not to the REGRESSION repository. Only regression-worthy scenarios (Candidate/Manual) are persisted there; most are Deferred. jira-native: Stage 4 CREATES `Test`s for those only (Deferred = report-only). jira-xray: sprint `Test`s already exist (Stage 1) — Stage 4 PROMOTES the regression-worthy into the Test Plan + enriches them. Document because it will be re-run, never to hit a count.
    - Apply techniques by trigger: EP always; BVA wherever a range/limit/length/date-window exists; State-Transition for stateful entities; Decision Table when 2+ conditions interact; Pairwise when 3+ combinable factors.
    - Parametrize for artifact economy: same-behavior data variants → ONE Test (`Scenario Outline` + `Examples` rows) per partition, NOT N separate Tests; split only when action / outcome / status / state differs. (Canon: doctrine §"Part 2.5".)
    - Cross-cutting characteristics (XSS, perf, a11y) deferred to app-level suites are an EXPLICIT handoff, not a silent drop — name the receiving suite or file the gap.
    
    **Test-documentation operational rules:**
    
    - Documents already-validated behavior only — not an exploration tool (exploration belongs to `/sprint-testing`).
    - TC identity = Precondition + Action + verifiable outcome. Naming (TC): `{US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]`; `Validate <feature>` is reserved for the GROUPING layer (Test Set summary / `describe()`). Reject `"Login test"`, `"Login - error"`, `"TC1: Test form"`.
    - ROI formula → one of three verdicts per TC: Candidate (feeds test-automation), Manual, Deferred. Prioritize by risk.
    - Cardinality: US→TC is 1:N; AC→TC is N:1 or N:M. Resolve TMS modality (Xray vs Jira-native) in Phase 0 before documenting.
    - Bug-driven (GOLDEN RULE): not every bug is a regression TC, but a regression-worthy bug MUST end with a Test — REUSE the existing failed Test if it came from one, else CREATE one (both modalities). A non-qualifying bug is treated like a failed test → Deferred, no new Test.
    
    **Read full SKILL.md when**: resolving TMS modality, computing ROI, writing Gherkin, or wiring US-ATP-ATR-TC traceability links.
    
    ---
    
    ## Mode routing
    
    Resolve mode before the readiness preflight and Phase -1 session workflow.
    
    - `repair-traceability`: selected only by the legacy `fix-traceability` alias or an explicit request to repair a ticket's existing traceability. Forward `$ARGUMENTS` unchanged and load only `references/repair-traceability.md`. Preserve its sealed sequence: audit -> present plan -> explicit user approval -> apply -> verify. Do not start Analyze -> Prioritize -> Document, create unrelated test cases, or broaden the ticket scope.
    - `document` (default): normal TMS documentation, ROI, and Candidate/Manual/Deferred work. Continue with the workflow below.
    
    If the user has not supplied the ticket key required by `repair-traceability`, ask for it before any TMS call. Missing credentials remain a hard stop under `AGENTS.md` Critical Rule #10.
    
    > **`repair-traceability` on ONE ticket cannot see the failure that matters most.** Coverage-link direction is a project-wide condition: an inverted link is invisible on its own Story (the link is present, the coverage panel is merely empty, nothing reports it) and only reads as a pattern in aggregate — on one measured project, 21 of 43 linked Stories were wired the wrong way, one of them losing a fully populated 69-Test Test Set. So when the mode audits a ticket, ALSO offer the project-wide mixed-direction sweep before applying anything: the `[TMS_TOOL]` traceability check accepts several keys or a JQL query and returns one repair worklist. Direction doctrine, the delete-before-recreate rule (Jira dedupes the pair+type, so adding the corrected link is a silent no-op) and the sweep are canon in `agentic-qa-core/references/traceability-linking.md` §4 and §10. Read them before proposing any link repair; the plan the user approves must say which links get deleted, by id.
    
    ---
    
    ## Subagent Dispatch Strategy
    
    > **Orchestration & Session contracts**: this skill follows `agentic-qa-core/references/orchestration-doctrine.md` (mandatory subagent dispatch — main thread is command center) AND `agentic-qa-core/references/session-management.md` (Phase 0 resume check, plan-first persistence at `.session/<skill-slug>/<scope>/`, archive on completion). Phase 0 (resume check) and Phase 1 (plan write) are NOT optional. The orchestrator also applies the per-stage **Definition-of-Done gates** in `agentic-qa-core/references/stage-gates.md`: verify a stage's DoD (planning stages include the Test-Design Checklist) BEFORE recording its progress checkpoint and advancing.
    
    This skill is **per-scope**: `<scope>` = `<JIRA-KEY>` (ticket / bug scope), `<module-slug>` (module scope), or `<YYYY-MM-DD>-adhoc` (ad-hoc scope). Session state lives at `.session/test-documentation/<scope>/{plan.md, progress.md}` per `agentic-qa-core/references/session-management.md` §3 + §9.
    
    **Naming collision note**: this skill already owns `## Phase 0 — Resolve TMS modality` (the TMS gate). The session resume check is therefore named `## Phase -1 — Session resume check` to avoid colliding with the existing Phase 0 anchor. Resume fires FIRST, then the TMS modality gate, then the rest of the pipeline.
    
    This skill is compliant with the doctrine in `AGENTS.md` §"Orchestration Mode (Subagent Strategy)" and the session contract in `.agents/skills/agentic-qa-core/references/session-management.md`. Every dispatch follows the 7-component briefing format defined in `.agents/skills/agentic-qa-core/references/briefing-template.md`, and the pattern selected per phase matches the decision guide in `.agents/skills/agentic-qa-core/references/dispatch-patterns.md`. Phase 1 (Analyze) and Phase 2 (Prioritize) stay inline because planning and decisions live in the orchestrator; the only Parallel hotspot is bulk TC creation in Phase 3, which is also the only step that branches per TMS modality.
    
    | Phase                                                  | Pattern    | Subagent role                                                                                                                                              |
    |--------------------------------------------------------|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
    | Phase -1 — Session resume check                        | inline     | orchestrator only; reads `.session/test-documentation/<scope>/progress.md` if present, offers resume / restart / abort per `agentic-qa-core/references/session-management.md` §4    |
    | Phase 0 — Resolve TMS modality                         | inline     | orchestrator only; existing 4-step probe — unchanged                                                                                                        |
    | Phase 1 — Analyze scope                                | Single     | inline — planning lives in the orchestrator (anti-pattern to delegate)                                                                                      |
    | Phase 2 — ROI / Candidate-Manual-Deferred verdict      | Single     | inline — decisions live in the orchestrator                                                                                                                 |
    | Phase 3 — TMS TC creation (N > 10 TCs)                 | Parallel   | M subagents, chunks of ~5-10 TCs per agent; cap = 10 to avoid Jira/Xray rate limits; each subagent loads `/xray-cli` (Modality jira-xray) or `/acli` (Modality jira-native)  |
    | Phase 3 — TMS TC creation (N ≤ 10 TCs)                 | Single     | inline — dispatch overhead is not justified for small batches                                                                                               |
    | Phase 3 — Traceability linking (US <-> ATS/ATP/ATR <-> TCs) | Single     | inline — requires aggregated state of all created entities                                                                                                  |
    | Phase 3 — Final report / reports (`COVERAGE-MATRIX-<scope>.md`, `PRIORITIZATION-<scope>.md`) | Single | inline — synthesis lives in the orchestrator                                                                                                                |
    
    - **Concurrency cap = 10 subagents** for Parallel TC creation. Jira and Xray APIs both rate-limit at ~10 writes/sec sustained; fanning out wider triggers 429 responses. If a module has >100 TCs, batches per subagent must be larger than 10 each (cap is on subagent count, not chunk size).
    - **Error protocol**: On any subagent failure: STOP, report the partial success state (which TCs landed, which failed, with their issue keys / errors), present retry / skip / abort options. Do NOT auto-fix nor auto-rollback. See `.agents/skills/agentic-qa-core/references/orchestration-doctrine.md`.
    
    ---
    
    ## Readiness Preflight Gate (MANDATORY — runs before Phase -1)
    
    > Full doctrine: `agentic-qa-core/references/preflight-gate.md`. Runs FIRST, before the resume check and before the TMS-modality gate. Two laws: (1) **args-as-answers** — the scope (module / ticket / bug / ad-hoc) and any stated modality are provided args; ask only the gaps. (2) **probe, don't assume**. Surface gaps + REDs as ONE `AskUserQuestion` checklist; self-fix with approval + explanation; STOP on any blocking RED. This skill documents already-validated behavior in the TMS — it does NOT execute against a live system, so its gate centers on TMS write capability. **Generic baseline** (env resolution, test-user creds, secret/restart handling, the two laws, output contract) is inherited from the reference §3.1 — not repeated here. Below is only this skill's **specific capability delta**.
    
    | Capability | Need | Why here |
    |---|---|---|
    | Issue-tracker (`[ISSUE_TRACKER_TOOL]`) | REQUIRED | TC / ATP / ATR creation, linking, transitions. Load `/acli`; validate via `bun run jira:check`. |
    | TMS modality + `[TMS_TOOL]` | REQUIRED | The whole Phase 0 gate. jira-xray → `/xray-cli` loaded + `XRAY_*` creds set + Xray issue types present. jira-native → `/acli` covers it. Resolve before Phase 1; ask only if all auto-checks fail. |
    | Source repos readable | OPTIONAL | Phase 1 source-code validation reads backend/frontend code, not a running env — no live-env or DB/API/browser probe needed. |
    
    Active env, test-user creds, DBHub, OpenAPI/`API_TOKEN`, Playwright, `resend` and `kata-manifest.json` (an automation-only concern owned by `/test-automation`) are **N/A** — documentation never hits a live system nor writes test code. After the gate clears (all REQUIRED GREEN), continue to Phase -1 below.
    
    ---
    
    ## Phase -1 — Session resume check (MANDATORY, inline)
    
    Runs BEFORE Phase 0 (TMS modality gate). Compute prospective `<scope>` from invocation: `<JIRA-KEY>` for ticket/bug scope, `<module-slug>` for module scope, `<YYYY-MM-DD>-adhoc` for ad-hoc. Then:
    
    1. Check `.session/test-documentation/<scope>/progress.md`.
    2. If it does NOT exist → proceed to Phase 0 (TMS modality).
    3. If it DOES exist:
       - Read `plan.md` (chosen scope, TMS modality, TC list, ROI verdicts).
       - Read tail of `progress.md` (last completed phase + next planned phase).
       - Surface to the user: scope, TMS modality, last completed phase, next phase, any pending TC creation chunks that did not finish (the most common interruption point — Phase 3 parallel bulk create capped at 10 subagents).
       - Offer **resume / restart / abort**. On `restart`, archive to `.session/.archive/<YYYY-MM-DD>-test-documentation-<scope>-aborted/` first.
    
    Critical resume case: Phase 3 parallel bulk create interrupted mid-batch. The `progress.md` records per-chunk completion (one entry per Parallel subagent return), so resume skips already-created TCs by reading the chunks marked `completed` and dispatching only the missing chunks. This is why per-subagent checkpoint matters (see Phase 3 below).
    
    ---
    
    ## Phase 0 — Resolve TMS modality (mandatory gate)
    
    Every project runs in one of two modalities. Resolve it **before** Phase 1. The same ATP/ATR/TC concepts have **different containers** in each mode.
    
    ### The question you MUST answer first
    
    ```
    Does this project have Xray installed and licensed on Jira?
      A. Yes -> Modality jira-xray
      B. No  -> Modality jira-native (no Xray)
    ```
    
    ### How to resolve it without asking (in order)
    
    1. Check `AGENTS.md` for `{{TMS_CLI}}`. Value `bun xray` (or any Xray CLI) -> **Modality jira-xray**. Value is unset, `acli`-only, or `{{TMS_CLI}}` matches `{{ISSUE_TRACKER_CLI}}` -> **Modality jira-native**.
    2. If `AGENTS.md` is ambiguous, look for a `.context/master-test-plan.md` line such as `TMS: Xray on Jira` or `TMS: Jira native`.
    3. If still ambiguous, list existing issue types in the project via `[ISSUE_TRACKER_TOOL] List issue types`. If the project exposes `Test Plan` / `Test Execution` / `Test Set` / `Pre-Condition`, it is **Modality jira-xray**. Otherwise **Modality jira-native**.
    4. **Only if all three checks fail**, ask the user the question above. Do NOT ask by default — autoresolve first.
    
    ### What changes per modality
    
    | Artifact | Modality jira-xray | Modality jira-native |
    |----------|---------------------------|---------------------------|
    | **ATP** (Acceptance Test Plan) | `Test Plan` issue titled `ATP: {STORY-KEY}: {story title}`, parented to the **QA Master Test Plan** epic, linked to the US | Same `Test Plan` issue **by excellence** (native Jira work type, Xray-independent); falls back to the Story `{{jira.acceptance_test_plan}}` field (then a `## Acceptance Test Plan (ATP)` comment) **only when the Test Plan work type is absent** from the instance. |
    | **ATR** (Acceptance Test Results) | `Test Execution` issue with Test Runs per TC, Environment, Begin/End Date, titled `ATR: {STORY-KEY}: Story Testing`, parented to the **QA Test Artifacts** epic | Same `Test Execution` issue **by excellence**; falls back to the Story `{{jira.acceptance_test_results}}` field (then a `## Acceptance Test Results (ATR)` comment) **only when the Test Execution work type is absent** from the instance. |
    | **TC** (Test Case) | Xray `Test` issue (type Manual / Cucumber / Generic) | Jira-native `Test` issue type (or `Task` with custom type), Description carries the full TC template |
    | **ATS** (Acceptance Test Set) | `Test Set` issue titled `ATS: {US_ID}: {story title}`, mandatory per Story — holds ALL the Story's TCs (membership Xray-internal), linked to the US (`is tested by` — the coverage-panel link) | Same `Test Set` issue **when the work type is present** — membership expressed as **TC→ATS issue links** (the "membership is never a link" rule is xray-only). Work type absent → **no ATS**: direct TC→Story links (cascade last resort) |
    | **TS / Precondition / Test Plan** | First-class Xray issue types (`TS:` feature Set is optional grouping) | Same native work types when present in the instance; absent → use labels + Epic grouping |
    | **Result sync** | CI imports JUnit/Cucumber via `[TMS_TOOL] Import Results` -> Test Runs auto-update | Custom script updates Test Status field on each TC + comment with build context |
    | **CLI tag** | `[TMS_TOOL]` resolves to `bun xray` or equivalent | `[TMS_TOOL]` falls through to `[ISSUE_TRACKER_TOOL]` (acli / Jira MCP) |
    
    ### Resolve `{{TC_CREATION_STAGE}}` in the same gate
    
    The modality says which TMS tool is live; `.agents/project.yaml` → `testing.tc_creation_stage` (referenced as `{{TC_CREATION_STAGE}}`) says **whether this skill CREATES the Candidate/Manual `Test` items or REFINES + promotes ones `/sprint-testing` already made**. Read it here, alongside the modality; unset or unrecognized → `auto`. The knob's full table + rationale is `sprint-testing/SKILL.md` §"Which stage creates the TCs" — that section is authoritative, this one only consumes it.
    
    | Resolved value | Phase 3's verb for a Candidate / Manual scenario |
    |---|---|
    | `auto` (default) | jira-xray → **promote + enrich** an existing sprint `Test` · jira-native → **create** the `Test` here |
    | `sprint-testing` | **promote + enrich** in BOTH modalities — the items already exist; creating a second one duplicates the repository |
    | `test-documentation` | **create** in BOTH modalities — no sprint items exist to promote |
    
    Whatever the verb, **the canonical title rule is identical**: a created TC is titled to the form, a promoted TC has its title re-derived and verified first (§"Title on promotion"). If the verb says *promote* but no sprint `Test` exists for a scenario (a Story tested before the knob was set, or a scenario derived only now), fall back to *create* for that scenario and note it in `progress.md` — never skip the TC.
    
    ### Persist the decision
    
    Once resolved, save the modality **and the resolved `{{TC_CREATION_STAGE}}`** into `.session/test-documentation/<scope>/plan.md` §Inputs (canonical session record) and ALSO mirror to `test-session-memory.md` for the ticket (if one exists, for per-ticket sub-agent context). Treat as sticky: do not re-resolve mid-session. If you detect drift (e.g. `[TMS_TOOL]` suddenly fails), stop and ask the user before re-resolving.
    
    Reference implementations:
    - Modality jira-xray concepts + Xray REST/GraphQL/CLI -> `references/xray-platform.md`
    - Modality jira-native project setup (Test issue type, Screen Scheme, custom fields) -> `references/jira-setup.md`
    - Both modes side-by-side (field mapping, workflow, Description template) -> `references/jira-test-management.md`
    
    ---
    
    ## When to use each scope
    
    Pick the scope based on the input, not the output. All four scopes share the same Analyze -> Prioritize -> Document pipeline; only the input source and defaults differ.
    
    | Scope | Input | Typical volume | Default labels | Notes |
    |-------|-------|----------------|----------------|-------|
    | **Module-driven** | A module of the system explored end-to-end | 20-100+ scenarios | `regression`, `e2e` or `integration` | Batch of TCs grouped under the Regression Epic. Most scenarios will be Deferred. |
    | **Ticket-driven** | A QA Approved user story from a sprint | 3-8 scenarios | `regression`, plus the test type | Output of a `sprint-testing` session. ATP/ATR created per US. |
    | **Bug-driven** | A closed bug with a verified fix | 0-2 scenarios | `regression`, `automation-candidate` (usually) | Run the Bug-driven decision (below). Not every bug qualifies; if it does, **reuse the existing failed Test or create one** — an important bug must end with a Test. ROI biased up: "it failed once, it can fail again." |
    | **Ad-hoc / Exploratory** | New scenarios found in exploratory testing | 1-10 scenarios | `regression` | Apply the 3 Phase-0 questions harshly; ad-hoc scenarios are often one-time validations. |
    
    If the user gives you a story ID, use ticket-driven. If they give you a bug ID, use bug-driven. If they give you a module name or a session output, use module- or ad-hoc accordingly.
    
    ### Bug-driven decision — "an important bug must have a test" (GOLDEN RULE)
    
    Not every bug becomes a regression Test — a one-time typo in a stable area is **treated like a failed test** (the fix was verified in sprint-testing) and Deferred. But run the **same analysis + prioritization** you'd run on any scenario; if the bug IS regression-worthy, it **MUST end with a Test that covers it**, in BOTH modalities. *Where there is an important bug, there must be a test that catches it again — this rule is worth gold.*
    
    ```
    1. Is this Bug/Defect a regression candidate?  (apply Phase-0 filter + ROI; the prior-bug rule biases up)
       NO  -> No new Test. Treat as a failed test: fix already verified in sprint-testing -> log as Deferred. Done.
       YES -> step 2.
    
    2. Was the bug found FROM an existing, already-executed Test?  (a Test that ran and failed — jira-native OR xray)
       YES -> REUSE that existing Test for the bug's retest + regression. It already lives in the test set;
              ensure it is linked to the bug (`tests / is tested by`) and promoted into regression. Do NOT duplicate.
       NO  -> CREATE + design the corresponding Test for the bug's retest.
              jira-native: new `Test` issue.  jira-xray: new Xray `Test` (+ plugin-appropriate Test Plan / Test Set linking).
              Link to the bug via `tests / is tested by`.
    ```
    
    This **overrides** sprint-testing's "the bug is the test case" — that phrase covers only the immediate in-sprint retest, NOT future regression. The retest reproduces+verifies the fix now; this rule decides whether a *persistent* Test must exist (reuse or create) so the bug can never silently return.
    
    **Scope handoff to `/test-automation`.** The `Candidate` TCs produced here flow downstream to `/test-automation`, which **re-scopes** them into its own 3 planning scopes: `module-driven → Module (Macro)`, `ticket-driven → Ticket (Medium)`, `bug-driven → Regression-driven (Micro)`. `ad-hoc / exploratory` Candidates have no 1:1 automation scope — they enter under whichever fits (a module batch, or regression-driven for a single TC). `Manual` and `Deferred` verdicts are terminal and never reach automation.
    
    After scope confirmation, **write `.session/test-documentation/<scope>/plan.md`** per `agentic-qa-core/references/session-management.md` §6 — Goal (scope + TMS modality + expected TC count), Inputs (PBI references, ATP source, prior bugs), Approach (per-phase dispatch table above), Phase breakdown (Phase 1 Analyze → Phase 2 Prioritize → Phase 3 TC creation with chunk count → Traceability → Final report), Risks, Verification checklist (all TCs created with traceability + both reports written + the Deferred list mirrored to Jira), Cross-references (`.context/PBI/epics/EPIC-<KEY>-<slug>/stories/STORY-<KEY>-<slug>/test-cases/*.md` per-TC files + `.context/reports/COVERAGE-MATRIX-<scope>.md` + `.context/reports/PRIORITIZATION-<scope>.md` — filenames per §"Reports — fixed filenames"). Append `## Phase -1 — Session resume check — <ts>` with `status: completed`, `next: Phase 0 — Resolve TMS modality` to `progress.md`.
    
    ---
    
    ## Phase 1 — Analyze
    
    ### Inputs you must gather
    
    | Source | What to read | Why |
    |--------|--------------|-----|
    | User Story / Epic | Description, ACs, comments, linked issues | Scenario identification, risk signals |
    | Closed bugs linked to the story | Summary, root cause, fix area | Prior-bug prioritization rule |
    | Exploratory session notes | Validated scenarios, observations | Reuse nomenclature already used |
    | Existing ATP (if present) — **modality-aware** (see §Phase 0) | **jira-native**: Story field `{{jira.acceptance_test_plan}}` → synced `.context/PBI/epics/EPIC-<KEY>-<slug>/stories/STORY-<KEY>-<slug>/acceptance-test-plan.md` (read-only Jira cache — sync via `bun run jira:sync-issues get <STORY> --include-comments`). **jira-xray**: Test Plan issue `description` → `bun run jira:sync-issues get <ATP_KEY>` → `test-plans/ATP-<KEY>-<slug>.md` (acronym prefix = conforming ladder title; a non-conforming title keeps the legacy `TESTPLAN-` / `TESTEXEC-` / `RETESTEXEC-` prefix); per-TC run state via `[TMS_TOOL]` (xray-cli) | Scenarios may already exist — do not reinvent |
    | Existing ATR (if present) — **modality-aware** (see §Phase 0) | **jira-native**: Story field `{{jira.acceptance_test_results}}` → synced `acceptance-test-results.md` (same `jira:sync-issues get <STORY> --include-comments`). **jira-xray**: Test Execution issue `description` → `bun run jira:sync-issues get <ATR_KEY>` → `test-executions/ATR-<KEY>-<slug>.md` (sync supports these types); per-TC run results via `[TMS_TOOL]` (xray-cli) | Prior run results — do not re-execute what is already recorded |
    | Implementation plan / source code | Actual files, APIs, test IDs | Validate design matches implementation before documenting |
    | `.context/business/domain-glossary.md` (if present) | Canonical entity + process names, anti-glossary banned terms | Vocabulary reference for TC names, steps, and preconditions — terms must match the glossary |
    
    ### Separate real scenarios from cross-cutting characteristics
    
    Cross-cutting traits are **validated inside every test**, not as separate TCs.
    
    | Cross-cutting (NOT a TC) | Validated by |
    |--------------------------|--------------|
    | Mobile responsive | Running each test in mobile viewport |
    | XSS prevention | Using special-character test data inside tests |
    | Performance | Timing assertions inside tests |
    | Accessibility | A11y assertions inside UI tests |
    | API contract | Response schema checks inside API tests |
    | Generic "error handling" | Specific negative-path scenarios |
    
    > **Deferral ≠ omission.** Moving a cross-cutting trait out of per-feature TC scope is an **explicit handoff**, not a silent drop. Each row must land somewhere: woven into a TC's data/assertions (the table above) OR owned by a named app-level suite (XSS / perf / a11y regression suite). If no such suite exists for a trait the feature genuinely exposes, file the gap (Deferred TC or a note in the ATR) — never let it evaporate.
    
    A real scenario is a **user flow**: clear business objective, concrete precondition + action, verifiable outcome. The TC name uses the `should` form — `{US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]`; reserve `Validate <feature>` for the GROUPING layer (Test Set summary / `describe()`), never for the individual case.
    
    ### Source-code validation (mandatory before documenting)
    
    The design in the ATP was written before code existed. Before creating any TC:
    
    1. Open the implementation plan (if any) and list the files it touches.
    2. Grep the actual code for `data-testid=`, route handlers, API paths, and text formats.
    3. Compare the ATP's assumptions against what the code does. If they diverge, correct the TC design and add a Refinement Notes section.
    
    Common discrepancies to check for:
    - An API the ATP assumed exists turns out to be SSR/direct DB.
    - UI text format in the ATP ("based on N reviews") vs reality ("(N reviews)").
    - Hardcoded IDs in the ATP vs variable pattern required in TMS.
    
    Skipping this step is the single most common cause of invalid automated tests later.
    
    ### Sprint TCs are DRAFTS — refine them, do not inherit them
    
    Whatever `/sprint-testing` Stage 1 left behind — Xray `Test` items, or ATP outlines under jira-native — was written to run **once, this sprint, by the person who wrote it**. It is an input to this phase, never its output. Before any of it enters the regression repository, refine it:
    
    | What Stage 1 produced | What this phase must do |
    |---|---|
    | **Title** | re-derive it to the canonical form (§"Title on promotion") — a sprint title reads for the tester who was there, a regression title reads for whoever runs it in six months |
    | **Steps / Gherkin** | raise to *repeatable* detail: no "as before", no implicit state, no step that only makes sense right after the previous test. Parameterize same-behavior data variants into one `Scenario Outline` (doctrine §Part 2.5) rather than leaving N near-duplicates |
    | **Preconditions** | make them explicit and buildable from a cold environment. A sprint test may have relied on data the tester happened to have; a regression test may not |
    | **Variables** | replace every hardcoded id / email / UUID captured during the sprint with `{variable}` + a Variables table saying how to obtain it |
    | **Scope** | a sprint TC that turned out to cover two (precondition, action) pairs splits here; two that cover the same pair merge (TC identity rule below) |
    
    Record what changed. A refined TC carries a short **Refinement Notes** line in its Description (same section the source-code validation above writes to) naming what was tightened and why — otherwise a reviewer cannot tell a refined TC from an untouched sprint artifact.
    
    Under jira-native with `{{TC_CREATION_STAGE}}` = `auto` there is no sprint `Test` item to refine — the outline in the ATP plays that role, and the same table applies to it.
    
    ### TC identity rule (load-bearing)
    
    **A TC is defined by Precondition + Action**. All expected results from the same (precondition, action) pair belong to the **same TC**, not separate TCs.
    
    ```
    Same TC:                                    Different TCs:
      Precondition: valid credentials             Precondition: valid credentials     -> TC-A
      Action:       submit login                  Precondition: locked account        -> TC-B
      Assertions:   redirect + token + welcome    Precondition: invalid credentials   -> TC-C
                    (all one TC)                  (all same action, but preconditions differ)
    ```
    
    Splitting one (precondition, action) into N "check panel A / check panel B / check panel C" TCs is a textbook anti-pattern. One TC, multiple assertions.
    
    ### Technique-driven TC derivation (1:N — full canon: `agentic-qa-core/references/test-design-doctrine.md`)
    
    One AC yields **multiple** TCs by default. Derive them by the AC's shape, then let the TC-identity rule above merge only *within* a partition — never across partitions, boundaries, or states. Reduce an AC to a single TC only with a written `trivially atomic` justification.
    
    | Trigger in the AC | Technique | TCs produced |
    |---|---|---|
    | Any input (always) | **Equivalence Partitioning** | same-output inputs → one parameterized TC (Scenario Outline + Examples); different-output inputs → separate TCs |
    | A range / limit / length / date-window | **Boundary Value Analysis** | TCs at `min-1·min·min+1 … max-1·max·max+1` + zero / empty / null / overflow (EP alone misses off-by-one) |
    | A status / lifecycle field | **State-Transition** | one TC per valid transition + per invalid transition |
    | 2+ interacting conditions | **Decision Table** | enumerate combos, collapse equivalents, one TC per surviving rule |
    | 3+ combinable factors | **Pairwise** | all-pairs TC set (log the reduction) |
    
    These are **candidate scenarios** derived by technique — not yet TMS work items. ROI (Phase 2) then decides which become **persistent regression TCs** (Candidate → automated, Manual → manual) and which stay **Deferred** (recorded in the prioritization report, **NOT created in the TMS**). Deriving widely is free; persisting is ROI-gated — most scenarios are Deferred. You document a scenario because it will be re-run, never to hit a count.
    
    > **Improvement bridge (`agentic-qa-core/references/defect-management-doctrine.md` Part 1).** When a test-beyond-AC exposes a gap **because the AC was under-specified or absent** — the system violated no defined criterion — the right artifact is an **Improvement** issue (filed per the doctrine, or delegated to `/sprint-testing`), NOT a regression TC and NOT a silent widening of the Story's ACs. Track the proposal as an Improvement; do not edit the Story's AC set after the fact.
    
    ---
    
    ## Phase 2 — Prioritize (ROI)
    
    Every scenario passes three gates in order. Fail any gate -> Deferred.
    
    ### Phase 0: The three filter questions
    
    1. **Does it protect against FUTURE regressions?** If the bug was a one-time typo in a stable area, the answer is no. Defer.
    2. **Are there PRIOR bugs in this area?** Yes -> prioritize even with moderate ROI ("it failed once, it can fail again").
    3. **Is it an APP-level concern or a FEATURE-level concern?** XSS / a11y / performance / responsive are APP-level suites, not per-feature TCs. Defer from this scope.
    
    ### ROI formula (load-bearing)
    
    ```
    ROI = (Frequency x Impact x Stability) / (Effort x Dependencies) / 10
    ```
    
    The trailing `/ 10` is a **normalization constant, not a sixth factor**. The raw quotient over 1-5 factors spans `0.04 .. 125`, while every threshold and worked example in this skill reads on a `0.004 .. 12.5` scale — so divide by 10, always. A neutral all-3s scenario lands at `(3x3x3)/(3x3)/10 = 0.3` → Deferred, which is the intended default (most scenarios should be Deferred).
    
    Each factor is scored 1-5 independently:
    
    | Factor | 1 | 2 | 3 | 4 | 5 |
    |--------|---|---|---|---|---|
    | Frequency (how often run) | Yearly / rarely | Every release | Every sprint | Daily | Every PR / commit |
    | Impact (if it fails) | Cosmetic | Minor inconvenience | Degrades UX | Blocks feature | Revenue / core business |
    | Stability (of the flow) | Very volatile | Unstable | Moderate | Stable, minor changes | Unchanged for months |
    | Effort (to automate) | Trivial | Low (hours) | Moderate (1-2 days) | High (several days) | Very high (week+) |
    | Dependencies | None | 1-2 simple | 3-4 | 5+ | Complex externals |
    
    Note: Effort and Dependencies are **divisors** — higher score = worse. The other three are multipliers.
    
    ### Component value bonus
    
    If a TC is reusable across multiple E2E flows:
    
    ```
    Component Value = Base ROI x (1 + 0.2 x N)
    ```
    
    where `N` = number of E2E flows that consume it. A moderate-ROI atomic like `authenticateSuccessfully` can cross out of the defer bands purely through reuse. **`N` is a qualitative estimate, capped at 3** (max multiplier `x1.6`): no tool counts call-sites, so read it off the ATP / feature map and record the estimate in the ROI comment. Full rule: `references/tms-conventions.md` §9 "Component value bonus".
    
    ### Three outcomes (load-bearing)
    
    Every scenario ends in exactly one of these buckets. There is no fourth.
    
    | Outcome | Triggers it | Where it goes next | TMS status flow |
    |---------|------------|--------------------|------------------|
    | **Candidate** | ROI > 3.0, OR (ROI 1.5-3.0 AND prior bug), OR critical happy path | Feeds `test-automation` skill | Draft -> In Design -> READY -> In Review -> Candidate |
    | **Manual** | ROI 0.5-1.5 AND not automatable (human judgment, visual inspection), OR explicitly manual-only | Terminal: manual regression suite | Draft -> In Design -> READY -> MANUAL |
    | **Deferred** | ROI < 0.5, OR failed Phase-0 filter, OR one-time validation, OR **it matched neither row above** (Deferred is the default bucket: ROI under 3.0 with no prior bug and no critical-path justification lands here) | Terminal: not in regression. Can be revisited if system changes | **jira-native**: do not create a TC in the TMS — document as Deferred in `.context/reports/PRIORITIZATION-<scope>.md` AND in the mirrored Jira comment (§"Reports — fixed filenames"; the local file is `[LOCAL]`, the comment is the durable record). **jira-xray**: the sprint `Test` (created in `/sprint-testing` Stage 1) is **not promoted** to the Regression Test Plan (RTP) — it stays as a sprint execution artifact, not deleted. |
    
    > **Band authority**: the three outcomes above are the *TMS-action* collapse of the 5-band table in `references/tms-conventions.md` §9 ("ROI decision thresholds (strict)"). That table is the authority on band boundaries and it resolves the middle bands explicitly — `1.5-3.0` is "Case by case: prior bug? critical flow? **If no, defer**", `0.5-1.5` is "Probably defer: include only if prior bug". Read it whenever a score falls between `0.5` and `3.0`.
    
    **Rule of thumb**: if more than 50% of candidates end up Candidate or Manual, re-apply Phase 0 more strictly. Most scenarios should be Deferred.
    
    > **Modality changes the verb in Phase 3, not the verdict here.** The ROI verdicts (Candidate / Manual / Deferred) are identical in both modalities. What differs is the action: **jira-native** — Phase 3 *creates* `Test` work items for Candidate + Manual only (Deferred is report-only). **jira-xray** — the `Test` work items already exist from `/sprint-testing` Stage 1 (Xray's `Test` is the execution unit); Phase 3 *selects + promotes* the Candidate/Manual ones into the RTP (re-derived canonical title, then label `regression-candidate`) and **enriches** them (rich Gherkin, parameterization, edge elaboration — the "specify much more" pass). Deferred sprint Tests are left as-is, unpromoted. See `sprint-testing/SKILL.md` §"TC creation timing (modality-aware)".
    
    ---
    
    ## Phase 3 — Document in TMS
    
    ### Preflight: Regression Epic
    
    Every documented TC must have a parent Regression Epic (single test repository for the project).
    
    > **This Regression Epic IS the QA Test Repository process epic** (`agentic-qa-core/references/defect-management-doctrine.md` Part 4). Resolve it **found-or-created** by the configured name `qa.qa_epics.test_repository_epic.name` (**"QA Test Repository"**); on absence create it once, write the test-repository strategy into its description, and cache its key into `.agents/project.yaml` `qa.qa_epics.test_repository_epic.key`. It is a **QA process epic — never a product/dev epic, never unparented.** Per the three-axis model this parent says only "which QA bucket tracks the Test"; the Test's **product area travels on `components`** (Part 3) and its **Story coverage travels on the issue link** (Part 4) — never on this parent.
    
    > **Prerequisite**: Load `/acli` skill before executing commands below.
    
    ```
    [ISSUE_TRACKER_TOOL] Search Issues:
      project: {{PROJECT_KEY}}
      query: type = Epic AND summary ~ "QA Test Repository"      # resolve by configured name qa.qa_epics.test_repository_epic.name
    ```
    
    If none exists, ask the user before creating one with name `QA Test Repository` (the value of `qa.qa_epics.test_repository_epic.name`) and labels `QA-Artifact, regression` (`QA-Artifact` is the mandatory identity label on every QA process epic).
    
    ### Preflight: Test Sets — ATS (mandatory per-Story) + TS (optional feature grouping)
    
    Two Set altitudes — do not conflate:
    
    - **ATS** (Acceptance Test Set) — `ATS: {US_ID}: {story title}` — **mandatory per Story, even when the Story has a single TC**. Holds ALL the Story's TCs and anchors coverage: the ATS→Story `is tested by` link is what fills the Xray coverage panel (ATP/ATR links do NOT — live-verified 2026-08-21, see `.session/artifact-ladder-refactor/scoping.md` §Verificación). Parented to **QA Test Artifacts**; `components` **inherited from the Story — mandatory** (the components exemption applies to feature-level `TS:` only). Phase 3 is **Set-first**: find-or-create the Story's ATS, add the TCs to it, THEN derive the ATP's and the Execution's test lists from the ATS membership.
    - **TS** (feature-level Test Set) — `TS: <EPIC_KEY|module>: Validate <feature>` — **optional** grouping (smoke / regression / feature suite), 1:1 with the Epic/module. `components` optional here — a feature Set spans modules by design. **Ask the user before creating** one (mirror the Regression-Epic ask-before-create rule — creation is otherwise async/manual; the AI only creates it lazily here when a promotion needs it). **Only promoted, regression-worthy Tests (Candidate/Manual) are added to the feature TS** — Deferred sprint Tests are NOT added.
    
    Containers: **Regression Epic** = repository umbrella · **ATS** = per-Story coverage set · **TS** = optional feature grouping · **Test Plan** = execution/regression scope.
    
    - **Modality jira-xray**: resolve/create Sets via `[TMS_TOOL]`; TC∈Set membership is Xray-internal (GraphQL) — NEVER a Jira issue link. The ATS→Story `is tested by` edge IS a Jira issue link and is mandatory.
    - **Modality jira-native**: instance **has the Test Set work type** → create the ATS item and express membership as **TC→ATS issue links** (explicit carve-out: the "membership is never a link" rule is xray-only) plus the ATS→Story link. Work type **absent** → **no ATS**: link each TC to the Story directly (`is tested by` — the cascade's last-resort path) and keep feature grouping via the Regression Epic + a feature/Epic label (e.g. `epic-<EPIC_KEY>` or the feature slug).
    
    ### Entity model: ATP / ATR / ATS / TC
    
    Five entities. **Traceability model:** the **Story links to its ATS, ATP and ATR** ("is tested by"), but only one of those edges carries coverage — **the ATS→Story link is what fills the Xray coverage panel; the ATP→Story and ATR→Story links are administrative traceability and contribute ZERO coverage** (live-verified 2026-08-21, `.session/artifact-ladder-refactor/scoping.md` §Verificación). The **ATP "designs" the TCs** (TC "is designed by" ATP) and the **ATR "executes" the TCs** (TC "is executed by" ATR). A **direct TC→Story link is the cascade's LAST RESORT** (used when no ATS exists — e.g. jira-native without the Test Set work type), not the default: TCs normally aggregate through the ATS. The defect is a TC with NO path to its Story, not the direct link itself. Full doctrine: `agentic-qa-core/references/traceability-linking.md` + `references/tms-architecture.md`.
    
    | Entity | Created | Naming | Main content |
    |--------|---------|--------|--------------|
    | **US** (Story) | Pre-existing | `{{PROJECT_KEY}}-{n}` | The requirement |
    | **ATP** | Content pre-sprint in `{{jira.acceptance_test_plan}}` (shift-left); the Test Plan ITEM by `/sprint-testing` Stage 1 from that field — or by this phase (find-or-create) when running module-driven and no Story ATP item exists | `ATP: {STORY-KEY}: {story title}` | Test Analysis + AC-to-TC coverage |
    | **ATR** | Stage 1 (or now, if missing) | `ATR: {STORY-KEY}: Story Testing` | Test Report + execution results |
    | **TC** | Stage 4 (this phase) | `{US_ID}: TC#: should <expected outcome> [<connector> <condition>] [given <precondition>]` | Precondition + Action + Expected |
    | **ATS** | Stage 1 (or now, find-or-create — MANDATORY per Story) | `ATS: {US_ID}: {story title}` | ALL the Story's TCs (even one). Coverage anchor: ATS→Story `is tested by` fills the coverage panel. Components inherited from the Story (mandatory). Parent: QA Test Artifacts. |
    | **TS** (optional) | Lazily in Stage 4 if a promotion needs it (ask first); else pre-existing (async) | `TS: {EPIC-KEY\|module}: Validate {feature}` | OPTIONAL feature-level grouping (1:1 Epic) of promoted regression Tests — smoke/regression suites. Components optional: a feature Set spans modules by design. Native without the work type: replaced by a feature/Epic label, no entity. |
    
    Read `references/tms-architecture.md` when creating ATP/ATR/TC for a ticket, checking required links, or validating that a story is fully documented.
    
    ### Linking order (always — Set-first)
    
    ```
    1. Find-or-create the Story's ATS -> link to US (Story "is tested by" ATS — the coverage-panel link)
    2. Find-or-create ATP (pre-sprint content lives in {{jira.acceptance_test_plan}}; the item usually
       exists from /sprint-testing Stage 1 — create here only when module-driven and no ATP item exists)
       -> link to US (Story "is tested by" ATP — administrative, no coverage)
    3. Create ATR -> link to US (Story "is tested by" ATR — administrative, no coverage)
    4. Update ATP -> link to ATR (bidirectional plan/results)
    5. For each TC:
         Create TC -> add to the ATS (jira-xray: Xray-internal membership; jira-native with the
                      Test Set work type: TC->ATS issue link)
                   -> link to ATP (TC "is designed by" ATP) + ATR (TC "is executed by" ATR)
         # Do NOT link the TC directly to the Story when an ATS exists — TCs aggregate via the ATS.
         # Direct TC->Story is the cascade's LAST RESORT (no ATS available — e.g. jira-native
         # without the Test Set work type). The defect is a TC with NO path, not the direct link.
         # AC coverage is recorded in the ATP's AC-to-TC matrix, not as a Story<->TC issuelink.
    6. Derive the ATP's and the ATR's test lists FROM the ATS membership (Set-first: the ATS holds
       ALL the Story's TCs; Plan and Execution consume that list).
    7. For each PROMOTED (regression-worthy) TC:
         FIRST -> re-derive the canonical title and, if the live summary differs, rewrite it
                  ([ISSUE_TRACKER_TOOL] Update Issue — summary is a Jira field, not an Xray one),
                  THEN verify it matches before anything else touches the TC (see §"Title on
                  promotion"). A wrongly-titled TC must never reach the RTP or carry the label.
         jira-xray  -> [TMS_TOOL] add TC to the OPTIONAL feature TS (resolve/create per Preflight) + [TMS_TOOL] add to the RTP
                       + [ISSUE_TRACKER_TOOL] label `regression-candidate` (labels are a Jira field; xray-cli has no update-label for existing Tests)
         jira-native -> [ISSUE_TRACKER_TOOL] apply the feature/Epic label (or add to a feature TS item when the work type exists)
    ```
    
    **Every artifact this skill CREATES carries `assignee` = the authenticated session user, set at create time** — the RTP, the ATS, the optional feature TS, every `Test`, every Precondition (`agentic-qa-core/references/artifact-lifecycle.md` §2). This is load-bearing, not bookkeeping: **Xray refuses membership edits on a Test Plan the caller does not own**, so an unassigned RTP cannot have promoted Tests added to it, and the failure surfaces as a mid-flow blocker long after the Plan exists. If the find-or-create step RETURNS an artifact owned by someone else, do not reassign it silently — ask the user first.
    
    **Plan and Set lifecycle** (`agentic-qa-core/references/artifact-lifecycle.md` §1):
    
    | Artifact | Born | This skill moves it to | Then |
    |---|---|---|---|
    | **RTP** (Regression Test Plan) | `{{jira.status.test_plan.planning}}` | `{{jira.status.test_plan.ready}}` via `{{jira.transition.test_plan.designed}}` on the first promotion | **stays `ready` forever** — the RTP is long-lived. NEVER fire `{{jira.transition.test_plan.complete}}` on it |
    | **ATS** (per-Story Set) | `{{jira.status.test_set.designing}}` | closed by `/sprint-testing` Reporting, not here | — |
    | **TS** (optional feature Set) | `{{jira.status.test_set.designing}}` | **stays `designing`** for the life of the feature | `{{jira.transition.test_set.done}}` only when its Epic closes |
    | **Precondition** | `{{jira.status.precondition.active}}` | nothing — the workflow has no transition out of `active` | stays `active`; that is correct, not a gap |
    
    > Per-op tool resolution + the Gherkin-enrichment CLI gap: `references/jira-test-management.md` §"Stage-4 promote + enrich — tool resolution map". Load `/xray-cli` for command syntax — never hardcode it here.
    
    Creating a TC before the ATS, ATP and ATR exist leaves orphaned references. Fix any broken links with `references/tms-architecture.md` §Traceability Rules.
    
    ### Where candidates go — the RTP handoff
    
    The question this answers is the one a team asks the first time Phase 2 produces a verdict: *those Candidates have to end up in a general regression suite — what is the procedure?* It is this, and it is the last thing Phase 3 does:
    
    1. **Find-or-create the project's Regression Test Plan (RTP)** — one long-lived `Test Plan` item per project, titled `RTP: {PROJECT_KEY|module}: Regression Test Plan`, parented to the **QA Master Test Plan** epic, `assignee` = self at create time (§the lifecycle table above — **Xray refuses membership edits on a Plan the caller does not own**, so an unassigned RTP cannot accept promotions later). Ask the user before creating it, same as the Regression Epic.
    2. **Every `Candidate` TC lands in it.** Title re-derived and verified (§"Title on promotion"), then `regression-candidate` applied, then added to the RTP. `Manual` TCs go to the manual regression suite — the same RTP under jira-xray, distinguished by the `manual-only` label and the `{{jira.status.test_case.manual}}` status, since a manual regression pass runs from the same plan. `Deferred` TCs never enter it; that is the whole point of the verdict.
    3. **The RTP moves to `{{jira.status.test_plan.ready}}` on the first promotion and stays there** — a regression run never completes the plan it ran from.
    4. **Downstream consumers read it from there, not from this session.** `/test-automation` picks up the TCs at `{{jira.status.test_case.candidate}}` carrying `regression-candidate`; `/regression-testing` executes the RTP's membership and writes its STR against it. Neither reads `.context/reports/` — both of those files are `[LOCAL]` and exist only on this machine. **If a Candidate is not in the RTP, it does not exist downstream.**
    
    #### Grouping Candidates into e2e regression flows
    
    A regression suite is not a bag of independent TCs: the same authentication or checkout TC is consumed by several end-to-end journeys, and that reuse is what the Component value bonus (§Phase 2) already scores. Group the Candidates explicitly, at the same altitude `/test-automation` will:
    
    - **One group = one e2e flow** (a user journey that a spec file will run end to end), named for the journey, not the module: `Checkout — guest purchase`, not `Checkout tests`.
    - **A TC reused by 2+ flows is an atomic component** — in KATA terms it becomes a Steps module rather than being duplicated per flow (`test-automation/references/kata-architecture.md`). Name it once, list it under every flow that consumes it, and let the `N` in the Component value bonus equal that count.
    - **Record the grouping in TWO places**: (a) the **RTP description**, as a `## Regression flows` section listing each flow with its member TC keys — this is the durable copy, readable by `/test-automation` and `/regression-testing` without this session; (b) `COVERAGE-MATRIX-<scope>.md`, as a flow column beside the AC → scenario → TC → verdict grid, for the local read.
    - **A Candidate that belongs to no flow is a smell, not a category.** Either it is an atomic component (say which flows consume it) or its journey was never identified — surface it rather than filing it under a catch-all.
    
    ### Creating TCs — modality matrix
    
    | TMS stack | Manual test | Automation-candidate test |
    |-----------|-------------|---------------------------|
    | **Xray on Jira** | **Two-step** (Xray Cloud silently drops inline steps): (1) `[TMS_TOOL] Create Test: type=Manual` **without** inline steps, (2) `[TMS_TOOL] Add Test Step` per step (optionally verify with `[TMS_TOOL] Get Test`), then `[ISSUE_TRACKER_TOOL] Update Issue` to paste the complete Description template | `[TMS_TOOL] Create Test: type=Cucumber, gherkin=<high-quality gherkin>` then `[ISSUE_TRACKER_TOOL] Update Issue` with the Description template |
    | **Native Jira (no Xray)** | `[ISSUE_TRACKER_TOOL] Create Issue: issueType=Test, description=<steps table>` | `[ISSUE_TRACKER_TOOL] Create Issue: issueType=Test, description=<gherkin in Description>` |
    
    Always populate Description with the full TC template (Related Story, Priority, ROI, Prior bugs, Test Design gherkin/steps, Variables table, Implementation Code table, Architecture, Available Test IDs, Preconditions, Expected Results). Read `references/jira-test-management.md` when choosing between Xray and native Jira, or when the Description must be filled.
    
    > **Dispatch**: Use the dispatch defined in §Subagent Dispatch Strategy: **Parallel** when N > 10 TCs (cap = 10 subagents), inline otherwise. The full briefings for both Modality jira-xray (via `/xray-cli`) and Modality jira-native (via `/acli`) live in `references/tms-architecture.md` §"Parallel TC creation". The sharding rule, error protocol, and aggregation contract are documented there. The serial flow below is the canonical procedure each subagent runs internally for its assigned chunk.
    
    ### High-quality Gherkin (for Candidates)
    
    ```gherkin
    @{priority} @regression @automation-candidate @{US_ID}
    Scenario Outline: should <outcome> <connector> <condition>
      """
      Bugs covered: BUG-1, BUG-2
      Related Story: {US_ID}
      """
    
      # === PRECONDITIONS (tester / script builds them) ===
      Given <entity> exists with <identifier>
      And <entity> has <quantity> <elements> where <quantity> <condition>
    
      # === ACTION ===
      When the user navigates to "<route>"
      And the user <main_action>
    
      # === VALIDATIONS ===
      Then <ui_element> is displayed with format "<expected_format>"
      And <additional_validation>
    
      # === EQUIVALENT PARTITIONS ===
      Examples: Happy path
        | ... |
      Examples: Edge case
        | ... |
    ```
    
    Rules that always apply:
    - **Variables, never hardcoded data**: `{mentor_id}` not `550e8400-...`. Include a Variables table with how to obtain each.
    - **Tags always include**: priority (`@critical|@high|@medium|@low`), suite (`@regression`, `@smoke` if critical path), automation flag (`@automation-candidate`), traceability (`@{US_ID}`).
    - **Structured comments**: `# === PRECONDITIONS ===`, `# === ACTION ===`, `# === VALIDATIONS ===`, `# === EQUIVALENT PARTITIONS ===`.
    - **Docstring with metadata**: related story, bugs covered, ROI.
    
    ### Workflow transitions
    
    > **Substrate refe

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related