# /tas-TestChecklist {Feature-ID} [--force-create] [--check-updates | --dry-run] [--skip-gaps]

**Owner:** PE | **Generator:** QA Agent | **Version:** 3.3 — Lean Consolidation

**Purpose:** High-level test design for a Feature → flow-based test points with ≥90% coverage gate.
**Input:** `{CODE}-Feature-{NNN}-{slug}.md`, `{CODE}-Feature-{NNN}-{slug}-Technical.md` (+ PRD for NFR sync). Confirmed flows from Phase 1.3.5.
**Output:** `Feature-{NNN}-TestChecklist.md` — sections per `.tas/templates/TestChecklist.md`.
**Core Principle:** If information is vague → ASK (Phase 1.3.3–1.3.4), never assume.

**Scope — IN / OUT:** PE-testable + human-executable flows/NFRs IN; tooling-required handoffs OUT. Canonical boundary: [test-design.md § QA vs. DevOps Scope](../../rules/qa/test-design.md#qa-vs-devops-scope).

> **Template is the contract.** Section numbers, columns, IDs, frontmatter field names, and AI Usage Log format are defined by `.tas/templates/TestChecklist.md` — this command never re-states them, it only describes *how* to populate them.

---

## Quick Reference

```bash
/tas-TestChecklist TAS-001                            # default UPDATE-SYNC
/tas-TestChecklist TAS-001 --check-updates            # show diff, ask before applying
/tas-TestChecklist TAS-001 --force-create             # backup old + regenerate
/tas-TestChecklist TAS-001 --dry-run                  # detect changes, no write
/tas-TestChecklist TAS-001 --skip-gaps                # skip gap-detection questions
```

---

## Resume Check (before Phase 0)

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`** · **`feature_technical`** · `prd` (if read) · `sad` (if read)
- Phase 1 digests: base 4 (`feature_digest`, `tech_digest`, `sad_digest`, `conflict_list`) — no command-specific additions

**Check:** `.tas/command-cache/testchecklist-{FEATURE_ID}-phase1.md`
- **Found + all sources unchanged** → load digests, skip to Phase {N+1}.
- **Found + any source newer** → delete checkpoint, restart full run.
- **Not found** → proceed to Phase 0.

---

## Phase 0 — Source Intake (Read-Once Manifest)

**Goal:** Read each source document exactly once → digest into named variables. Later phases reuse digests.

### Phase 0.0 — Project Cache (PRD + SAD + Design-Spec + Tech-Stack)

Apply [verification-layers.md § 8](../../rules/qa/verification-layers.md#8-project-cache-docsqa-project-basemd) against `docs/qa-project-base.md` — project-wide, persists across Features (not deleted like the per-Feature checkpoint in §7):

1. Cache absent → read PRD + SAD (+ Design-Spec, CLAUDE.md `## Tech Stack` if present) in full, build digests, **then immediately write `docs/qa-project-base.md` to disk via the Write tool (§8.2 Step 1) — this is a mandatory file write, not a mental note or scratchpad entry. Do not proceed to Step 0.1 until the file exists on disk.**
2. Cache present + all docs' `{version, last_updated}` unchanged → skip re-reads, use cached `prd_nfr_digest` / `project_roles[]` / `prd_usecase_digest` / `sad_digest` / `sad_flow_digest` / `known_externals[]` / `integration_contracts[]` / `design_spec_digest` / `tech_stack_digest` directly (§8.2 Step 2).
3. Cache present but a doc's `{version, last_updated}` changed → check that doc's `## Changelog` for changes touching a tracked anchor ([§8.3](../../rules/qa/verification-layers.md#83--tracked-anchors-testchecklist)); touched → re-read that anchor only; not touched → update stored version/date, no re-read (§8.2 Step 3).

Output feeds `prd_read_mode` below and Phase 4.5 — this step replaces a full PRD open for NFR/persona/flow content; Phase 4.5 still handles feature-specific BR-tracing reads. All 9 digests above are held in memory for Phase 1.3.3's Layer 3 gap resolution — never re-read there.

**Input Detection (file-finding patterns):**

| Pattern | Match ✅ | Action |
|---------|----------|--------|
| `**/*-Feature-*.md` | `{CODE}-Feature-{NNN}-{slug}.md` | ERROR if 0 matches (Glob) |
| `**/*-Feature-*-TestChecklist.md` | Existing TestChecklist | Parse frontmatter (Glob) |
| `BR-\d{3,4}` | `BR-003:`, `BR-007/008` | Set `prd_read_mode=full` if found (Grep `-n`) |
| `^#{1,3}\s*NFR` | `## NFR`, `### Non-Functional` | NFR section anchor for Phase 4.5 (Grep) |

**Step 0.1–0.5:** Read Feature.md → store `feature_digest`:
- Frontmatter (`status`, `implements_frs`, `plan_status`)
- `## Acceptance Criteria` → all AC-N with Given/When/Then + `(FR-NNN, BRU-NNN)` tag (full text, never paraphrase)
- `## User Flow` → actor per step (role named inline — Feature.md has no separate Actor/Persona section) → feeds `role_matrix_applicable` non-public-actor check ([test-design.md § Role Matrix Applicability Detection](../../rules/qa/test-design.md#role-matrix-applicability-detection-role_matrix_applicable))
- `## Non-Functional Requirements` → NFR-NNN list (if present) → `feature_nfr_digest`
- AC/User Flow text naming an existing contract/behavior ("existing", "still work", "unchanged", "sync", "consistent") → feeds `bc_applicable` Suspect-verdict check ([test-design.md § Backward-Compat Applicability Detection](../../rules/qa/test-design.md#backward-compat-applicability-detection-bc_applicable))

Read Feature-Technical.md → store `tech_digest`:
- `## Context Refs` (pre-resolved PRD/SAD/ADR pointers — do not re-open full PRD/SAD from this table)
- `## Modules` (Entities owns/uses, Contracts produces, NFRs claimed)
- `## DO NOT CHANGE` → IC-NN contracts consumed (frozen cross-stack dependencies)
- `## Context Diagram` → `**External systems:**` bullets (3rd-party/integration scope)
- `## API Spec` + `Error Codes` (endpoints, methods, request/response, status) → an endpoint's auth-scheme/permission handler feeds `role_matrix_applicable`; an endpoint also in a `#### Modify` file-changes table feeds `bc_applicable`
- `## Stack: {Web|Service|Integration|App}` → whichever sections are present (each is omitted entirely if not involved) → `available_stacks[]`

Scan for PRD refs (`BR-\d{3,4}` in Feature.md, or the PRD row in `## Context Refs`) → set `prd_read_mode` (Phase 0.0 already covers NFR/persona/flow content — this only governs the deeper BR-tracing read in Phase 4.5, which the cache cannot replace since it does not track BR/FR mapping). PRD/SAD digests come from Phase 0.0 — do not re-read either file here.

---

## Phase 1 — Input Validation & Scope Analysis

**Ref:** [verification-layers.md § 2](../../rules/qa/verification-layers.md#2-the-5-phase-vocabulary-per-phase--tier-2)

### Phase 1.0 — Input Validation Gate

**Goal:** Validate CLI inputs + Phase 0 digests.

**Validate:** Feature code format (`^[A-Z0-9]+-\d+$`), Feature-Technical present, Platform ∈ {web, app, All}, CLI flags recognized.  
**Result:** Pass → Phase 1.1 | Fail → STOP with error message.

### Phase 1.1–1.4 — Scope Analysis & Confirmation Gate

**Input:** `feature_digest`, `tech_digest`, `sad_digest` (via Context Refs table, if present).

| Step | Action | Output |
|------|--------|--------|
| **1.1** | Extract in-scope boundary (User flows + System flows + SAD constraints). **ASK** if out-of-scope section missing. Detect scope narrowing: retained ⊂ available → `scope_narrowed` flag. Ref: [test-design.md § QA vs. DevOps Scope](../../rules/qa/test-design.md#qa-vs-devops-scope). | Merged boundary (User + System + SAD) + `scope_narrowed` flag + `scope_gap[]` |
| **1.2** | Determine PE-executable test types from boundary. | Test Type list (Web/App UI, Security Probe, Data Verification, etc.) |
| **1.3** | Confirm flows from Feature.md ACs → flow type (Main/Alt/Edge) + risk tags `[Security]`, `[Data-Critical]`, `[User-Blocking]`, `[Integration]` + dependencies. Run Phase 1.3.3 gap-detection (4-layer pipeline, below) and Phase 1.3.4 settings ASK (shared components, NFR baselines, test data catalog, traceability matrix). | Confirmed flows + risk tags + dependencies + gap answers |
| **1.4** | **Risk-reopen check:** any AC/flow excluded from scope at 1.1 that still matches a risk-tag vocabulary (`[Security]`, `[Data-Critical]`, `[User-Blocking]`, `[Integration]`) → **ASK** re-include in scope; declined → mandatory §5 risk row (never silently dropped). **BLOCKING GATE:** Runs only after Phase 1.3.3.4 completes (all auto-resolutions confirmed/rejected, all open questions answered/skipped) and the risk-reopen check above. Emit resolved scope inventory (flows, constraints, unresolved gaps → §5 risks). **ASK** [Y/N] Correct + complete? | Scope confirmation (PASS → save Phase 1 checkpoint, continue Phase 2 | FAIL → loop to 1.1 or 1.3.3) |

#### Phase 1.3.3 — Gap Detection (3-Layer Pipeline)

**Ref:** [test-design.md § Requirement Gap Detection Patterns](../../rules/qa/test-design.md#requirement-gap-detection-patterns), [§ Cross-Document Consistency Patterns](../../rules/qa/test-design.md#cross-document-consistency-patterns), [§ PRD-to-Feature Mapping](../../rules/qa/test-design.md#prd-to-feature-mapping) (incl. Entry/Exit sub-rule), [§ Attempt-Answer Procedure](../../rules/qa/test-design.md#attempt-answer-procedure-layer-2--layer-3). Every sub-step below is a pointer into that file — logic is never restated here.

| Sub-step | Layer | Action | Digests read |
|---|---|---|---|
| **1.3.3.1** | Layer 1 | Detect — 14 patterns + Logic Validation + Enum Interaction Check against Feature.md ACs. Detect only, no ask yet. | `feature_digest` |
| **1.3.3.2** | Layer 2 | Attempt-Answer Procedure against `tech_digest` for every Layer-1 gap + Feature-vs-Technical instances of C1/C2/C3/C5/C6 + the Layer-2 half of C7/`bc_applicable`/`role_matrix_applicable`. | `feature_digest`, `tech_digest` |
| **1.3.3.3** | Layer 3 | Attempt-Answer Procedure against the Project Cache for gaps still unresolved + C4/C4B + [§ Shared Component Detection](../../rules/qa/test-design.md#shared-component-detection-from-prd) (PRD use-case overlap → `[SHARED-COMPONENT]`, independent of `scope_narrowed`) + PRD/SAD-facing C1–C6 + the Layer-3 half of C7/`bc_applicable`/`role_matrix_applicable` + Design-Spec/Tech-Stack screening. | `prd_nfr_digest`, `project_roles[]`, `prd_usecase_digest`, `sad_digest`, `sad_flow_digest`, `known_externals[]`, `integration_contracts[]`, `design_spec_digest`, `tech_stack_digest` (all from Phase 0.0 — no re-read) |
| **1.3.3.4** | Present | Emit `[AUTO-RESOLVED]` confirm/reject list for Layer-2/3-resolved gaps (Confirmed-verdict `bc_applicable`/`role_matrix_applicable` skip straight to §5/TP-input — no confirm/reject needed), then the open-question list for anything still unresolved. Route Y/N/EDIT and open-question answers through the unchanged Answer Mapping table. | — |

**Rule:** Unsourced constraint → stays `[BR-AMBIGUITY]` risk (never invented as value).

---

## Phase 2 — High-Level Test Design

> Ref: [test-design.md § TP Category → Test Approach Mapping](../../rules/qa/test-design.md#tp-category--test-approach-mapping-istqb).

**Input:** `feature_digest` (ACs), `tech_digest` (API Spec), gap answers from Phase 1.3.3.

| TP Source | Derivation | Output |
|-----------|-----------|--------|
| **Feature ACs (Given/When/Then)** | Business Process Mapping (high-level flows, not field-level) | 1 TP per major user flow |
| **API Spec (endpoints + outcomes)** | FE-Observable UI Behavior (success/error/loading states) | 1 TP per distinct FE response outcome (NOT per HTTP status code) |
| **Phase 1.3.3 gap answers** | Answer Mapping (see [test-design.md § Answer Mapping](../../rules/qa/test-design.md#-answer-mapping-gap--test-points--risks)) | 1–2 TPs per gap; if unanswered → `[BR-AMBIGUITY]` risk (RC-BR, owner PE) |

**Coverage Gate (internal):** All test types from Phase 1.2 have ≥1 TP; else flag `[TECH-COVERAGE]` in §5.

**Phase 2 checkpoint:** Save `.tas/command-cache/testchecklist-{FEATURE_ID}-phase2.md` with TP counts + technique map.

---

## Phase 3 — Determine Mode

| Condition | Mode |
|-----------|------|
| File missing | CREATE |
| `--force-create` | CREATE (backup old) |
| `--check-updates` or `--dry-run` | UPDATE-REVIEW |
| Default (no flags) | UPDATE-SYNC |

**`--force-create` pre-check:** Scan old §2.1 for TPs with category EXC/STATE/INT/BL/NFR that have no AC keyword match → **ASK** carry forward? Store carried IDs → Phase 5 merges with `[carried-forward]` note.

**Phase 3.5–3.6:** Detect Feature + PRD file changes (git log → mtime → sha256). Set `prd_read_mode` per Phase 0 logic.

---

## Phase 4 — Version Bump & Smart PRD Read

**Version policy:** per [verification-layers.md § 5](../../rules/qa/verification-layers.md#5-shared-foundation-block-template) — Feature changed (± PRD) → +1.0 MAJOR · PRD changed only → +0.1 MINOR · No changes → NO BUMP (audit-only; no Change Log/AI Usage Log row).

**Phase 4.5 — Smart PRD Read (deferred from Phase 0):**
- `prd_read_mode=full` → read PRD fully now (BR-tracing; NFR already in `prd_nfr_digest` from Phase 0.0 — do not re-read NFR section)
- `prd_read_mode=nfr_only` → no additional read; `prd_nfr_digest` already satisfies this from Phase 0.0

Route `prd_nfr_digest` requirements: PE-testable (NFR baselines §2.2) | tooling-required → `[TECH-COVERAGE]` (RC-PERF, RC-INT, RC-SEC).

**ADR check:** Use ADR list from Context Refs. FE-observable security → 1 SEC TP per ADR (§2.1.1). Infra-level → `[TECH-COVERAGE]` risk.

---

## Phase 5 — Output

### Phase 5.0 — Mandatory Template Read (blocks the rest of Phase 5)

**This step exists because the #1 failure mode of this command is drafting the output's shape from general QA knowledge instead of copying the template.** Skipping it is not an option.

1. **Read** `.tas/templates/TestChecklist.md` in full — now, even if it was read in a prior run. Never reuse a memorized structure.
2. Extract its heading list verbatim (every `#`/`##`/`###` line, in order) → `template_skeleton[]`. Do not paraphrase, renumber, or reorder.
3. Extract every table's column header row per section → `template_columns{section: [columns]}`.
4. Hold both in working memory for the rest of Phase 5 — every section written below must match one entry exactly. No heading, subsection, or column gets written unless `template_skeleton[]`/`template_columns{}` has a matching slot; content with no slot belongs in an existing section's Notes/Rationale column, or it doesn't belong in this artifact.

**Gate:** Cannot proceed to CREATE/UPDATE-SYNC/UPDATE-REVIEW below until `template_skeleton[]` is populated from an actual Read this run.

**§6 Effort Estimation:** Formula owned by [verification-layers.md § 9](../../rules/qa/verification-layers.md#9-effort-estimation-rom--agile-priority-weighted--istqb-test-level) — **do not restate it here or in the output**. Once §1.1/§2.1/§1.2–§1.3/§1.5/§5 are complete, compute every row **in-head** per §9 (no script) and render the template's §6 table only. Set `eta_total_hours`/`eta_total_pd` from the Total row.

Three modes; apply per table:

| Mode | Process | Output |
|------|---------|--------|
| **CREATE** | Generate all §1–§7 from confirmed scope + gap answers. Multi-pass §2.1: Pass 1 = extract TPs per AC/category → Pass 2a = dedup IDs → Pass 2b = assign Test Approach → Pass 2c = extract TP dependencies → Pass 2d = split §2.1.1 (feature-wide) vs §2.1.2 (per-AC). | New artifact |
| **UPDATE-SYNC** | Skip scope confirmation (Phase 1.4); preserve `approval:` block; update audit fields always. Append changelog + AI log only on version bump (Phase 4). | Updated artifact |
| **UPDATE-REVIEW** | Steps 1–4 of SYNC; STOP before write; show change detection; **ASK** approval before writing. | Conditional |

**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/TestChecklist.md` — frontmatter fields {owner, author, created_by, created_date, updated_date} are empty placeholders for substitution.

Then set:
  - `version` = 1.0 (CREATE) or increment per Version Policy
  - `extensions.test_checklist.check_count=1`, `approval.status=draft`, `artifact-status=draft`

**Phase 5.9 — AI Usage Log + Cleanup:** Append row to §8 AI Usage Log (CREATE or UPDATE with version bump only); skip on audit-only runs. Follow `.tas/rules/common/token-logging.md` format. Delete cache files.

---

## Output Validation (MANDATORY)

Before output, verify:
1. **Skeleton diff:** the output's heading list, in order, equals `template_skeleton[]` from Phase 5.0 exactly — same section numbers, same heading text, no extra headings, none missing (conditional §1.4/§2.4/§3 present only if Phase 1.3.4 flag = Y). Every table's header row equals `template_columns{}` for that section. Any mismatch → fix the output, not the check.
2. Flow IDs `{FEAT}-F{NNN}-AC{N}`; TP IDs `{FEAT}-{CAT}-{N}`
3. All `extensions.test_checklist.*` fields populated (incl. `eta_total_hours`/`eta_total_pd`)
4. Coverage ≥90% OR gap explained in §5
5. YAML frontmatter valid (no syntax errors)
6. §6 Effort Estimation: visible content is the template table only — no extra sub-heading, no bullet-list "show work" (computation stays in-head per [verification-layers.md § 9](../../rules/qa/verification-layers.md#9-effort-estimation-rom--agile-priority-weighted--istqb-test-level)). Rows skip Condition=false (no 0h rows); Total row present; `eta_total_hours`/`eta_total_pd` set.
7. §7 Change Log: row appended IF (CREATE OR UPDATE with bump), skip on audit-only (same gate as #8); Author = `git config user.name` output per [verification-layers.md § 5.1](../../rules/qa/verification-layers.md#51-authorship--audit-metadata-canonical-) procedure
8. §8 AI Usage Log appended IF (CREATE OR UPDATE with bump); skip on audit-only
9. §5 Risk Registry scanned: `[BR-AMBIGUITY]`, `[TECH-COVERAGE]`, `[SHARED-COMPONENT]` all checked; each risk written with RC code (not tag)

✅ PASS all 9 → output | ❌ FAIL any → fix + re-validate.

---

## Error Handling

| Error | Action |
|-------|--------|
| Invalid feature code | Show expected: `XXX-NNN` |
| File not found | Show expected path |
| Invalid platform | Show: `web \| app \| All` |
| Invalid flag | Show valid: `--force-create`, `--check-updates`, `--dry-run`, `--skip-gaps` |
| Corrupted TestChecklist | Suggest `--force-create` |
| PRD missing (UPDATE) | Warn: "PRD required for NFR sync" |

---

## Frontmatter Fields

Template frontmatter (lines 1–69) is authoritative. This command only describes how to populate:
- **Auto-calc:** `flows_*`, `test_points_*`, `nfrs_*`, `risks_*`, `coverage_percentage`
- **Change tracking:** `last_content_change`, `upstream_versions.*`
- **Audit:** `last_check_date`, `check_count`
- **Gate:** `coverage_percentage ≥90%`, `gate_result`, `gates_auto_passed`, `gates_pending_human`

---

## Design Principles (v3.3)

1. **Template is the contract** — never invent sections/columns
2. **Ask > Assume** — vague info → ASK, never silent assumption
3. **Single Source of Truth** — §5 Risk Registry is authoritative
4. **Conditional Sections** — 1.4, 2.4, 3 generated only if explicitly requested
5. **Git-aware Change Detection** — 3-tier fallback: git → mtime → hash
6. **Smart Reads** — PRD read scope based on BR-reference detection
7. **Deterministic Versioning** — per Phase 4 Version Policy (SSoT: [verification-layers.md § 5](../../rules/qa/verification-layers.md#5-shared-foundation-block-template))
8. **Always Append** — Change Log + AI Usage Log append on version bump; no overwrites
9. **Manual Approval Only** — never auto-approve; never auto-reset `approval:` block
10. **Token-Efficient** — deterministic change detection avoids redundant reads
