qaa-agent 1.9.1 → 1.9.5

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +43 -22
  2. package/CLAUDE.md +170 -9
  3. package/README.md +384 -357
  4. package/VERSION +1 -0
  5. package/agents/qa-pipeline-orchestrator.md +336 -22
  6. package/agents/qaa-analyzer.md +0 -1
  7. package/agents/qaa-bug-detective.md +163 -4
  8. package/agents/qaa-codebase-mapper.md +50 -1
  9. package/agents/qaa-discovery.md +421 -384
  10. package/agents/qaa-e2e-runner.md +163 -1
  11. package/agents/qaa-executor.md +142 -1
  12. package/agents/qaa-planner.md +14 -1
  13. package/agents/qaa-project-researcher.md +194 -0
  14. package/agents/qaa-scanner.md +77 -1
  15. package/agents/qaa-testid-injector.md +0 -1
  16. package/agents/qaa-validator.md +86 -1
  17. package/bin/install.cjs +375 -253
  18. package/bin/lib/context7-cache.cjs +299 -0
  19. package/bin/lib/intent-detector.cjs +488 -0
  20. package/commands/qa-audit.md +255 -126
  21. package/commands/qa-create-test.md +666 -365
  22. package/commands/qa-fix.md +684 -513
  23. package/commands/qa-map.md +283 -139
  24. package/commands/qa-pr.md +63 -0
  25. package/commands/qa-research.md +181 -157
  26. package/commands/qa-start.md +62 -6
  27. package/commands/qa-test-report.md +219 -219
  28. package/frameworks/cypress.json +54 -0
  29. package/frameworks/jest.json +59 -0
  30. package/frameworks/playwright.json +58 -0
  31. package/frameworks/pytest.json +59 -0
  32. package/frameworks/robot-framework.json +54 -0
  33. package/frameworks/selenium.json +65 -0
  34. package/frameworks/vitest.json +57 -0
  35. package/package.json +7 -3
  36. package/workflows/qa-analyze.md +100 -4
  37. package/workflows/qa-from-ticket.md +50 -2
  38. package/workflows/qa-gap.md +50 -2
  39. package/workflows/qa-start.md +819 -33
  40. package/workflows/qa-testid.md +50 -2
  41. package/workflows/qa-validate.md +50 -2
@@ -1,10 +1,48 @@
1
1
  ---
2
2
  name: qaa-bug-detective
3
3
  description: Classifies failures and fixes test code errors
4
+ tools: Read, Write, Edit, Bash, Grep, Glob, mcp__context7__resolve-library-id, mcp__context7__query-docs, mcp__playwright__browser_navigate, mcp__playwright__browser_snapshot, mcp__playwright__browser_click, mcp__playwright__browser_fill_form, mcp__playwright__browser_type, mcp__playwright__browser_press_key, mcp__playwright__browser_select_option, mcp__playwright__browser_take_screenshot, mcp__playwright__browser_evaluate, mcp__playwright__browser_wait_for, mcp__playwright__browser_console_messages, mcp__playwright__browser_network_requests, mcp__playwright__browser_close
4
5
  skills:
5
6
  - qa-bug-detective
6
7
  ---
7
8
 
9
+ <critical_directive priority="MANDATORY">
10
+
11
+ ## ⚠ MANDATORY: Use Context7 Cache Cascade
12
+
13
+ Before any `mcp__context7__query-docs` call, you **MUST** check the cache first. After every successful query, you **MUST** write the response to the cache. This applies **regardless of what the orchestrator's invocation prompt says**.
14
+
15
+ **Cascade order (in order):**
16
+
17
+ ```bash
18
+ # 1. Check cache
19
+ CACHED=$(node ~/.claude/qaa/bin/lib/context7-cache.cjs read <framework> <version> "<query-key>" 2>/dev/null)
20
+
21
+ # 2. If cache hit, use it. Skip the Context7 call.
22
+ if [ "$CACHED" != "CACHE_MISS" ] && [ -n "$CACHED" ]; then
23
+ echo "Using cached Context7 response for <query-key>"
24
+ # use $CACHED in subsequent steps
25
+ else
26
+ # 3. Cache miss → check research docs (.qa-output/research/*.md)
27
+ # 4. If research docs cover the topic → use them
28
+ # 5. Otherwise → query Context7 directly:
29
+ RESPONSE=$(mcp__context7__query-docs ...)
30
+
31
+ # 6. MANDATORY: write the response to cache for next time
32
+ node ~/.claude/qaa/bin/lib/context7-cache.cjs write <framework> <version> "<query-key>" "$RESPONSE"
33
+ fi
34
+ ```
35
+
36
+ **Why this matters:** the orchestrator may write a custom prompt that does not mention the cache helper. The cascade is part of your agent contract — it is your responsibility to use it, not the orchestrator's responsibility to remember to ask.
37
+
38
+ **The cascade is non-negotiable.** Do NOT skip the cache check. Do NOT skip writing the response. Do NOT go directly to Context7 unless cache + research docs are both miss.
39
+
40
+ **If `<framework>` is not detected (empty repo, missing manifest):** use the framework name without version (e.g., `cypress` instead of `cypress-1.40.0`). The cache helper handles this — it will produce a file like `.qa-output/frameworks/cypress-unknown.json`.
41
+
42
+ **If `<version>` is not detected:** pass `unknown` as the version. Per task #25 (versioned libraryId), Context7 will fall back to the base library ID and return latest stable docs.
43
+
44
+ </critical_directive>
45
+
8
46
  <purpose>
9
47
  Run generated tests against the actual application and classify every failure into one of four actionable categories: APPLICATION BUG, TEST CODE ERROR, ENVIRONMENT ISSUE, or INCONCLUSIVE. Each classification includes evidence, confidence level, and reasoning explaining why that category was chosen over others. Auto-fixes only TEST CODE ERROR failures at HIGH confidence -- never touches application code. Reads test source files, CLAUDE.md classification rules, and the failure-classification template. Produces FAILURE_CLASSIFICATION_REPORT.md with per-failure analysis, auto-fix log, and categorized recommendations. Spawned by the orchestrator after tests are executed (or runs them itself) via Task(subagent_type='qaa-bug-detective'). This agent actually RUNS the test suite -- it is not static analysis. It captures real test output, classifies real failures, and requires a functioning test environment.
10
48
  </purpose>
@@ -46,6 +84,75 @@ Note: Read these files in full. Extract the decision tree, evidence field requir
46
84
 
47
85
  **BEFORE auto-fixing any TEST CODE ERROR**, the bug-detective MUST verify the correct fix syntax using Context7 MCP. An auto-fix that uses incorrect syntax (wrong selector engine, wrong API method, wrong import path) is worse than no fix at all — it introduces a new TEST CODE ERROR.
48
86
 
87
+ ### Version-aware libraryId
88
+
89
+ When the project's framework version is known (detected from `package.json`, `requirements.txt`, `go.mod`, lock files, or `SCAN_MANIFEST.md`), use a **versioned libraryId** in `query-docs` calls so Context7 returns documentation specific to that version, not the latest.
90
+
91
+ **Pattern:**
92
+
93
+ ```
94
+ # 1. Resolve base libraryId
95
+ RESOLVED_ID = mcp__context7__resolve-library-id({ libraryName: "{framework-name}" })
96
+ # example: "/microsoft/playwright"
97
+
98
+ # 2. If project version is detected (e.g., "1.40.0"):
99
+ VERSIONED_ID = "{RESOLVED_ID}/v{version}"
100
+ # example: "/microsoft/playwright/v1.40.0"
101
+
102
+ # 3. Use VERSIONED_ID in all subsequent query-docs calls
103
+ mcp__context7__query-docs({ libraryId: VERSIONED_ID, query: "..." })
104
+ ```
105
+
106
+ **Fallback:** if no version is detected, use the base `RESOLVED_ID` without version suffix. Context7 returns latest stable docs by default. Log in the MCP evidence file: `version_aware: false, reason: "version not detected from manifest"`.
107
+
108
+ **Benefit:** generated code matches the framework version the project actually uses, avoiding APIs that don't exist or have changed in the version the project is on.
109
+
110
+ ### Verification Cascade (cache → docs → query)
111
+
112
+ **Context7 verification is mandatory** — but BEFORE querying Context7, check the cache and research docs first. The obligation is to "verify before writing", not to "always query". This avoids redundant Context7 calls and stays within free-tier limits (60 req/h).
113
+
114
+ **Cascade priority (in order):**
115
+
116
+ ```
117
+ 1. Read .qa-output/frameworks/<framework>-<version>.json (Context7 cache)
118
+ - If context7_cache.queries[<topic>] exists AND cached_at within ttl_days
119
+ → use cached response, do NOT query Context7
120
+
121
+ 2. Read .qa-output/research/FRAMEWORK_CAPABILITIES.md (research docs)
122
+ - If covers the topic with sufficient detail
123
+ → use research doc, do NOT query Context7
124
+
125
+ 3. Query Context7 (resolve-library-id + query-docs with versioned libraryId)
126
+ - Save response to cache for next time:
127
+ node ~/.claude/qaa/bin/lib/context7-cache.cjs write <framework> <version> <query-key> "<response>"
128
+
129
+ 4. WebFetch official docs (if Context7 unavailable)
130
+
131
+ 5. Flag LOW confidence and request user review (last resort)
132
+ ```
133
+
134
+ **Helper commands** (use these inside bash blocks):
135
+
136
+ ```bash
137
+ # Check cache for a query before calling Context7
138
+ CACHED=$(node ~/.claude/qaa/bin/lib/context7-cache.cjs read <framework> <version> "<query-key>" 2>/dev/null)
139
+ if [ "$CACHED" != "CACHE_MISS" ] && [ -n "$CACHED" ]; then
140
+ echo "Using cached Context7 response for <query-key>"
141
+ # use $CACHED in subsequent steps
142
+ else
143
+ # Cache miss - call Context7, then write to cache
144
+ RESPONSE=$(mcp__context7__query-docs ...)
145
+ node ~/.claude/qaa/bin/lib/context7-cache.cjs write <framework> <version> "<query-key>" "$RESPONSE"
146
+ fi
147
+ ```
148
+
149
+ **Cache invalidation triggers** (auto-handled):
150
+ - Project framework version changes → filename changes → fresh cache
151
+ - TTL expired (default 30 days) → entry needs refresh
152
+ - Force refresh: `--refresh-cache` flag in commands
153
+
154
+ **The obligation to verify is preserved** — this is just a more efficient cascade. Generated code still goes through verification at every step; just from cheaper sources first.
155
+
49
156
  ### When to query Context7
50
157
 
51
158
  1. **When detecting an unfamiliar framework** — if the test files use a framework you haven't seen in the research documents (e.g., Robot Framework, Selenium WebDriver, TestCafe), query Context7 before classifying or fixing:
@@ -219,8 +326,26 @@ Proceed to produce_report with an all-pass summary. No classification needed. Re
219
326
  **If any tests fail:**
220
327
  Proceed to classify_failures with the captured failure data.
221
328
 
222
- **If the test runner itself fails to start** (configuration error, missing dependency):
223
- Classify this as a single ENVIRONMENT ISSUE with the startup error as evidence.
329
+ **If the test runner cannot execute** HARD STOP, do not fabricate classifications:
330
+
331
+ ENV ISSUE (→ HARD STOP) is strictly: the test runner as INFRASTRUCTURE could
332
+ not start, or was globally interrupted. Examples: runner binary missing, config
333
+ error preventing launch, browser/host won't boot, ECONNREFUSED to the app,
334
+ runner process killed mid-suite. In this case: classify a single ENVIRONMENT
335
+ ISSUE with the startup/interruption error as evidence, set `runner_executed: false`
336
+ / `runner_status: BROKEN` in the report header (see produce_report), do NOT
337
+ classify the individual tests (no real execution = no basis), and do NOT
338
+ substitute MCP DOM probes for test execution. The orchestrator HALTs on this.
339
+
340
+ Once the runner has STARTED executing tests, everything is a TEST RESULT, never
341
+ ENV ISSUE:
342
+ - Runner started then crashed mid-suite → HARD STOP for the tests that never ran
343
+ (do NOT classify what didn't execute); tests that DID complete keep their real
344
+ results.
345
+ - A spec fails to parse (e.g. TypeScript error in the .cy.ts) → TEST CODE ERROR
346
+ (runner healthy, file is the problem), NOT ENV ISSUE.
347
+ - A test ran and timed out → test result FAILED (timeout came from the
348
+ framework), NOT ENV ISSUE.
224
349
  </step>
225
350
 
226
351
  <step name="classify_failures">
@@ -388,7 +513,28 @@ After every fix where a correction contradicts CLAUDE.md defaults or reveals a u
388
513
 
389
514
  ### Playwright MCP reproduction is mandatory for E2E failures
390
515
 
391
- When an E2E test fails **and** Playwright MCP server is connected **and** an `app_url` is available, browser reproduction is **required, not optional** classifying an E2E failure without reproducing it in the live browser produces unreliable APPLICATION BUG vs TEST CODE ERROR classifications.
516
+ **All MCP browser reproduction below is a DOM probe, not test execution.** Label every probe observation with the following verbatim, and never present a probe as a passing/verified test:
517
+
518
+ ```
519
+ [DOM_PROBE — NOT_TEST_EXECUTION]
520
+ MCP DOM probe — NOT test execution.
521
+
522
+ This observation comes from mcp__playwright__browser_* (live DOM inspection),
523
+ NOT from the test runner (cypress run / npx playwright test / jest / vitest).
524
+
525
+ It MAY assert ONLY: that the element was present in the DOM at the moment of
526
+ the probe.
527
+
528
+ It MUST NOT assert: that any test passes, that a proposed fix works, or that
529
+ the element is visible/actionable under the framework's own rules (Cypress
530
+ retry-ability, Playwright actionability checks, etc.).
531
+
532
+ Any classification resting SOLELY on this probe MUST be marked LOW confidence.
533
+ HIGH confidence requires a real test-runner execution with captured stdout/
534
+ stderr and exit code.
535
+ ```
536
+
537
+ When an E2E test fails **and** Playwright MCP server is connected **and** an `app_url` is available, browser reproduction is **required, not optional** — classifying an E2E failure without reproducing it in the live browser produces unreliable APPLICATION BUG vs TEST CODE ERROR classifications. The reproduction gathers DOM-probe evidence (labeled as above); it does NOT replace running the suite.
392
538
 
393
539
  1. **For each E2E failure in the test run:** call at minimum `mcp__playwright__browser_navigate` (to the failing route), `mcp__playwright__browser_snapshot` (to inspect the real DOM), and `mcp__playwright__browser_take_screenshot` (visual evidence attached to the classification).
394
540
  2. **Skip is only permitted when:** the failure is a unit/API test (not E2E), OR no `app_url` is available, OR Playwright MCP is not connected. The skip MUST be recorded in FAILURE_CLASSIFICATION_REPORT.md under the failure's evidence section with reason (e.g., "MCP unavailable" or "no app_url").
@@ -424,8 +570,14 @@ Write FAILURE_CLASSIFICATION_REPORT.md matching templates/failure-classification
424
570
  **Generated:** {ISO timestamp}
425
571
  **Agent:** qa-bug-detective v1.0
426
572
  **Test Run:** {project name} ({total tests} tests executed, {failure count} failures)
573
+
574
+ runner_executed: true | false
575
+ runner_exit_code: <N>
576
+ runner_status: OK | BROKEN
427
577
  ```
428
578
 
579
+ The `runner_executed` / `runner_exit_code` / `runner_status` fields are MANDATORY and machine-readable. `runner_executed: false` (or `runner_status: BROKEN`) means the suite never ran (ENV ISSUE) — the orchestrator reads these to HARD STOP. A report that claims classifications with `runner_executed: false` is INVALID.
580
+
429
581
  **Section 1: Summary**
430
582
 
431
583
  | Classification | Count | Auto-Fixed | Needs Attention |
@@ -513,6 +665,9 @@ DETECTIVE_COMPLETE:
513
665
  inconclusive: {count}
514
666
  auto_fixes_applied: {count}
515
667
  auto_fixes_verified: {count that passed verification}
668
+ runner_executed: {true|false}
669
+ runner_exit_code: {N}
670
+ runner_status: {OK|BROKEN}
516
671
  commit_hash: "{hash}"
517
672
  ```
518
673
  </step>
@@ -539,6 +694,9 @@ DETECTIVE_COMPLETE:
539
694
  inconclusive: {count}
540
695
  auto_fixes_applied: {count}
541
696
  auto_fixes_verified: {count that passed verification}
697
+ runner_executed: {true|false}
698
+ runner_exit_code: {N}
699
+ runner_status: {OK|BROKEN}
542
700
  commit_hash: "{hash}"
543
701
  ```
544
702
 
@@ -572,6 +730,8 @@ Before considering the classification complete, verify ALL of the following.
572
730
  - [ ] Application code was NOT modified (no changes in src/, app/, lib/, or any production code directory)
573
731
  - [ ] Auto-fixes were limited to TEST CODE ERROR at HIGH confidence only -- no other category or confidence level was auto-fixed
574
732
  - [ ] Each auto-fix was verified by re-running the specific failing test and recording PASS or FAIL
733
+ - [ ] No test was reported as passed/verified based on an MCP DOM probe; every "pass" traces to a real runner execution with stdout + exit code captured. Every DOM probe carries the `[DOM_PROBE — NOT_TEST_EXECUTION]` label.
734
+ - [ ] The report header has `runner_executed` / `runner_exit_code` / `runner_status`. If `runner_executed: false`, no individual tests were classified (ENV ISSUE + HARD STOP) and the orchestrator was signaled to HALT.
575
735
 
576
736
  If any check fails, fix the issue before finalizing the output. Do not deliver a classification report that fails its own quality gate.
577
737
  </quality_gate>
@@ -628,4 +788,3 @@ echo "=== BUG-DETECTIVE CHECKLIST END ==="
628
788
  - If any output shows a problem (REPORT_NOT_WRITTEN, NO_CLASSIFICATIONS_FOUND), fix it before returning.
629
789
  - If output shows expected "not found" results (e.g., NO_MCP_EVIDENCE when no E2E failures existed), that is fine — the point is you RAN the command instead of assuming the answer.
630
790
  - Do NOT return control to the parent agent until the block has been executed and you have read every line of output.
631
-
@@ -924,6 +924,56 @@ Test the highest-risk gaps first:
924
924
 
925
925
  </critical_rules>
926
926
 
927
+
928
+ <quality_gate>
929
+ Before considering codebase mapping complete, verify ALL of the following:
930
+
931
+ - [ ] Focus area received and acknowledged in the agent prompt (testability, risk, patterns, or existing-tests)
932
+ - [ ] Documents produced for the specified focus area:
933
+ - testability → TESTABILITY.md and TEST_SURFACE.md
934
+ - risk → RISK_MAP.md and CRITICAL_PATHS.md
935
+ - patterns → CODE_PATTERNS.md and API_CONTRACTS.md
936
+ - existing-tests → TEST_ASSESSMENT.md and COVERAGE_GAPS.md
937
+ - [ ] All file paths in produced docs are formatted with backticks (e.g., `src/services/payment.ts`)
938
+ - [ ] Every observation has a concrete file:line reference, not vague descriptions
939
+ - [ ] Mock boundaries documented (testability focus): "Mock X when testing Y"
940
+ - [ ] Risk levels assigned per item (risk focus): HIGH | MEDIUM | LOW with justification
941
+ - [ ] Code examples included with code patterns (patterns focus)
942
+ - [ ] Existing tests catalogued with their quality assessment (existing-tests focus)
943
+ - [ ] Output files written to ${output_dir}/codebase/
944
+
945
+ If any check fails, fix the issue before returning. Do not deliver codebase docs that fail their own quality gate.
946
+ </quality_gate>
947
+
948
+ <bash_checklist>
949
+ Run this checklist verbatim before returning control:
950
+
951
+ ```bash
952
+ echo "=== CODEBASE-MAPPER CHECKLIST START ==="
953
+ echo "1. Focus area received:"
954
+ echo "${FOCUS_AREA:-MISSING}"
955
+ echo "2. Output dir:"
956
+ ls -d "${output_dir:-.qa-output}/codebase/" 2>/dev/null || echo "DIR_MISSING"
957
+ echo "3. Documents produced for this focus:"
958
+ ls "${output_dir:-.qa-output}"/codebase/*.md 2>/dev/null | wc -l
959
+ echo "4. File paths backticked (per philosophy):"
960
+ grep -cE '`[a-z][^`]+\.(ts|js|py|go|java)`' "${output_dir:-.qa-output}"/codebase/*.md 2>/dev/null
961
+ echo "5. Mock boundaries (testability focus):"
962
+ [ "$FOCUS_AREA" = "testability" ] && grep -ic "mock" "${output_dir:-.qa-output}/codebase/TESTABILITY.md" 2>/dev/null || echo "n/a"
963
+ echo "6. Risk levels (risk focus):"
964
+ [ "$FOCUS_AREA" = "risk" ] && grep -cE "HIGH|MEDIUM|LOW" "${output_dir:-.qa-output}/codebase/RISK_MAP.md" 2>/dev/null || echo "n/a"
965
+ echo "7. Code examples (patterns focus):"
966
+ [ "$FOCUS_AREA" = "patterns" ] && grep -c '```' "${output_dir:-.qa-output}/codebase/CODE_PATTERNS.md" 2>/dev/null || echo "n/a"
967
+ echo "8. Existing tests catalogued (existing-tests focus):"
968
+ [ "$FOCUS_AREA" = "existing-tests" ] && grep -ic "test" "${output_dir:-.qa-output}/codebase/TEST_ASSESSMENT.md" 2>/dev/null || echo "n/a"
969
+ echo "=== CODEBASE-MAPPER CHECKLIST END ==="
970
+ ```
971
+
972
+ **Rules:**
973
+ - Run the block AS-IS. Do not modify it. Do not split it.
974
+ - If any output shows a problem, fix it before returning.
975
+ - Do NOT return control to the parent agent until the block has been executed.
976
+ </bash_checklist>
927
977
  <success_criteria>
928
978
  - [ ] Focus area parsed correctly
929
979
  - [ ] Codebase explored thoroughly for focus area (3+ representative files read in depth)
@@ -935,4 +985,3 @@ Test the highest-risk gaps first:
935
985
  - [ ] No secrets or forbidden file contents leaked
936
986
  - [ ] Confirmation returned (not document contents)
937
987
  </success_criteria>
938
-