qaa-agent 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,474 @@
1
+ <purpose>
2
+ Generate test cases and test files from a ticket (GitHub Issue, Jira, Linear, plain text, or file). Extracts acceptance criteria, user stories, and edge cases from the ticket content, scans the dev repo for related source files, generates a traceability matrix mapping acceptance criteria to test cases, then spawns the executor and validator agents to produce and verify test files. Use this workflow to ensure every acceptance criterion has corresponding test coverage before a feature ships.
3
+ </purpose>
4
+
5
+ <required_reading>
6
+ - `CLAUDE.md` -- QA automation standards, test spec rules, naming conventions, quality gates, testing pyramid
7
+ - `agents/qaa-scanner.md` -- Scanner agent definition (repo scanning for related source files)
8
+ - `agents/qaa-executor.md` -- Executor agent definition (test file generation)
9
+ - `agents/qaa-validator.md` -- Validator agent definition (4-layer validation)
10
+ - `templates/test-inventory.md` -- TEST_INVENTORY.md format contract (test case structure)
11
+ </required_reading>
12
+
13
+ <process>
14
+
15
+ <step name="parse_arguments">
16
+ ## Step 1: Parse Ticket Source
17
+
18
+ Parse `$ARGUMENTS` to determine the ticket source type and content.
19
+
20
+ **Supported argument formats:**
21
+
22
+ | Format | Example | Detection |
23
+ |--------|---------|-----------|
24
+ | GitHub Issue URL | `https://github.com/org/repo/issues/123` | Starts with `https://github.com` and contains `/issues/` |
25
+ | GitHub Issue shorthand | `org/repo#123` or `#123` | Contains `#` followed by digits |
26
+ | Jira URL | `https://company.atlassian.net/browse/PROJ-123` | Contains `.atlassian.net/browse/` |
27
+ | Linear URL | `https://linear.app/team/issue/TEAM-123` | Contains `linear.app` |
28
+ | File path | `./tickets/feature-spec.md` | Path exists on disk |
29
+ | Plain text | `"As a user I want to..."` | None of the above patterns match |
30
+
31
+ **Parsing logic:**
32
+
33
+ ```bash
34
+ TICKET_SOURCE="$ARGUMENTS"
35
+ TICKET_TYPE=""
36
+ TICKET_CONTENT=""
37
+
38
+ # Detect source type from the argument pattern
39
+ if matches GitHub URL or shorthand:
40
+ TICKET_TYPE="github"
41
+ elif matches Jira URL:
42
+ TICKET_TYPE="jira"
43
+ elif matches Linear URL:
44
+ TICKET_TYPE="linear"
45
+ elif file exists at path:
46
+ TICKET_TYPE="file"
47
+ else:
48
+ TICKET_TYPE="text"
49
+ ```
50
+
51
+ **If no arguments provided:**
52
+
53
+ Print error and STOP:
54
+ ```
55
+ Error: No ticket source provided.
56
+ Usage: /qa-from-ticket <source>
57
+
58
+ Supported sources:
59
+ GitHub: https://github.com/org/repo/issues/123 or #123
60
+ Jira: https://company.atlassian.net/browse/PROJ-123
61
+ Linear: https://linear.app/team/issue/TEAM-123
62
+ File: ./path/to/ticket.md
63
+ Text: "As a user I want to log in so that I can access my dashboard"
64
+ ```
65
+ </step>
66
+
67
+ <step name="fetch_ticket_content">
68
+ ## Step 2: Fetch Ticket Content
69
+
70
+ Retrieve the ticket content based on the source type.
71
+
72
+ **GitHub Issue:**
73
+
74
+ ```bash
75
+ # For full URL: extract owner, repo, issue number
76
+ # For shorthand #123: use current repo context
77
+ gh issue view {issue_number} --repo {owner/repo} --json title,body,labels,assignees,milestone
78
+ ```
79
+
80
+ Extract from JSON response:
81
+ - `title` -- Issue title
82
+ - `body` -- Issue body (markdown)
83
+ - `labels` -- Issue labels (may indicate priority)
84
+ - `milestone` -- Milestone (may indicate release target)
85
+
86
+ **Jira / Linear URL:**
87
+
88
+ ```bash
89
+ # Use WebFetch to retrieve the ticket page content
90
+ # Extract structured content from the response
91
+ ```
92
+
93
+ If WebFetch fails or authentication is required:
94
+
95
+ ```
96
+ CHECKPOINT:
97
+ type: human-action
98
+ blocking: "Cannot access ticket URL -- authentication required"
99
+ details: "Attempted to fetch: {TICKET_SOURCE}. Received authentication error."
100
+ awaiting: "Provide ticket content as plain text or a file path instead. Or authenticate with the service."
101
+ ```
102
+
103
+ **File path:**
104
+
105
+ ```bash
106
+ # Read the file content directly
107
+ TICKET_CONTENT=$(cat "{TICKET_SOURCE}")
108
+ ```
109
+
110
+ If the file is empty or unreadable, print error: `"Error: Cannot read ticket file: {path}"` and STOP.
111
+
112
+ **Plain text:**
113
+
114
+ ```bash
115
+ TICKET_CONTENT="${TICKET_SOURCE}"
116
+ ```
117
+
118
+ **Print ticket summary:**
119
+
120
+ ```
121
+ Ticket Source: {TICKET_TYPE}
122
+ Title: {extracted title or first line}
123
+ Content Length: {character count}
124
+ ```
125
+ </step>
126
+
127
+ <step name="extract_acceptance_criteria">
128
+ ## Step 3: Extract Acceptance Criteria
129
+
130
+ Parse the ticket content to identify testable acceptance criteria, user stories, edge cases, and priority.
131
+
132
+ **Extraction targets:**
133
+
134
+ | Target | What to Look For | Example |
135
+ |--------|-----------------|---------|
136
+ | Title | Issue title or first heading | "Add password reset flow" |
137
+ | User Story | "As a [role], I want to [action], so that [benefit]" pattern | "As a user, I want to reset my password via email" |
138
+ | Acceptance Criteria | Bullet lists after "Acceptance Criteria", "AC:", "Given/When/Then" patterns | "Given a valid email, When I request reset, Then I receive a reset link" |
139
+ | Edge Cases | Items mentioning: invalid, expired, duplicate, empty, boundary, error, timeout | "Handle expired reset tokens gracefully" |
140
+ | Priority | Labels, priority fields, or keywords: critical, blocker, P0, P1, P2 | "Priority: P0" |
141
+ | Affected Components | File paths, module names, feature areas mentioned | "Auth module", "src/services/auth.service.ts" |
142
+
143
+ **Structured extraction output:**
144
+
145
+ ```
146
+ TICKET_TITLE: "{title}"
147
+ TICKET_PRIORITY: "{P0|P1|P2}"
148
+
149
+ ACCEPTANCE_CRITERIA:
150
+ AC-1: "{criterion text}"
151
+ AC-2: "{criterion text}"
152
+ ...
153
+
154
+ USER_STORIES:
155
+ US-1: "{story text}"
156
+ ...
157
+
158
+ EDGE_CASES:
159
+ EC-1: "{edge case description}"
160
+ EC-2: "{edge case description}"
161
+ ...
162
+
163
+ KEYWORDS: ["{keyword1}", "{keyword2}", ...]
164
+ ```
165
+
166
+ **If no acceptance criteria can be extracted:**
167
+
168
+ ```
169
+ CHECKPOINT:
170
+ type: human-action
171
+ blocking: "Cannot extract acceptance criteria from ticket"
172
+ details: "Ticket content does not contain recognizable acceptance criteria, Given/When/Then patterns, or bullet-pointed requirements. Raw content: {first 500 chars}"
173
+ awaiting: "Provide acceptance criteria explicitly as a numbered list, or reformat the ticket."
174
+ ```
175
+ </step>
176
+
177
+ <step name="scan_related_source">
178
+ ## Step 4: Scan Dev Repo for Related Source Files
179
+
180
+ Search the dev repo for source files related to the ticket's feature area.
181
+
182
+ **Search strategy (using keywords from step 3):**
183
+
184
+ 1. **File name search:** Glob for files matching keywords from the ticket
185
+ - Keywords: module names, feature areas, component names mentioned in the ticket
186
+ - Patterns: `**/*{keyword}*.*` for each keyword
187
+
188
+ 2. **Content search:** Grep for function names, route paths, class names mentioned in the ticket
189
+ - Search for acceptance-criteria-related terms: endpoints, function names, component names
190
+ - Grep patterns: route paths (e.g., `/api/v1/password-reset`), handler names (e.g., `resetPassword`)
191
+
192
+ 3. **Directory search:** Check for feature-organized directories matching the ticket's domain
193
+ - Directories: `src/services/{feature}*`, `src/controllers/{feature}*`, `src/routes/{feature}*`
194
+
195
+ **Build related files list:**
196
+
197
+ ```
198
+ RELATED_FILES:
199
+ - path: "src/services/auth.service.ts"
200
+ relevance: "Contains resetPassword function referenced in AC-1"
201
+ - path: "src/routes/auth.routes.ts"
202
+ relevance: "Contains /api/v1/password-reset endpoint from AC-2"
203
+ - path: "src/controllers/auth.controller.ts"
204
+ relevance: "Controller handling password reset requests"
205
+ ...
206
+ ```
207
+
208
+ **If no related files found:**
209
+
210
+ Print warning but continue:
211
+ ```
212
+ Warning: No source files found matching ticket keywords.
213
+ Keywords searched: {keywords}
214
+ Generating test cases based on ticket content only (no source-level analysis).
215
+ ```
216
+ </step>
217
+
218
+ <step name="generate_test_cases">
219
+ ## Step 5: Generate Test Cases with Traceability Matrix
220
+
221
+ Map each acceptance criterion to one or more test cases, following CLAUDE.md test spec rules.
222
+
223
+ **Test case generation rules:**
224
+
225
+ 1. **One or more test cases per acceptance criterion** -- Each AC must have at least one test case. Complex ACs may produce multiple test cases (happy path + error cases).
226
+
227
+ 2. **One test case per edge case** -- Each extracted edge case becomes a dedicated test case.
228
+
229
+ 3. **Follow naming convention:**
230
+ - Unit tests: `UT-{MODULE}-{NNN}` (for logic-level ACs)
231
+ - API tests: `API-{RESOURCE}-{NNN}` (for endpoint-level ACs)
232
+ - Integration tests: `INT-{MODULE}-{NNN}` (for cross-module ACs)
233
+ - E2E tests: `E2E-{FLOW}-{NNN}` (for user-journey ACs)
234
+
235
+ 4. **Follow CLAUDE.md Test Spec Rules:**
236
+ - Every test case MUST have: unique ID, exact target, concrete inputs, explicit expected outcome, priority
237
+ - Expected outcomes must be concrete (no "works correctly", "handles properly")
238
+ - Concrete inputs with actual values (no "valid data")
239
+
240
+ 5. **Pyramid level assignment:**
241
+ - Pure function or service logic -> Unit test
242
+ - API endpoint behavior -> API test
243
+ - Cross-module interaction -> Integration test
244
+ - Full user journey described in ticket -> E2E test
245
+
246
+ **Write TEST_CASES_FROM_TICKET.md:**
247
+
248
+ ```markdown
249
+ # Test Cases from Ticket
250
+
251
+ ## Ticket Info
252
+
253
+ | Field | Value |
254
+ |-------|-------|
255
+ | Source | {TICKET_SOURCE} |
256
+ | Title | {TICKET_TITLE} |
257
+ | Priority | {TICKET_PRIORITY} |
258
+ | Acceptance Criteria | {AC_COUNT} |
259
+ | Edge Cases | {EC_COUNT} |
260
+ | Test Cases Generated | {TOTAL_TEST_CASES} |
261
+
262
+ ## Traceability Matrix
263
+
264
+ | Acceptance Criterion | Test Case ID | Pyramid Level | Priority |
265
+ |---------------------|--------------|---------------|----------|
266
+ | AC-1: {text} | UT-AUTH-001 | Unit | P0 |
267
+ | AC-1: {text} | API-AUTH-001 | API | P0 |
268
+ | AC-2: {text} | E2E-RESET-001 | E2E | P0 |
269
+ | EC-1: {text} | UT-AUTH-002 | Unit | P1 |
270
+ | ... | ... | ... | ... |
271
+
272
+ ## Test Cases
273
+
274
+ ### Unit Tests
275
+
276
+ #### UT-{MODULE}-{NNN}: {description}
277
+
278
+ | Field | Value |
279
+ |-------|-------|
280
+ | test_id | UT-{MODULE}-{NNN} |
281
+ | target | {file_path}:{function_name} |
282
+ | what_to_validate | {behavior description} |
283
+ | concrete_inputs | {actual input values} |
284
+ | mocks_needed | {dependencies to mock or "None (pure function)"} |
285
+ | expected_outcome | {exact return value, error message, or state change} |
286
+ | priority | {P0|P1|P2} |
287
+ | traces_to | AC-{N} or EC-{N} |
288
+
289
+ [... repeat for all unit tests ...]
290
+
291
+ ### API Tests
292
+
293
+ [... same structure with API-specific fields ...]
294
+
295
+ ### Integration Tests
296
+
297
+ [... same structure with integration-specific fields ...]
298
+
299
+ ### E2E Smoke Tests
300
+
301
+ [... same structure with E2E-specific fields ...]
302
+ ```
303
+
304
+ **Set output directory:**
305
+
306
+ ```bash
307
+ OUTPUT_DIR=".qa-output"
308
+ mkdir -p "${OUTPUT_DIR}"
309
+ ```
310
+
311
+ Write to `{OUTPUT_DIR}/TEST_CASES_FROM_TICKET.md`.
312
+ </step>
313
+
314
+ <step name="generate_test_files">
315
+ ## Step 6: Spawn Executor Agent
316
+
317
+ Build a synthetic generation plan from the test cases and spawn the executor to write test files.
318
+
319
+ **Build generation plan:**
320
+
321
+ Group test cases by feature (from ticket domain) and create task entries following the same structure the executor expects:
322
+
323
+ ```markdown
324
+ # Generation Plan (from ticket)
325
+
326
+ ## Summary
327
+
328
+ | Metric | Value |
329
+ |--------|-------|
330
+ | Total tasks | {N} |
331
+ | Total files | {N} |
332
+ | Feature groups | {N} |
333
+ | Test cases covered | {N} |
334
+ | Framework | {detected from project} |
335
+ | File extension | {ext from project} |
336
+
337
+ ## Tasks
338
+
339
+ ### Task: {feature}-unit
340
+ | Field | Value |
341
+ |-------|-------|
342
+ | task_id | {feature}-unit |
343
+ | feature_group | {feature} |
344
+ | files_to_create | tests/unit/{feature}.unit.spec.{ext} |
345
+ | test_case_ids | UT-{MODULE}-001, UT-{MODULE}-002, ... |
346
+ | depends_on | none |
347
+ | estimated_complexity | {LOW|MEDIUM|HIGH} |
348
+
349
+ [... additional tasks for API, E2E, POM, fixtures ...]
350
+ ```
351
+
352
+ Write to `{OUTPUT_DIR}/GENERATION_PLAN_TICKET.md`.
353
+
354
+ **Spawn executor:**
355
+
356
+ ```
357
+ Task(
358
+ prompt="
359
+ <objective>Generate test files from ticket-derived test cases</objective>
360
+ <execution_context>@agents/qaa-executor.md</execution_context>
361
+ <files_to_read>
362
+ - {OUTPUT_DIR}/GENERATION_PLAN_TICKET.md
363
+ - {OUTPUT_DIR}/TEST_CASES_FROM_TICKET.md
364
+ - CLAUDE.md
365
+ </files_to_read>
366
+ <parameters>
367
+ output_base: {test output directory}
368
+ </parameters>
369
+ "
370
+ )
371
+ ```
372
+
373
+ **Handle executor return:**
374
+
375
+ Extract: `files_created`, `total_files`, `commit_count`, `test_case_count`.
376
+ </step>
377
+
378
+ <step name="validate_generated_tests">
379
+ ## Step 7: Spawn Validator Agent
380
+
381
+ Validate the generated test files against CLAUDE.md standards.
382
+
383
+ ```
384
+ Task(
385
+ prompt="
386
+ <objective>Validate generated test files across 4 layers</objective>
387
+ <execution_context>@agents/qaa-validator.md</execution_context>
388
+ <files_to_read>
389
+ - CLAUDE.md
390
+ - {OUTPUT_DIR}/GENERATION_PLAN_TICKET.md
391
+ </files_to_read>
392
+ <parameters>
393
+ output_path: {OUTPUT_DIR}/VALIDATION_REPORT.md
394
+ </parameters>
395
+ "
396
+ )
397
+ ```
398
+
399
+ **Handle validator return:**
400
+
401
+ Extract: `overall_status`, `confidence`, `issues_found`, `issues_fixed`, `unresolved_count`.
402
+ </step>
403
+
404
+ <step name="print_summary">
405
+ ## Step 8: Print Summary
406
+
407
+ Print a comprehensive summary showing traceability from ticket to tests.
408
+
409
+ ```
410
+ === Test Generation from Ticket Complete ===
411
+
412
+ Ticket: {TICKET_TITLE}
413
+ Source: {TICKET_TYPE} ({TICKET_SOURCE})
414
+
415
+ Acceptance Criteria Coverage:
416
+ Total ACs: {AC_COUNT}
417
+ Covered: {COVERED_COUNT}
418
+ Uncovered: {UNCOVERED_COUNT}
419
+
420
+ Edge Cases:
421
+ Extracted: {EC_COUNT}
422
+ With tests: {EC_TESTED_COUNT}
423
+
424
+ Test Cases Generated:
425
+ Unit Tests: {unit_count}
426
+ Integration Tests: {integration_count}
427
+ API Tests: {api_count}
428
+ E2E Tests: {e2e_count}
429
+ --------------------------
430
+ Total: {total_count}
431
+
432
+ Files Created: {file_count}
433
+
434
+ Validation:
435
+ Status: {PASS|PASS_WITH_WARNINGS|FAIL}
436
+ Confidence: {HIGH|MEDIUM|LOW}
437
+
438
+ Artifacts:
439
+ - {OUTPUT_DIR}/TEST_CASES_FROM_TICKET.md (traceability matrix)
440
+ - {OUTPUT_DIR}/GENERATION_PLAN_TICKET.md (generation plan)
441
+ - {OUTPUT_DIR}/VALIDATION_REPORT.md (validation results)
442
+ - {test file paths...} (generated test files)
443
+ ===========================================
444
+ ```
445
+ </step>
446
+
447
+ </process>
448
+
449
+ <output>
450
+ This workflow generates tests mapped 1:1 to ticket acceptance criteria.
451
+
452
+ **Artifacts produced:**
453
+
454
+ | Artifact | When Produced | Description |
455
+ |----------|---------------|-------------|
456
+ | TEST_CASES_FROM_TICKET.md | Always | Test cases with traceability matrix mapping ACs to test IDs |
457
+ | GENERATION_PLAN_TICKET.md | Always | Synthetic generation plan for the executor agent |
458
+ | Test files (unit, API, E2E, POM, fixtures) | Always | Actual test code following CLAUDE.md standards |
459
+ | VALIDATION_REPORT.md | Always | 4-layer validation of generated test files |
460
+
461
+ **Traceability guarantee:** Every acceptance criterion in the ticket maps to at least one test case. The traceability matrix in TEST_CASES_FROM_TICKET.md documents this mapping with `traces_to` fields.
462
+ </output>
463
+
464
+ <error_handling>
465
+ | Error | Cause | Action |
466
+ |-------|-------|--------|
467
+ | No ticket source provided | Missing argument | Print usage help, STOP |
468
+ | Cannot access ticket URL | Auth required or URL invalid | Checkpoint: ask user for content as text or file |
469
+ | Cannot read ticket file | File does not exist or is empty | Print error with path, STOP |
470
+ | No acceptance criteria found | Ticket lacks structured requirements | Checkpoint: ask user to provide ACs explicitly |
471
+ | No related source files found | Keywords do not match any files | Warning only -- continue with ticket-only analysis |
472
+ | Test framework not detected | No config files in project | Executor checkpoints for user to specify framework |
473
+ | Validation FAIL | Generated tests have quality issues | Report issues in VALIDATION_REPORT.md for review |
474
+ </error_handling>