# /tas-functest $FEATURE_FILE $CHECKLIST_FILE

You are a Senior QA Engineer creating a comprehensive Functional Test Specification based on a Feature document and Test Checklist.

## Purpose

Generate a detailed Functional Test Specification document that maps Acceptance Criteria to executable test cases, with proper traceability, test data management, and automation readiness flags.

**Scope — IN / OUT:** UI/observable black-box testing (ISTQB Ch 4.2) — human-QC-executable test cases + P2 UX/NFR. API contract/interface + tooling-required NFR → `/tas-apitest-plan`. Canonical boundary: [verification-layers.md §4 Scope-Conflict Matrix](../../rules/qa/verification-layers.md#4-scope-conflict-matrix-functest--apitest-plan).

## Shared Foundation (read first)

| Concern | Canonical Source |
|---|---|
| ISTQB technique routing (functional) | [test-design.md § TP Category → Test Approach Mapping](../../rules/qa/test-design.md#tp-category--test-approach-mapping-istqb) |
| Priority assignment (P0/P1/P2 by tool availability) | [test-design.md § Testing Priority Assignment](../../rules/qa/test-design.md#testing-priority-assignment-tool-availability) |
| TC-count expansion + **6 Dedup Rules** | [tc-generation-strategy.md § Layer 3 + § The 6 Deduplication Rules](../../rules/qa/tc-generation-strategy.md) |
| TC ID convention + Category codes | [test-id-convention.md §2, §4](../../rules/qa/test-id-convention.md) |
| 5-phase vocab + scope-conflict | [verification-layers.md](../../rules/qa/verification-layers.md) |
| Autoable values (`YES | NO` — binary) | [tc-generation-strategy.md § Autoable Classification](../../rules/qa/tc-generation-strategy.md#autoable-classification-phase-2--phase-3-handoff--canonical-) |
| §4.E origin (design-spec/tech-stack UI/UX + non-scriptable risk) | [test-design.md § Design-Spec/Tech-Stack Screening](../../rules/qa/test-design.md#design-spec--tech-stack-screening) — TestChecklist already resolves this into §2.1 TPs or §5 risk; do NOT re-detect here |
| AI Usage Log format | [token-logging.md](../../rules/common/token-logging.md) |

**Frontmatter base (output file):** `feature_id` · `release_id` (optional) · `status: Draft` (never auto-approve).
**Version policy:** per [verification-layers.md §5](../../rules/qa/verification-layers.md#5-shared-foundation-block-template) (Feature = MAJOR source, PRD = MINOR source — same mapping as the generic rule, no local override).

## When to Use

- Run after Test Checklist is approved
- Run before writing automation scripts
- Run when Feature requirements change (update test spec)

## Prerequisites

1. Feature document exists (pattern: `*-Feature-*.md`)
2. Test Checklist exists (pattern: `*-TestChecklist.md`) - optional but recommended
3. Template exists at `.tas/templates/Func-Test.md`
4. `tas.yaml` exists at project root

## Resume Check (before Step 1)

Checkpoint strategy: [verification-layers.md §7](../../rules/qa/verification-layers.md#7-checkpoint--resume) (SSoT).

**Sources + Digests (per §7.5 table):**
- `source_mtimes` keys: **`feature`** · **`testchecklist`**
- Phase 1 digests: base 4 (`feature_digest`, `tech_digest`, `sad_digest`, `conflict_list`) + command-specific: `funct_digest` (full TC list from Func-Test scope)

**Check:** `.tas/command-cache/functest-{FEATURE_ID}-phase{N}.md`
- **Found + feature + testchecklist mtimes unchanged** → load digests + AC dep map, skip to Step {N+1}, print resume summary.
- **Found + any source newer** → delete checkpoint, restart full run.
- **Not found** → proceed to Step 1.

---

## Step-by-Step Actions

> **5-Phase mapping** ([verification-layers.md §2](../../rules/qa/verification-layers.md)): **Input** = Steps 1–1.6 · **Design** = Steps 2–3.5 · **Detail** = Step 4 · **Gate** = Step 8 · **Output** = Steps 5–7, 9.

### Step 1 (Input): Locate and Read Input Documents

**1.1 Feature Document:**
   - If `$FEATURE_FILE` provided, use that
   - Otherwise, resolve the Feature dir `docs/features/{CODE}-Feature-{NNN}-{slug}/` and read the Feature file (the one WITHOUT `-Technical` suffix); fall back to `*-Feature-*.md` in current directory only if not run from repo root
   - Extract: Feature Code, Feature Name, Acceptance Criteria (kit v3 = Feature-only; no Epic/Story)

**1.2 Test Checklist:**
   - If `$CHECKLIST_FILE` provided, use that
   - Otherwise, search for `*-TestChecklist.md` in current directory
   - Extract all test points from checklist matrix by category
   - Map checklist points to test cases

**1.3 Extract Feature ID** (CRITICAL — determines all TC IDs):

   Priority hierarchy: TestChecklist frontmatter `feature_id:` → Feature document `feature_id:` → TestChecklist §1.1 Flow ID.
   Store as `FEATURE_ID` (e.g., `F003`). **TC ID format** is canonical in [test-id-convention.md §2](../../rules/qa/test-id-convention.md) — do not redefine.

**1.4 Extract Dependency Map** — from TestChecklist §2.1 (CRITICAL — for Depends propagation):

   For each TP row in TestChecklist §2.1:
   - If `Depends On` column is filled (not `None`/`—`):
     → Store entry: `dep_map[TP_ID] = Depends_On_TP_ID`
   
   Example: `dep_map["TP-A004"] = "TP-A003"` means TP-A004 depends on TP-A003.
   Store `dep_map` for use in Steps 3–4 and validation in Step 8.

**1.5 Read Template:**
   - Read `.tas/templates/Func-Test.md`

### Step 1.6 (Input): Detect Input Defects (gap-first — run before designing TCs)

Scan inputs before generating anything. Do **not** fabricate to fill a gap.

- **AC with no covering TP** in TestChecklist §2.1 → coverage gap. SKIP that AC and **ask user** to update TestChecklist (or confirm intentional). If proceeding anyway → record in §5 risk.
- **AC ambiguous / Given-When-Then incomplete** in Feature.md → ASK PE to clarify; do not guess the expected result.
- **TestChecklist absent** → warn, generate from Feature only, and note reduced-coverage risk in §5.
- **Conflict** between Feature AC and TestChecklist TP → STOP + ask which is authoritative.

**Phase 1 checkpoint (after Step 1.6, on no blocking defects):** Save `.tas/command-cache/functest-{FEATURE_ID}-phase1.md` with `FEATURE_ID`, AC list, `dep_map`, `feature_mtime`. Print: `📌 Checkpoint saved → .tas/command-cache/functest-{FEATURE_ID}-phase1.md`

### Step 2 (Design): Declare Scope + Structure Requirements

**Emit scope declaration** (mandatory per [verification-layers.md §4](../../rules/qa/verification-layers.md#4-scope-conflict-matrix-functest--apitest-plan)): `Scope: UI/observable black-box (ISTQB Ch 4.2). API contract/interface + tooling-NFR → /tas-apitest-plan.` Mark each AC in/out per §1.6 gap check (out-of-scope AC → defer, note in §5).

From Feature document, extract:

**A. Acceptance Criteria (AC):**
- Each AC with Given/When/Then format
- Assign AC ID: `{FeatureCode}-AC{N}`
- TC Priority (P0/P1/P2) is inherited per-TC from the source TP in TestChecklist §2.1 during Step 3 (not assigned here).

**B. Feature Context:**
- Feature Summary: As a [user], I want [action] so that [benefit]
- Scope: What's being tested
- Out of Scope: What's NOT tested
- Dependencies: APIs, mocks, upstream features
- Test Strategy: Manual → Automation

### Step 3 (Design): Map Checklist to Test Cases

Design decision only — no rendering yet (Step 4 renders). For each TP in checklist decide: **technique** (L2), **TC count** (L3), **priority** (inherit from TP), **Autoable**, **Depends**, plus **NFR → scripted TC vs SKIP**.

* §2.1.1 (Cross-Cutting) → Route per Category + Priority
* §2.1.2 (Per-AC) → Route per Category + Technique
* §2.1.3 (API Response) → Route per EXC category (1 TC per error type)
* **NFR (§2.2)** → per NFR: matches critical pattern in [test-design.md § Critical UI/UX Patterns](../../rules/qa/test-design.md#critical-uiux-patterns--scripted-tcs-when-to-create-vs-skip) → scripted TC; else SKIP (P2 UX/UI, manual if needed). Tooling-required NFR → §5 Inherited Risk.

**Output routing (same Autoable decision above — no new logic, no re-derivation):**
- Autoable=YES (VAL/BL/EXC) → renders in §4.1–4.5 (Step 4)
- Autoable=NO (GUI/SEC/INT) → renders in §4.E (Step 4), `Source=TP`, `Traceability=`{originating TP ID}. These TPs may originate from a plain AC or from TestChecklist's Design-Spec/Tech-Stack Screening ([test-design.md §380](../../rules/qa/test-design.md#design-spec--tech-stack-screening)) — either way, tas-functest only reads the already-resolved TP, never re-screens design specs or tech stack itself.

Apply [test-design.md](../../rules/qa/test-design.md) (routing + technique = L2) and [tc-generation-strategy.md](../../rules/qa/tc-generation-strategy.md) (TC count + dedup + Autoable + Depends + Test Data = L3).

### Step 3.5 (Design): Determine Section 4 Layout (Pre-Generation Decision)

```
total_tc_count = total TCs across all flows
layout = "SINGLE_TABLE" if total_tc_count ≤ 30 else "MULTI_TABLE"
```

* **SINGLE_TABLE** (≤30 TCs): one `## 4. Test Cases` table
* **MULTI_TABLE** (>30 TCs): group by **business flow** from TestChecklist §1.1 — `### 4.1`, `### 4.2`, … per flow, each with its own table. If any flow has >20 TCs, subdivide that flow by AC (`#### 4.1.a`, `#### 4.1.b`, …).
* **NEVER** use `#####` TC-ID headings with nested text blocks — always tables.

**Phase 2 checkpoint (after Step 3.5):** Save `.tas/command-cache/functest-{FEATURE_ID}-phase2.md` with TC count per AC, `layout` decision, technique-per-TP map. Print: `📌 Checkpoint saved → .tas/command-cache/functest-{FEATURE_ID}-phase2.md`

### Step 4 (Detail): Generate Test Case Sections (Using Layout from Step 3.5)

Render the design from Step 3 into §4.1–4.5 or §4.E per the Autoable routing decided in Step 3 (SSoT for column structure + order = template `Func-Test.md` §4). Do not re-route or re-decide here — same TC generation, same Test Data sourcing, same Depends propagation; split only by destination table:
- Autoable=YES → §4.1–4.5 (existing behavior, unchanged)
- Autoable=NO → §4.E, populate `Source=TP` and `Traceability=`{TP ID} columns

Enforce for both destinations:
1. **Depends propagation:** Apply `tc_depends` from Step 3 per [tc-generation-strategy.md § Dependency Management](../../rules/qa/tc-generation-strategy.md)
2. **Coverage:** ≥1 Happy Path TC per AC + the Negative/Edge/Permission/NFR TCs decided in Step 3.
3. **Test data:** Populate the Test Data column with concrete values from TestChecklist §2.3 (not abstract field names) per [tc-generation-strategy.md Rule 6](../../rules/qa/tc-generation-strategy.md#rule-6-test-data-sourced-from-testchecklist-23-not-tp-definition), tagged `field: "value" [TECHNIQUE·tag]` (technique per Step 3).

### Step 5 (Output): Fill Frontmatter and Metadata

**Authorship (per [verification-layers.md § 5.1](../../rules/qa/verification-layers.md#51-authorship--audit-metadata-canonical-)):**
- Read PE name from `tas.yaml` key `project.qa_owner` → populate `owner` (CREATE only, immutable)
- Run `git config user.name` → populate `author`, `created_by`, Change Log Author (per § 5.1 procedure: git user, or fallback to owner)
- Set `created_date`, `updated_date` (YYYY-MM-DD): CREATE for both; UPDATE for updated_date only

**Template:** `.tas/templates/Func-Test.md` — frontmatter fields {owner, author, created_by, created_date, updated_date} are empty placeholders for substitution.

Then populate remaining template fields:
```yaml
feature_id: {FEATURE_ID from Step 1.3}
status: Draft
platform: {web | app | service | integration}
tags: [functional, {feature_slug}]
ver: 1.0

sources:
  testchecklist: "{path} # v{ver}"
  feature: "{feature_id} # v{ver}"
  reviewed: {YYYY-MM-DD}

test_strategy:                      # carry inclusion_rules from TestChecklist routing if specified
  scope: manual_gui_execution
  inclusion_rules: { ... }          # Apply defaults per [tc-generation-strategy.md § Inclusion Rules](../../rules/qa/tc-generation-strategy.md) unless TestChecklist routing overrides
  coverage: { total_tps, included_tps, excluded_tps, coverage_percentage }
```

### Step 6 (Output): Generate Coverage Matrix

**Requirement Coverage Matrix:**
- Map each AC to covering TC IDs
- Calculate coverage % (ACs with at least 1 TC)
- Target: 100% AC coverage

**Test Run Summary:**
- Total TCs by priority
- Pass/Fail/Blocked counts (initially all "— Not Run")

### Step 7 (Output): Generate Risk & Assumption Log

Write both into template §5 (Inherited Risk Notes) — inherited first, then execution:
1. **Inherit from TestChecklist §5 (FIRST):** carry forward any active `[BR-AMBIGUITY]`, `[TECH-COVERAGE]`, `[SHARED-COMPONENT]`, `[NFR-NON-PE]` risk — out-of-functional-scope here, owned per TestChecklist. Plus any gap from Step 1.6.
2. **Route PE-owned exploratory risk to §4.E (same §5 read as bullet 1 — no re-read):** for each row where `Owner=PE` AND note references "FuncTest §4.E exploratory" — these rows originate from TestChecklist's Design-Spec/Tech-Stack Screening ([test-design.md §380](../../rules/qa/test-design.md#design-spec--tech-stack-screening)); tas-functest only ROUTES them, never re-derives or re-screens → add 1 row to §4.E, `Source=Risk(§5)`, `Traceability=`{Risk ID}. Do NOT also duplicate this row into the §5 Inherited Risk Notes list below (it is now covered as an executable TC, not an open risk).
3. **Add execution risks (if any apply):** API stability · test data availability · environment config · feature flags · third-party dependencies. Omit §5 entirely if no inherited AND no execution risk.

### Step 8 (Gate): Validate Section 4 Layout + Write Output File

**Pre-Write Validation (CRITICAL — run ALL checks before writing):**

```
✓ Check 0 (Feature ID): Verify FEATURE_ID extracted from Step 1.3 (not feature_code). If looks like "PROJ-Feature-001" → STOP.

✓ Check 1 (Layout): Rendered §4 matches SINGLE_TABLE/MULTI_TABLE decision (Step 3.5), each table ≤20 rows. NEVER ##### TC-ID headings → REJECT.

✓ Check 2 (Columns): Table headers match template Func-Test.md §4 (count + order). If missing "Pre-Condition", "Execution Locators", "Test Result" → STOP.

✓ Check 3 (Depends): For TPs in dep_map → verify all TCs start with "Depends: {TC_ID}", referenced TC exists, no self-dependency. For entry points → verify no "Depends:". On fail → STOP.

✓ Check 4 (Dedup): Apply the 6 Dedup Rules from [tc-generation-strategy.md § The 6 Deduplication Rules](../../rules/qa/tc-generation-strategy.md#the-6-deduplication-rules). Flag any pair where: same field + same technique (Rule 1/3), or different ACs + identical business behavior (Rule 2), or multi-step split into separate TCs instead of one Depends chain (Rule 4). On true duplicate → merge to primary AC + link both ACs in §3 coverage; do NOT emit duplicate TC rows. Complementary TCs (same field, different technique) are NOT duplicates — keep.

✓ Check 5 (Autoable vocab): Every §4 `Autoable` cell ∈ {`YES`, `NO`} per [tc-generation-strategy.md § Autoable Classification](../../rules/qa/tc-generation-strategy.md#autoable-classification-phase-2--phase-3-handoff--canonical-). Any other value → STOP.

✓ Check 6 (§4/§4.E boundary): Every §4.1-4.5 row has Autoable=YES. Every §4.E row has Autoable=NO (Source=TP) OR Source=Risk(§5). No TC ID appears in both sections. On violation → STOP.
```

**If any validation fails:** Stop, log error with check number, do NOT output broken artifact.

Create file in the **Feature directory** (the SSoT path all downstream commands read):
```
docs/features/{CODE}-Feature-{NNN}-{slug}/{CODE}-FuncTest.md
```
`/tas-functest-web`, `/tas-functest-mobile`, and `/tas-functest-report` all resolve the spec from this exact path — writing it anywhere else breaks the chain.

Fill template `Func-Test.md` sections in order:
- Frontmatter (Step 5): `created_by`/`created_date`/`updated_date` per [verification-layers.md § 5.1](../../rules/qa/verification-layers.md#51-authorship--audit-metadata-canonical-), `ver` = 1.0 (CREATE) or increment per Version Policy
- §1 Feature Context
- §2 Environment & Data Configuration (keep defaults, customize if needed; delete §2.3 if no-auth)
- §3 Acceptance Criteria & Test Coverage (AC → TC IDs + coverage summary)
- §4 Test Cases (validated layout from Step 3.5) 
- §5 Inherited Risk Notes (from Step 7 — TestChecklist §5 carry-forward + Step 1.6 gaps)
- §6 Change Log: Author = `git config user.name` output per [verification-layers.md § 5.1](../../rules/qa/verification-layers.md#51-authorship--audit-metadata-canonical-) procedure, then AI Usage Log (follow `token-logging.md`)

**Checkpoint cleanup (after file written in Step 8):** Delete `.tas/command-cache/functest-{FEATURE_ID}-phase*.md`. Print: `✅ Checkpoints cleaned. FuncTest {FEATURE_ID} complete.`

### Step 9 (Output): Output Summary

Report to user:
```
✓ Functional Test Spec created: {filename}

Summary:
├─ Total ACs: {count}
├─ Total Test Cases: {count} (by category: GUI/VAL/BL/EXC/SEC/INT per test-id-convention.md §4)
├─ Automatable: {count} ({percent}%)
└─ Manual Only: {count} ({percent}%)

Priority Breakdown:
├─ P0 (Critical): {count}
├─ P1 (High): {count}
└─ P2 (Medium): {count}

AC Coverage: {percent}%
Target: 100%

Next Steps:
1. Review test cases with team; for Autoable=YES → `/tas-functest-web` (web) / `/tas-functest-mobile` (app). These reuse the §4 TC ID verbatim as each test title (chain contract).
2. §4 "Execution Locators" stays `_Phase 3 — SE_` here; Phase 3 overwrites it with the Locator DSL from Feature-Technical `### Locator Map`.
3. After running the automation, convert results into the Feature test report — `/tas-functest-report {Feature-ID}` (maps each result back to a §4 TC ID + applies the merge gate).
```

## Important Notes

- **One AC → multiple TCs**, each with a traceable AC ID (happy path + negative).
- **Independent & reproducible:** each TC runs standalone with isolated test data; include cleanup if it mutates state.
- **Verifiable Expected Results** — observable, not subjective.

## Error Handling

- No Feature found: "No Feature document found. Run in feature directory or specify: /tas-functest <feature-file>"
- No Checklist found: "Warning: No Test Checklist found. Will generate based on Feature document only."
- Template missing: "Error: Func-Test.md template not found in .tas/templates/"
- No ACs in Feature: "Error: Feature document has no Acceptance Criteria. Cannot generate test spec."
