# Test Design Standards (QA/PE)

**Purpose:** Standardized test design patterns, platform NFR baselines, and test techniques for functional manual testing.

**Used by:**
- `/tas-TestChecklist` — auto-populate Section 2.2 NFRs (Phase 1.3.4B)
- `/tas-functest` — design detailed test cases (test techniques, data patterns)
- `/tas-e2e` — scope E2E flows per platform

**How to use:**
- Agents/commands READ this file on demand (no auto-injection)
- Platform selection (web|app|all) determines which NFR baseline applies
- Test techniques & data patterns are reusable across features
- Risk scoring formula is mandatory for all risk assessments

**Related:** [Testing Requirements](testing.md) for developer unit/integration/E2E test standards

---

## Platform NFR Baselines

### web
**Definition:** PC + Tablet + Mobile view

| Category | Baseline | Test Approach | Tool |
|----------|----------|----------------|------|
| **Responsive** | 320px–1440px (Mobile / Tablet / Desktop) | Device viewport test | BrowserStack |
| **Browser** | Chrome, Firefox, Safari, Edge — latest 2 versions | Cross-browser matrix | BrowserStack |
| **Performance** | LCP < 2.5s, FCP < 1.8s, CLS < 0.1 | Lighthouse audit (3-run avg) | Lighthouse |
| **Accessibility** | WCAG 2.1 AA | Accessibility scan (Axe) + Manual | Axe |

### app
**Definition:** iOS + Android native

| Category | Baseline | Test Approach | Tool |
|----------|----------|----------------|------|
| **OS** | iOS 16+ (latest 2 major) / Android 10+ (API 29+) | Real device + emulator | XCTest, Espresso |
| **Device** | 5", 6", 6.7" screen sizes | Real device + emulator | Physical + Simulator |
| **Performance** | Cold start < 2s, screen transition < 300ms | Profiler + manual | Xcode, Android Profiler |
| **Network** | Offline graceful, 2G/3G, mid-request interrupt | Network throttling | Charles Proxy, Proxyman |
| **Permissions** | Graceful degradation on deny | Manual permission toggle | Device Settings |
| **Accessibility** | VoiceOver (iOS), TalkBack (Android) | Screen reader test | Native |

### all (Union + NFR Mapping)

Confirm resource scope before selecting `all` — it implies both web + app test effort.

| NFR | web | app | Tool | Owner |
|-----|-----|-----|------|-------|
| Responsive (320px–1440px) | ✅ | ❌ | BrowserStack | PE |
| Browser compat (latest 2) | ✅ | ❌ | BrowserStack | PE |
| OS version (iOS 16+/Android 10+) | ❌ | ✅ | XCTest, Espresso | PE |
| Device sizes (5"/6"/6.7") | ❌ | ✅ | Real device + Simulator | PE |
| Performance: LCP/FCP/CLS | ✅ | ❌ | Lighthouse | PE |
| Performance: Cold start/transition | ❌ | ✅ | Xcode/Android Profiler | PE |
| API response time | ✅ | ✅ | Postman | SE |
| Network: Offline/2G/3G | ✅ | ✅ | Charles Proxy, Proxyman | PE |
| Permissions: graceful deny | ❌ | ✅ | Device Settings | PE |
| Accessibility: WCAG 2.1 AA | ✅ | ❌ | Axe + Manual | PE |
| Accessibility: VoiceOver/TalkBack | ❌ | ✅ | Native screen reader | PE |
| Security (L1 checks) | ✅ | ✅ | Postman/Browser | DSE |

---

## Testing Priority Assignment (Tool Availability)

| Priority | Business Criteria | Tools Available | Owner |
|----------|------------------|-----------------|-------|
| **P0** | Main flow, high-risk edge | BrowserStack, Postman, Manual UI, DB Query, Dev Toolbar, API Logger | PE |
| **P1** | Alt flow variants | (same as P0) | PE |
| **P2** | Low-risk edge, optional NFRs | WCAG Axe, Load testing, Mobile profilers, Security scanning (project-dependent) | PE / DevOps |

**Out of Scope (SE/DevOps owned):** Unit tests, integration tests, 3rd party service integration, data sync testing, infrastructure monitoring, penetration testing.

---

## Test Techniques (Categories + Examples)

### TP Category → Test Approach Mapping (ISTQB) — CANONICAL ⭐

> **Single source of truth** for category→technique. `/tas-functest` and `tc-generation-strategy.md` reference this table; do not redefine the mapping elsewhere. For *how many TCs a technique expands to* and dedup, see [tc-generation-strategy.md § Layer 3](tc-generation-strategy.md).

| TP Category | Primary Technique | Secondary | Examples | Artifact Sections (Func-Test.md) |
|---|---|---|---|---|
| **GUI & UX** | UI Manual | Visual Inspection | Screen layout, button placement, form rendering, responsive layout | §4.1–4.5 (scripted TCs) + §4.E (exploratory findings) |
| **Validation** | Boundary Value Analysis + Equivalence Partitioning | Negative Testing | Field format, length, required/optional, constraints | §4.1–4.5 |
| **Business Logic** | Decision Table + State Transition | Use Case Flow | Order state transitions, workflow progression, conditional logic | §4.1–4.5 |
| **Exception** | Negative Testing + Error Handling | Equivalence Partitioning | Invalid input, error messages, recovery flows, boundary violations | §4.1–4.5 |
| **Security** | Input Sanitization + Auth Bypass | PII Handling, HTTPS/TLS | XSS, SQL injection, unauthorized access, data leakage | §4.1–4.5 |
| **Integration** | API Mock + Webhook Verification | Use Case Flow | Third-party API calls, webhook handling, system integration | §4.1–4.5 |

**GUI & UX:** Scripted TCs (§4.1–4.5, AC-mapped, deterministic) + P2 UX/UI items tested manually if needed (no scripted TC required).

### Critical UI/UX Patterns → Scripted TCs (When to Create vs. Skip)

**Purpose:** Identify common high-impact UI/UX issues requiring executable TCs (not checklist). Used by `/tas-functest` Step 4 to route critical NFR → §4 scripted TCs, rest → SKIP (no scripted TC).

| NFR Category | Critical Pattern | When to Script as TC (§4) | When to SKIP (no TC) |
|---|---|---|---|
| **Responsive** | Layout break at critical breakpoint | P0 flows + breakpoint affects form submission or core action | All other breakpoints |
| **Accessibility** | Keyboard navigation blocks core flow | P0 flows requiring keyboard (e.g., checkout, form submit) | General keyboard testing |
| **Form** | Validation message not visible | Error message on P0 flow (blocking submission) | Cosmetic validation feedback |
| **Browser** | Core flow fails on major browser | P0 happy path on Chrome/Firefox/Safari/Edge | Minor visual differences |
| **Visual** | Button/CTA not clickable (overlap/z-index) | Any CTA on P0 flow | Alignment issues (non-blocking) |
| **Accessibility** | Screen reader announces wrong state | P0 flow state changes (success/error) | General screen reader audit |

#### Cross-Cutting TP Test Approach Rules (Feature-Wide TPs)

**Scope:** TestChecklist §2.1.1 (Cross-Cutting Tests) — TPs that cover multiple ACs.

| TP Type | Priority | Category | Test Approach | Rationale |
|---------|----------|----------|---------------|-----------|
| cross_cutting | P0, P1 | GUI, VAL, BL, EXC, SEC | UI Manual | UI-observable functional scope (see verification-layers.md §4) |
| cross_cutting | P0, P1 | PERF, INT (API-only) | SKIP — Route to `/tas-apitest-plan` | API-observable only (see verification-layers.md §4) |
| cross_cutting | P2 | GUI, UX | Optional → §5 Inherited Risk | UX coverage is discretionary (low priority) |

---

### Test Techniques Detail

| Category | Technique | Example |
|----------|-----------|---------|
| Functional / EP | Equivalence Partitioning | Email: [valid], [empty], [invalid format] |
| Functional / BVA | Boundary Value Analysis | Age: [1,120,121]; Password length: [7,8,9] |
| Functional / DT | Decision Table | Payment: [Method × Amount] = 4 combos |
| Functional / ST | State Transition | Order: Pending→Paid→Shipped→Delivered; Form: Fill→Navigate→Return→state unchanged |
| Functional / UCF | Use Case Flow | Login: [Main], [Forgot PWD], [Invalid] |
| Security / XSS | Input Sanitization | `<script>alert('xss')</script>@example.com` |
| Security / SQLi | SQL Injection | `' OR 1=1 --` in password field |
| Security / Auth | Auth Bypass | Direct URL access without session |
| Security / PII | PII Handling | Verify PII not in logs / network trace |
| Security / TLS | HTTPS/TLS | Network sniffer test for HTTPS only |
| Performance | Lighthouse Audit | LCP, FCP, CLS, TTI — Lighthouse (3-run avg) |
| Performance | Page Load Time | Time to interactive — Browser DevTools |
| Performance | API Response Time | Endpoint latency — Postman, API Monitor |
| Performance | DB Query Time | Query performance — Slow query log |
| Accessibility | Axe Scan | WCAG 2.1 A/AA — Axe DevTools |
| Accessibility | Keyboard Navigation | Tab order, focus — Manual |
| Accessibility | Screen Reader | VoiceOver, TalkBack, NVDA — Native |
| Accessibility | Color Contrast | WCAG AA (4.5:1 text) — Contrast Checker |
| Accessibility | ARIA Labels | Semantic HTML — Manual inspection |

---

## Test Data Patterns

### By Field Type

| Field Type | Valid Examples | Invalid Examples | Security Test | Technique |
|-----------|-----------------|------------------|---------------|-----------|
| **Email** | test@example.com, user.name+tag@domain.co.uk | notanemail, test@, @domain, >255 chars (RFC 5322) | `<script>@test.com` | Boundary, Negative |
| **Password** | Pass123, MyP@ssw0rd (8+ chars, 1 upper, 1 digit) | pass, Pass1 (too short) | `Pass123<script>` | Boundary, Negative |
| **DOB** | 1990-01-01, 2000-12-31 | future date, before 1900, invalid format | — | Boundary, State, Decision Table |
| **Amount (Numeric)** | 0.01, 10.50, 999.99 | -1, 1000, "abc" | `<img src=x>` | Boundary, Negative |
| **Enum (Dropdown)** | Valid option from list | Invalid/blank option | Injection attempt | Equivalence |
| **Phone** | +1-555-0123, (555) 012-3456 | 123, +1-abc, spaces only | Injection | Boundary |
| **Date Range** | Within allowed range | Before/after range | — | Boundary |

### ID Naming Convention

> **Canonical SSoT:** [test-id-convention.md](../../rules/qa/test-id-convention.md) — all ID formats (Flow, Test Point, TC, API TC, Test Data, Risk). Do not redefine here.

---

## Risk Scoring Formula

**Score = (Impact × 3) + (Probability × 2) + (Complexity × 1) + (DataCriticality × 2)**

**Scales:** Each dimension Low=1, Medium=2, High=3 (no Critical tier in scoring).

### Risk Levels

| Score | Level | Action |
|-------|-------|--------|
| 26–36 | **CRITICAL** | Block immediately; must have mitigation before release |
| 16–25 | **HIGH** | Prioritize testing; include in Stage 2 TC |
| 9–15 | **MEDIUM** | Test/monitor; include if time permits |
| 4–8 | **LOW** | Test if time permits |

### Risk Categories (RC)

| Code | Category | Examples |
|------|----------|----------|
| **RC-AUTH** | Authentication | Session hijacking, unauthorized access, token expiry |
| **RC-DATA** | Data | Invalid input, loss, corruption, constraint violation |
| **RC-INT** | Integration | API failure, webhook timeout, third-party unavailable |
| **RC-PERF** | Performance | Slow load, timeout, resource limits, concurrent ops |
| **RC-SEC** | Security | XSS, SQL injection, PII leakage, HTTPS bypass |
| **RC-BR** | Business Rule | Logic failure, edge case, constraint violation |
| **RC-UX** | User Experience | Responsive broken, accessibility, clarity |
| **RC-INFRA** | Infrastructure | Deployment, scalability, failover, reliability |

### Detection Tag → RC Code ⭐ (Single Source of Truth)

> **Canonical SSoT** for converting detection tags (used internally during analysis) to RC codes (written to §5 Risk Registry). The `RC` column in §5 always carries the RC code — **never** the bracketed detection tag. Risk ID format: `R-{NNN}` (Feature-unique, sequential) per [test-id-convention.md §5](../../rules/qa/test-id-convention.md#5-supporting-ids).

| Detection Tag | RC Code | Risk Registry Category | Owner | Route To |
|---|---|---|---|---|
| `[BR-AMBIGUITY]` | RC-BR | Business Rule ambiguity | PE | Clarify with stakeholder |
| `[TECH-COVERAGE]` | RC-INT / RC-SEC / RC-PERF | Technical coverage gap (tooling-required) | SE / DSE | `/tas-apitest-plan` or `/tas-security` |
| `[SHARED-COMPONENT]` | RC-DATA / RC-AUTH | Shared component regression risk | PE / SE | Regression scope in §1.4 |
| `[NFR-NON-PE]` | RC-PERF / RC-INFRA | NFR outside QA scope (DevOps/Infra owned) | DevOps | NFR pipeline |
| `[UX]` | RC-UX | User experience / accessibility gap | PE | `/tas-functest` |
| `[User-Blocking]` | RC-UX | Blocking UX flow (destructive action unguarded) | PE | Verification TP |

**Risk entry format (§5 Risk Registry):**
```
# | Risk description | Level | RC (code, not tag) | Likelihood | Root Cause | Mitigation | Action | Owner | Linked TPs | Status
1 | Photo upload req unclear — REQUIRED or OPTIONAL? | 🟡 MEDIUM | RC-BR | M | No AC spec | REQ-CLARIFY | Clarify with PE: can form proceed without photo? | PE | — | ⏳ Active
```

**Risk ID:** `R-{NNN}` (sequential per Feature, from §5 row number — do NOT use detection tags as IDs).

---

## Requirement Gap Detection Patterns

**Used by:** `/tas-TestChecklist` Phase 1.3.3.1 (Layer 1) — detection only. A match here does **not** go straight to the human: every detected gap is routed through [§ Attempt-Answer Procedure](#attempt-answer-procedure-layer-2--layer-3) (Layer 2 against Feature-Technical, then Layer 3 against the Project Cache) before it reaches Phase 1.3.3.4's presentation step. This table's content and question wording are unchanged — only when the human sees the question has changed.

**14 Common Gaps:**

| # | Pattern | Trigger Keywords | Question Template | If YES → | If NO/UNCLEAR → |
|---|---------|-----------------|-------------------|----------|-----------------|
| 1 | **State Persistence** | step, wizard, navigate, back | "Can user navigate BACK? State preserved?" | TP: Back nav + verify state | Risk [BR-AMBIGUITY] |
| 2 | **Concurrent Edits** | create, update, edit, share | "Can 2 users edit same record? Conflict handling?" | TP: Conflict handling | Risk [BR-AMBIGUITY] |
| 3 | **Data Loss** | save, submit, upload, close tab | "What if user closes tab during save? Auto-save?" | TP: Warning/auto-save | Risk [BR-AMBIGUITY] |
| 4 | **Empty State** | list, search, filter, results | "What if search returns 0? Empty message shown?" | TP: Empty state display | Skip |
| 4B | **Min Item Count** ⭐ | multiple, upload, file, remove, add | "Can user proceed with 0 items? Blocking validation?" | TP: Blocking validation | Risk [BR-AMBIGUITY] |
| 5 | **Boundary Values** | field, input, min/max, limit, size | "Are min/max documented? Enforced (warn/block/trim)?" | Skip (check AC) | Risk [BR-AMBIGUITY] |
| 6 | **Error Recovery** | fail, error, invalid, retry | "Can user retry after error? Data preserved?" | TP: Recovery + data preserved | [UX] → RC-UX |
| 7 | **API Failure** | api, third-party, webhook, external | "What if API times out? Retry + error msg?" | TP: Retry + error msg | [TECH-COVERAGE] → RC-INT |
| 7A | **Retry Logic** ⭐ | retry, timeout, transient | "Retry strategy? Max attempts? Backoff policy?" | TP: Retry scenario | [TECH-COVERAGE] → RC-INT + RC-PERF |
| 7B | **Webhook Timeout** ⭐ | webhook, callback, async | "What if webhook timeout? Retry? Fallback?" | TP: Timeout + fallback | [TECH-COVERAGE] → RC-INT |
| 7C | **Rate Limit** ⭐ | api, third-party, rate, quota | "What if rate limit exceeded? Queue? Error msg?" | TP: Rate limit handling | [TECH-COVERAGE] → RC-PERF |
| 7E | **Undocumented System Step** ⭐ | a step named in Feature-Technical Data Flow or its Context Diagram external systems has no matching AC/flow (same action, different doc) | "Feature-Technical describes {system step} — is this user/API-observable (needs a TP) or infra-only?" | Observable → TP: {step}'s FE/API-visible outcome. Infra-only → skip TP | [TECH-COVERAGE] → RC-INT (infra-only, no ASK needed if clearly backend-internal) |
| 8 | **Session Expiry** | login, session, auth, logout | "What if session expires? Redirect to login?" | TP: Expiry handling | [BR-AMBIGUITY] → RC-AUTH |
| 9 | **Progress Feedback** | upload, process, generate, import | "Is progress shown? (spinner/progress bar)" | TP: Progress indicator | [UX] → RC-UX |
| 10 | **Confirmation** | delete, cancel, submit, confirm | "Is action confirmed? Destructive ops guarded?" | Verify TP exists | [UX] → RC-UX |

| 11 | **WCAG Baseline (web)** ⭐ | platform=web AND no WCAG/accessibility NFR in PRD NFR section | "PRD has no accessibility NFR. Include P2 WCAG 2.1 AA scan (Axe + keyboard nav)?" | Add §2.2 NFR row (P2, source=platform baseline) | Exclude §2.2 Accessibility row entirely |
| 15 | **Shared Component (Stack Narrowing)** ⭐ | scope_narrowed=TRUE AND AC mentions keyword from deferred_stack | "AC-{N} mentions '{concept}' from {deferred_stack}. Test {observable_outcome} in {retained_stack}?" | TP: {observable_outcome} | Risk [SHARED-COMPONENT] |

> **#4B** catches min-item-count gaps, e.g. AC says "multiple files" but never states "must have ≥1 to proceed". **#7A/7B/7C** expand integration failure modes beyond generic API timeout. **#7E** catches the reverse direction — a system step Feature-Technical already describes but no AC covers (system→user, not user→system); one AC legitimately covers several system steps sharing the same action (e.g. AC "submit consultation" covers both "validate" and "persist" steps) — only flag a step whose action matches **no** AC. **#11** prevents WCAG auto-injection without business justification — always explicit opt-in. **#15** captures shared components when PE narrows scope (e.g., web-only defers service, but UI outcomes from service behaviors still observable in web).

---

## Cross-Document Consistency Patterns

The 14 patterns above detect gaps **within one document**. These classes detect gaps **across documents** (Feature ↔ Technical ↔ PRD ↔ SAD) — run them *before* scope is fixed.

**Trigger (lean — bounds the scan):** cross-check entities in ≥2 sources OR single-source owner-defined requirements (NFR/BR/ADR). Two failure axes: **(A) does what's shared MATCH?** (C1–C3) · **(B) is anything DROPPED or RENAMED?** (C4–C6, C4B).

**Layer routing (per-instance, not per-pattern):** C1/C2/C3/C5/C6 each fire from whichever doc pair actually conflicts for that specific instance — Feature-vs-Feature-Technical → attempted at Phase 1.3.3.2 (Layer 2); anything touching PRD/SAD content (via the Project Cache) → attempted at Phase 1.3.3.3 (Layer 3). C4/C4B/C7 are **Layer-3-only** — their definition ("owner defines it, Feature is silent") has no Feature-vs-Technical variant, since the owner is always PRD/SAD.

| # | Pattern (cross-doc) | Detection signal | Tag | Example (F-002) |
|---|---|---|---|---|
| C1 | **Value conflict** — same field, different numbers | same entity/field in ≥2 sources, quantified values differ | [DOC-CONFLICT] | allergen 4 (Feature) vs 6 (PRD FR-005) |
| C2 | **Orphan value** — number with no owning source | quantified value in 1 source, absent/mismatched in its owner doc | [ORPHAN-VALUE] | Draft TTL 60min (SAD says 48h/7d) |
| C3 | **Dangling ref** — points to non-existent item | `BR-\d+`/`FR-\d+`/`§\d` ref does not resolve in target doc | [DANGLING-REF] | Feature refs FR-005 but PRD has none |
| C4 | **Uncovered requirement** — owner defines, consumer silent | required item in PRD/SAD has no matching AC in Feature | [UNCOVERED-REQ] | PRD allergen-severity FR, AC silent |
| C4B | **Uncovered NFR** ⭐ | NFR in PRD has no keyword match in Feature ACs | [UNCOVERED-NFR] | PRD NFR-001 (load <2s) → AC silent |
| C5 | **Terminology drift** — same concept, different name | one entity/role named differently across sources | [TERM-DRIFT] | "Consultant" (Feature) vs "Practitioner" (SAD) |
| C6 | **Lifecycle/state mismatch** | lifecycle keyword (`draft`/`resume`/`ttl`/`expiry`/`retention`/`token`) → SAD lifecycle section mandatory read; states must match | [STATE-MISMATCH] | Draft/resume not matching SAD §10 |
| C7 | **Known external, undeclared boundary** ⭐ | Feature/Tech names an external system or handoff step (e.g. "Payment (Step 5)", "owned by X Feature") whose name matches a `known_externals[]` entry, AND Feature-Technical's `## DO NOT CHANGE` (or equivalent contract-citing section) does **not** cite the matching `integration_contracts[]` ID | [TECH-COVERAGE] | Feature-004 names "Payment (Step 5)" → matches `known_externals[]` "Mollie" → `integration_contracts[]` has `IC-05` → Feature-004-Technical never cites IC-05 → boundary-contract risk missed |

**C7 detection (deterministic — no ASK):** for each `known_externals[]` name, string-match it against `feature_digest` (AC/User Flow text) and `tech_digest` (Modules/Context Diagram/Data Flow). A match found + Feature-Technical's `## DO NOT CHANGE` does not cite the corresponding `integration_contracts[]` ID → auto-emit the §5 risk (RC-INT, no confirm/reject — this is a fact, not a judgment call, same as a Confirmed-verdict `bc_applicable`). Runs at Phase 1.3.3.3 using digests already in memory — no new read.

**Output rule:** emit each flagged item to §5 Risk Registry — **do NOT pick a winner.** All cross-doc tags → RC-BR (Owner=PE) unless the value is `[Security]`/`[Data-Critical]` (→ HIGH) or C7 (→ RC-INT, per its own row). Affected values are **blocked from scope** (Phase 1.1) until resolved.

---

## 💬 Question Generation Algorithm (Logic Validation Check)

For each AC in Feature.md:

1. Extract AC text
2. Check keywords against Pattern Table (14 patterns)
3. If pattern matched:
   - **RUN LOGIC VALIDATION CHECK:**
     - Extract key claims from AC: "required", "default", "confirm", "delete", "auto-action", etc.
     - Check for contradictions (5 simple rules):
       - **Rule 1:** required=TRUE + default=not-empty for same field → "Is field truly required if default exists?"
       - **Rule 2:** manual-confirm + auto-action for same operation → "Manual confirm vs auto-action contradicts"
       - **Rule 3:** field=optional + has-delete-button → "Why delete optional field? UX confusion?"
       - **Rule 4:** constraint-exists (min/max) + enforcement undefined → "How are limits enforced? Warn/block/trim?"
       - **Rule 5:** multi-step-flow + no-back-nav-mentioned → "Can user go back? State preserved?"
     - **If contradiction found:** Ask 1 consolidated question addressing both claims. _Example (Rule 1 + Rule 4): "Consultant type — required, or optional with default? Also: email validation rules (format + max length)?"_
     - **Else:** Ask standard pattern question
   - **RUN ENUM INTERACTION CHECK (Rule 6):**
     - If AC lists a set of options (checkbox/radio) AND includes a catch-all option (e.g. "no clear pattern", "none", "other") → verify: is mutual exclusivity defined?
     - If NO → detect [BR-AMBIGUITY]: "Can user select catch-all option + specific option simultaneously? Is catch-all standalone-only?"
     - Do NOT generate TC for catch-all interaction until clarified — any expected result is inferred.
   - **RUN SOURCE VERIFICATION CHECK (Rule 7):**
     - Every TP/risk referencing a BR/NFR/ADR must quote exact text from that source doc.
     - Verify match is **semantic** (content matches) not just **lexical** (keyword appears).
     - If no exact semantic match → source = ADR (if applicable) OR "Security baseline (test-design.md)" OR "Platform NFR baseline" — never fabricate a BR ref.
     - Tag fabricated/unverified sources as `[SOURCE-UNVERIFIED]` → treat as [BR-AMBIGUITY] LOW.

4. Mark AC + gap category
5. Deduplicate questions (multiple ACs may trigger same gap)
6. Sort by priority (Security > Data-Critical > UX)

**Output:** Ordered question list → every question on this list is a candidate for [§ Attempt-Answer Procedure](#attempt-answer-procedure-layer-2--layer-3) before it reaches the human.

---

## Attempt-Answer Procedure (Layer 2 / Layer 3)

**Used by:** `/tas-TestChecklist` Phase 1.3.3.2 (Layer 2) and 1.3.3.3 (Layer 3) — for every gap the Question Generation Algorithm produced, try to resolve it from cheaper sources before asking the human. Detection (which patterns fired) is unchanged; only *when* the human sees the question changes.

**Mechanism — deterministic, reuses the existing Source Verification Check (Rule 7) as the acceptance gate. No new judgment primitive is introduced:**

```
ATTEMPT-ANSWER(gap, candidate_source):
  1. Search candidate_source's already-extracted sections relevant to the gap's
     pattern — never a full-text scan:
       Layer 2 (tech_digest): API Spec, Error Codes, Modules, Context Diagram,
                               DO NOT CHANGE
       Layer 3 (Project Cache): prd_nfr_digest, project_roles[], prd_usecase_digest,
                                 sad_digest, sad_flow_digest, known_externals[],
                                 integration_contracts[], design_spec_digest,
                                 tech_stack_digest
  2. No candidate passage found → unresolved, fall through to the next layer
     (Layer 2 unresolved → retry as Layer 3; Layer 3 unresolved → the gap
     reaches the human as an open question, exactly as today).
  3. Candidate found → gate it through Rule 7 (semantic match required — the
     passage must resolve the SAME field/action/entity the gap's question is
     about, not just share a keyword):
       Semantic match  → resolved: {layer, source_excerpt, derived_answer}
       Lexical-only    → tag [SOURCE-UNVERIFIED], treat as unresolved, fall through
```

**Presentation (Phase 1.3.3.4):** every gap Layer 2 or Layer 3 resolved is shown to the human — question + derived answer — for confirmation, not accepted silently:

```
[AUTO-RESOLVED — Layer {2|3}] {pattern / C-code / procedure name}
Q: {question}
Resolved by: {tech_digest section | project-cache digest name}
Source excerpt: "{exact quoted passage}"
Derived answer: {answer}
→ Confirm? [Y / N / EDIT]
```

- **Y** → routes into [§ Answer Mapping](#-answer-mapping-gap--test-points--risks)'s existing "✅ clear answer" row; tag the resulting TP's Source cell `[AUTO-RESOLVED-L2]` / `[AUTO-RESOLVED-L3]` (same bracket-tag convention `[INFERRED]` already uses — no new frontmatter field).
- **N** (rejected) → falls through to Answer Mapping's existing "❌ cannot answer" row — same `[BR-AMBIGUITY]` MEDIUM outcome. Not a new outcome type; a rejected auto-resolution is never silently dropped.
- **EDIT** → routes into Answer Mapping's existing "✅ clear answer" row as a normal human-sourced answer — no `[AUTO-RESOLVED]` tag, since the human is now the source of truth.

Gaps that never resolve at either layer reach the human exactly as today: an open question, answered through the unchanged Answer Mapping table (clear answer / cannot-answer / skip / inferred-without-source).

### Backward-Compat Applicability Detection (`bc_applicable`)

**Used by:** `/tas-TestChecklist` Phase 1.3.3.3 (Layer 3) — decide whether this Feature touches a contract/behavior existing consumers depend on. **Principle — detect, don't re-read:** all inputs are already in memory (`sad_digest`, `tech_digest`) — the SE already declared these changes in the SAD Impact Matrix / API Spec during `/tas-plan`.

| Verdict | Signal (already in memory) | Action |
|---|---|---|
| **Confirmed** (`bc_applicable=true`) | `sad_digest` SAD Impact Matrix (API Contract row) names a breaking/versioning change (major-version bump, removed/renamed/retyped field, deprecated path) | `bc_applicable=true`; **no ASK** (SE-declared) — write §5 risk directly, skip Attempt-Answer confirm/reject |
| **Confirmed** (`bc_applicable=true`) | `tech_digest` — an API Spec endpoint also appears in a `#### Modify` File-Changes table (existing endpoint's contract is being touched) | `bc_applicable=true`; **no ASK** |
| **Suspect** (→ one ASK, via the standard confirm/reject presentation above) | `sad_digest` shows a schema-evolution signal on an existing table/module without a clear breaking/additive label | ASK: "This Feature extends an existing contract/schema. Do existing consumers depend on the prior behavior — test backward-compat?" |
| **Net-new** (`bc_applicable=false`) | All API Spec endpoints are `#### Create` only, all tables/modules are new | `bc_applicable=false`; no ASK |

**§5 row (when `bc_applicable=true`):** Risk = `Backward-compat regression — existing consumers of {API names} may break`; RC = `RC-INT`; Root Cause names the concrete API(s)/endpoint(s) + change type. `/tas-apitest-plan §3` designs the TCs from this row — no re-detection downstream.

### Role Matrix Applicability Detection (`role_matrix_applicable`)

**Used by:** `/tas-TestChecklist` Phase 1.3.3.3 (Layer 3) — decide whether this Feature exercises >1 role / any authenticated access, so a Test Account & Role Matrix is in scope.

| Verdict | Signal (all in memory) | Action |
|---|---|---|
| **Applicable** (`true`) | Feature `## User Flow` names a non-public actor, OR a `tech_digest` API-Spec endpoint carries an auth-scheme/permission handler, OR the flow involves ≥2 non-public actors | `role_matrix_applicable=true`; `roles[]` = the named actors; **no ASK** |
| **Suspect** (→ one ASK) | Exactly one public actor named, but `project_roles[]` (Layer 3) shows the project has an auth/RBAC model | ASK: "This Feature operates under one public role — must the test distinguish accounts/roles?" |
| **Not applicable** (`false`) | No signal fired, no contradiction from `project_roles[]` | `role_matrix_applicable=false`; no ASK |

**Cross-check:** an actor named in the Feature but absent from `project_roles[]` (Layer 3) → `[DOC-CONFLICT]` → §5 RC-BR, Owner=PE. When `role_matrix_applicable=true` with a genuine auth risk → add one §5 RC-AUTH row (standard format); `roles[]` names only what the Feature actually names — never a generic "Admin"/"Standard User".

### Design-Spec / Tech-Stack Screening

**Used by:** `/tas-TestChecklist` Phase 1.3.3.3 (Layer 3) — for each UX or tech concern surfaced by `design_spec_digest` / `tech_stack_digest` (Project Cache) that this Feature's ACs don't already cover:

- **In-scope, PE-testable** (observable via dev tooling — e.g. a documented responsive breakpoint, a component pattern the Feature reuses) → 1 TP input.
- **Not coverable by scripted TC** → §5 Risk (Owner=PE), note: "covers via FuncTest §4.E exploratory."

No ASK needed when the concern is a straightforward TP or a straightforward risk — only genuinely ambiguous cases (does this concern apply to this Feature at all) go through the standard confirm/reject presentation.

---

## 🎯 Answer Mapping: Gap → Test Points + Risks

**For each gap detected, ask 1 clarifying question. Handle answers per table below:**

| User Answer | Outcome | Action | Risk Flag |
|---|---|---|---|
| ✅ **Provides clear answer** | Question resolved | Generate 1-2 TPs from answer | None |
| ❌ **Cannot answer** (says "unclear") | Ambiguity found | Do NOT generate TP | Flag [BR-AMBIGUITY] MEDIUM, Owner=PE |
| ⏭️ **Skip** (no input) | Deferred decision | Do NOT generate TP | Flag [BR-AMBIGUITY] MEDIUM, Owner=PE, Status=Pending |
| ⚠️ **Answer w/o source** (AI inferred a value) | Unverified | Generate TP BUT tag the value `[INFERRED]` | Flag [BR-AMBIGUITY] LOW, Owner=PE |

**Risk entry format for unanswered gaps** (write to §5 Risk Registry):
```
Risk ID (R-NNN):  R-001                          ← sequential, per Feature
Risk:             {gap pattern}: {AC excerpt} — requirement unclear
Level:            🟡 MEDIUM (→ 🔴 HIGH if tagged [Security] or [Data-Critical])
RC:               RC-BR                          ← RC code, not detection tag
Likelihood:       M
Root Cause:       No AC specification
Mitigation:       REQ-CLARIFY
Action:           Clarify with stakeholder: {question asked}
Owner:            PE
Linked TPs:       —
Status:           ⏳ Active (if cannot-answer) / ⏳ Active (if skipped — deferred)
```

**Example: AC-2 Photo Upload**
```
DETECTED GAP (Pattern #5 — Field Requirements):
Q: "Is photo upload field REQUIRED or OPTIONAL?"

User Answer: "Not sure, need to check with designer"
→ Outcome: Cannot answer → detection tag [BR-AMBIGUITY]
→ RC Code: RC-BR (per Detection Tag → RC Code table above)
→ Risk Entry (§5): R-001 | Photo upload req unclear | MEDIUM | RC-BR | M | No AC spec | REQ-CLARIFY | Clarify with PE | PE | — | ⏳ Active

User Answer: "REQUIRED — must have at least 1 photo"
→ Outcome: Question resolved → generate TPs:
   {FEAT}-BL-001: "Attempt submit without photo → Show blocking error"
   {FEAT}-BL-002: "Submit with ≥1 photo → Success"
```

> Decision logic is defined once in § Question Generation Algorithm (step 3) above — answer → TP; cannot-answer/skip → detection tag [BR-AMBIGUITY] → RC code RC-BR → Risk entry R-{NNN} in §5, owner PE.

---

## Test Approach Values (Functional Flows)

| Approach | When to Use | Example | Owner |
|----------|------------|---------|-------|
| **UI Manual** | New/changed UX, validation, user interactions | Login form fill, button click, error display | PE |
| **Data Verification** | Business logic, state changes, DB operations | Verify session created, user data saved | PE |
| **Configuration Check** | Feature flags, environment-specific settings | Feature flag on/off, admin permissions | PE |
| **Security Probe** | XSS, auth bypass, PII handling | Password field injection, HTTPS check | DSE |
| **Visual Regression** | Responsive, component alignment, CSS changes | Mobile layout, button alignment, color | PE |
| **API Integration** | 3rd party APIs, webhooks, external systems | Payment gateway callback, OAuth flow | SE |
| **Performance** | Load time, responsiveness, resource usage | LCP < 2.5s, cold start < 2s | PE |

---

## QA vs. DevOps Scope

### ✅ QA Scope (INCLUDE in TestChecklist)

| NFR Category | Owner | Why QA Tests |
|-------------|-------|-------------|
| **Usability** | PE | Accessibility, keyboard navigation, screen reader |
| **Compatibility** | PE | Cross-browser matrix, device viewport, responsive |
| **Performance** | PE | LCP/FCP targets, page load, cold start (user-facing) |
| **Accessibility** | PE | WCAG 2.1 AA compliance, ARIA labels, color contrast |

### ❌ DevOps Scope (EXCLUDE from TestChecklist)

| NFR Category | Owner | Why Not QA |
|-------------|-------|-------------|
| **Scalability** | DevOps | Load testing, concurrent users (infrastructure) |
| **Reliability/Uptime** | DevOps | SLA monitoring, failover (deployment) |
| **Disaster Recovery** | Infra | RTO/RPO, backup/restore (infrastructure) |
| **Penetration Testing** | Security | Annual security audit (specialized team) |

---

## Coverage Metrics Clarification

| Metric | Owner | Definition | Target |
|--------|-------|-----------|--------|
| **Code Coverage** | Developers | % of code lines executed by unit/integration tests | ≥80% (see [Testing Requirements](testing.md)) |
| **Flow Coverage** | QA (PE) | % of business flows with ≥1 test point | ≥90% (Stage 1 gate) |

---

## PRD-to-Feature Mapping ⭐

**Rule:** Feature ACs must cover ALL steps in the mapped PRD Use Case.

**How:**
1. Identify PRD UC for this Feature
2. Extract journey steps from PRD UC
3. For each step: verify Feature has corresponding AC
4. If step missing AC → ask user to add AC or document why deferred

**Example (Feature-003):**
```
PRD UC2: Submit Eczema Consultation (steps: click card → upload skin → upload product → questionnaire → payment)
Feature-003 ACs: AC-0 (click card) → AC-1 (skin) → AC-3 (product) → AC-5 (Q) → AC-11 (payment)
Match? ✅ All steps covered
```

**If mismatch:**
```
PRD UC includes Step 1 (Landing Page) but Feature AC-0 missing
→ Ask: "Add AC-0 or defer to another Feature?" [Y/N/DEFER]
```

**Why:** Prevents Features from accidentally excluding Must-Haves. Ensures test coverage = genuinely complete user journey.

**Entry/Exit sub-rule:** apply the same step-check to AC-1's `Given` (entry) and the last AC's `Then` (exit) against the PRD UC's first/last step. Exit stops short → ASK: "Feature ends at {feature_exit}; PRD continues to {prd_exit} — deliberate handoff to another Feature, or incomplete?" Handoff confirmed → record boundary, no TP for the far side (e.g. Feature-004 ends at AC-11 "advances to Payment" — Payment itself is a separate Feature's scope). Incomplete → same as a missing middle step.

---

## Shared Component Detection (from PRD)

**Pattern:** When a business flow appears in 2+ use cases in PRD → shared component candidate.

**How to identify:**
1. Read PRD "Key Use Cases" section
2. Extract flow steps from each use case
3. Find repeated action keywords (e.g., "validates email", "creates session")
4. If action appears in 2+ use cases → shared component

**Example:**
```
PRD Key Use Cases:

UC1 (Login):     "User enters email → System validates email → ..."
UC2 (Signup):    "User enters email → System validates email → ..."
UC3 (Password Reset): "User enters email → System validates email → ..."

→ Action "validates email" found in 3 use cases
→ Shared component: Email Validator (HIGH risk, auth-critical)
```

---

## TestChecklist: Approval Gate Requirements ⭐

> **Canonical SSoT** for gate definitions, thresholds, and PASS/FAIL conditions. Used by:
> - `/tas-TestChecklist` Output Validation — evaluate gates before writing file
> - `TestChecklist.md §4` — display live gate results (reads thresholds from here)
> - `/tas-functest` Step 1 — prerequisite check before TC generation

**Layer split:**
- **Rules (this file):** gate definitions, thresholds, pass/fail conditions
- **Command (`/tas-TestChecklist`):** executes gates, populates `gate_result` + `gates_auto_passed` + `gates_pending_human` frontmatter fields
- **Template (`TestChecklist.md §4`):** displays computed results — does NOT redefine gate logic

Each TestChecklist must pass 4 gates before proceeding to `/tas-functest`:

| Gate | ID | Type | Threshold | Pass Condition | Fail Action |
|------|----|------|-----------|----------------|-------------|
| **1. Flow Coverage** | `gate1_coverage` | Auto | ≥90% | `coverage_percentage ≥ 90` AND Main≥50%, Alt≥30%, Edge≥10%; every AC → ≥1 flow | REVISION |
| **2. Category Completeness** | `gate2_category` | Auto | ≥75% | ≥4 of 6 categories (GUI/Validation/BL/Security/Exception/Integration) represented; all P0 rows complete | REVISION |
| **3. Risk Mitigation** | `gate3_risk` | Human | All CRITICAL/HIGH mitigated | Each CRITICAL/HIGH risk has: mitigation strategy + owner + linked TPs | BLOCK |
| **4. Dependencies** | `gate4_dependencies` | Human | No orphan/circular deps | `Depends On` populated; §1.3 ↔ §2.1 aligned; no circular deps; no missing dep targets | REVISION |

**`gate_result` field (frontmatter):** Set to `"PASS"` only when Gates 1–2 auto-pass AND Gates 3–4 are human-approved. Otherwise `"FAIL"` or `""` (pending). Command populates this; template displays it — never edit manually.

**`gates_auto_passed` array:** IDs of auto-passed gates (e.g. `["gate1_coverage", "gate2_category"]`). Set by command during Output Validation.

**`gates_pending_human` array:** IDs of gates requiring human review (e.g. `["gate3_risk", "gate4_dependencies"]`). Cleared to `[]` only when human approver signs off via `approval:` block.

> **Mechanical dependency validation** (cycle detection, missing-dep, self-dep, topological order) — canonical rules in [tc-generation-strategy.md § Validation Rules](tc-generation-strategy.md#validation-rules--canonical-). Gate 4 applies these rules at **TP level** (§2.1 `Depends On` column, TestChecklist scope). `/tas-functest` re-applies them at **TC level** (Step 8 Check 3, FuncTest scope). Do not duplicate the rules — pointer only.

