with one click
tdd-spec
// [Testing] Use when you need to generate or update test specifications in feature docs (Section 15) with unified TC-{FEATURE}-{NNN} format.
// [Testing] Use when you need to generate or update test specifications in feature docs (Section 15) with unified TC-{FEATURE}-{NNN} format.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | tdd-spec |
| description | [Testing] Use when you need to generate or update test specifications in feature docs (Section 15) with unified TC-{FEATURE}-{NNN} format. |
Codex compatibility note:
- Invoke repository skills with
$skill-namein Codex; this mirrored copy rewrites legacy Claude/skill-namereferences.- Prefer the
plan-hardskill for planning guidance in this Codex mirror.- Task tracker mandate: BEFORE executing any workflow or skill step, create/update task tracking for all steps and keep it synchronized as progress changes.
- User-question prompts mean to ask the user directly in Codex.
- Ignore Claude-specific mode-switch instructions when they appear.
- Strict execution contract: when a user explicitly invokes a skill, execute that skill protocol as written.
- Subagent authorization: when a skill is user-invoked or AI-detected and its protocol requires subagents, that skill activation authorizes use of the required
spawn_agentsubagent(s) for that task.- Do not skip, reorder, or merge protocol steps unless the user explicitly approves the deviation first.
- For workflow skills, execute each listed child-skill step explicitly and report step-by-step evidence.
- If a required step/tool cannot run in this environment, stop and ask the user before adapting.
Codex does not receive Claude hook-based doc injection. When coding, planning, debugging, testing, or reviewing, open project docs explicitly using this routing.
Always read:
docs/project-config.json (project-specific paths, commands, modules, and workflow/test settings)docs/project-reference/docs-index-reference.md (routes to the full docs/project-reference/* catalog)docs/project-reference/lessons.md (always-on guardrails and anti-patterns)Situation-based docs:
backend-patterns-reference.md, domain-entities-reference.md, project-structure-reference.mdfrontend-patterns-reference.md, scss-styling-guide.md, design-system/README.mdfeature-docs-reference.mdintegration-test-reference.mde2e-test-reference.mdcode-review-rules.md plus domain docs above based on changed filesDo not read all docs blindly. Start from docs-index-reference.md, then open only relevant files for the task.
[BLOCKING] Execute skill steps in declared order. NEVER skip, reorder, or merge steps without explicit user approval. [BLOCKING] Before each step or sub-skill call, update task tracking: set
in_progresswhen step starts, setcompletedwhen step ends. [BLOCKING] Every completed/skipped step MUST include brief evidence or explicit skip reason. [BLOCKING] If Task tools are unavailable, create and maintain an equivalent step-by-step plan tracker with the same status transitions.
[IMPORTANT] task tracking BEFORE any work. NEVER skip task creation.
Goal: Generate/update test specs in feature docs Section 15 (canonical TC registry) — unified TC-{FEATURE}-{NNN} format. 5 modes: TDD-first, implement-first, update (post-change/PR), sync, from-integration-tests.
Workflow: (1) Mode Detection → (2) Investigation → (3) TC Generation → (4) Write Section 15 → (5) Dashboard Sync → (6) Next Steps
Key Rules: Unified TC-{FEATURE}-{NNN} format · Section 15 = source of truth · Evidence required on every TC · Minimum 4 categories (positive, negative, authorization, edge cases) · Interactive review via a direct user question mandatory
[BLOCKING] task tracking — break ALL work into small tasks BEFORE starting. NEVER skip.
External Memory: Complex/lengthy work → write findings to
plans/reports/— prevents context loss.
Evidence Gate: [BLOCKING] — every claim/finding/recommendation requires
file:lineproof + confidence % (>80% act, <80% verify first).
Graph Context (MANDATORY when graph.db exists): Before generating test specs for cross-service features, run:
python .claude/scripts/code_graph trace {ServiceDir}/{FeatureFile}.cs --direction both --jsonUse output to identify: event consumers, message bus subscribers, background jobs triggered by this feature. These are cross-service TC candidates (category 041–049).
[BLOCKING] task tracking todo to READ these reference files BEFORE generating TCs:
Evidence-Based Reasoning — Speculation is FORBIDDEN. Every claim needs proof.
- Cite
file:line, grep results, or framework docs for EVERY claim- Declare confidence: >80% act freely, 60-80% verify first, <60% DO NOT recommend
- Cross-service validation required for architectural changes
- "I don't have enough evidence" is valid and expected output
BLOCKED until:
- [ ]Evidence file path (file:line)- [ ]Grep search performed- [ ]3+ similar patterns found- [ ]Confidence level statedForbidden without proof: "obviously", "I think", "should be", "probably", "this is because" If incomplete → output:
"Insufficient evidence. Verified: [...]. Not verified: [...]."Cross-Cutting Quality — Check across all changed files:
- Error handling consistency — same error patterns across related files
- Logging — structured logging with correlation IDs for traceability
- Security — no hardcoded secrets, input validation at boundaries, auth checks present
- Performance — no N+1 queries, unnecessary allocations, or blocking calls in async paths
- Observability — health checks, metrics, tracing spans for new endpoints
.claude/skills/tdd-spec/references/tdd-spec-template.md— TC format template: GWT structure, Evidence field, decade-numbering, Preservation Tests section (mandatory for bugfixes). Read before generating any TC.
.claude/skills/tdd-spec/references/tdd-spec-template.md— TC template formatdocs/project-reference/domain-entities-reference.md— Domain entity catalog, relationships, cross-service sync (read directly when relevant; do not rely on hook-injected conversation text)docs/project-reference/integration-test-reference.md— Integration test patterns, fixture setup, seeder conventions, lessons learned (MUST READ before reviewing/writing integration tests)docs/specs/— Existing TCs by module — read BEFORE generating to avoid ID collisions
Workflow:
docs/specs/ cross-module dashboardKey Rules:
TC-{FEATURE}-{NNN} — feature codes in docs/project-reference/feature-docs-reference.mddocs/specs/ as primary destination.Evidence: {FilePath}:{LineRange} or TBD (pre-implementation) for TDD-firstreferences/tdd-spec-template.md#preservation-tests-mandatory-for-bugfix-specs| Skill | Relationship |
| --------------------------- | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| tdd-spec [direction=sync] | Native sync mode — syncs S15 TCs to/from docs/specs/ dashboard (replaces test-specs-docs) |
| integration-test | Code generator → generates integration tests FROM TCs written by this skill |
| feature-docs | Feature doc creator → creates the Section 15 that this skill populates |
| $spec-discovery | Upstream spec — engineering spec bundle is the source of truth for domain model | When TCs reveal implementation doesn't match spec-discovery output: run spec-discovery audit/update |
| Artifact | Path |
|---|---|
| TCs (canonical) | docs/business-features/{App}/detailed-features/{feature}.md Section 15 |
| Dashboard (optional) | docs/specs/{Module}/README.md Implementation Index |
| Priority index (optional) | docs/specs/PRIORITY-INDEX.md |
Phase-Mapped Coverage: When a plan exists with multiple phases, generate test cases PER PHASE — not just per feature. Each phase's success criteria must have ≥1 test case.
When this task involves frontend or UI changes,
docs/project-reference/frontend-patterns-reference.mddocs/project-reference/scss-styling-guide.mddocs/project-reference/design-system/README.mdDetect mode from prompt and context:
| Mode | Signal | Action |
|---|---|---|
| TDD-first | PBI/story exists, code not yet written | Generate specs from requirements |
| Implement-first | Code already exists, no/incomplete TCs | Generate specs from codebase analysis |
| Update | Existing TCs + code changes / bugfix / PR | Diff existing TCs against current code/PR, find gaps, update both |
| Sync | User says "sync test specs" or bidirectional need | Reconcile feature docs ↔ docs/specs/ (either direction) |
| From-integration-tests | Tests exist with test spec annotations, no docs | Extract TC metadata from test code → write to feature docs |
[REQUIRED] Confirm mode before Phase 2 when signals ambiguous:
"Detected mode: {detected_mode} for feature: {feature_name}. TCs to write: ~{estimated_count}. Correct?"
Options: [Yes, proceed] [Change mode] [Change scope]
Skip confirmation only when mode explicit in $ARGUMENTS AND feature name unambiguous.
Must read FIRST:
docs/project-reference/feature-docs-reference.md — correct {FEATURE} code for TC IDs (read directly when relevant; do not rely on hook-injected conversation text)docs/project-reference/spec-principles.md — Section 7 (TC Coverage Mapping), minimum categories and depth (read directly when relevant; do not rely on hook-injected conversation text)Spec Readiness Gate (BLOCKING — implement-first and update modes only):
Read target feature doc Sections 5, 6, 8, 13. Check:
[Source: file:line] citation — flag missingBR-XX — flag unreferenced operationsIf 2+ fail → a direct user question: "Spec readiness below TC generation threshold. Fill gaps first OR proceed with shallow TCs (Status: Planned)?" NEVER silently generate shallow TCs.
If target feature doc missing: suggest $feature-docs first, OR create minimal Section 15 stub.
TDD-first mode:
team-artifacts/pbis/ or user-providedImplement-first mode:
[BLOCKING]: Enumerate ALL operations first — establishes minimum TC floor.
Use Case Inventory (implement-first):
# Write-side: CQRS command handlers
grep -r "ICommandHandler\|CommandHandler\b" src/Services/{service}/ --include="*.cs" -l
# Write-side: REST mutating endpoints
grep -r "\[HttpPost\]\|\[HttpPut\]\|\[HttpPatch\]\|\[HttpDelete\]" src/Services/{service}/ --include="*.cs" -l
# Event consumers / background jobs
grep -r "IConsumer\|EventHandler\|IMessageConsumer\|BackgroundJob\|IHostedService" src/Services/{service}/ --include="*.cs" -l
# Read-side: CQRS query handlers
grep -r "IQueryHandler\|QueryHandler\b" src/Services/{service}/ --include="*.cs" -l
# Read-side: REST GET endpoints
grep -r "\[HttpGet\]" src/Services/{service}/ --include="*.cs" -l
Count: N (write) + M (read) + K (event/background) = minimum TC count. If minimum > 20: split into operation-group batches (≤20 ops each per task tracking). NEVER generate all TCs in one pass for large features.
Actor Catalog Discovery (MANDATORY — feeds authorization TCs):
# Permission attributes and role guards
grep -r "\[Authorize\]\|RequirePermission\|IsInRole\|HasPermission" src/Services/{service}/ --include="*.cs" -n | head -30
# Role/permission enums
grep -r "enum.*Role\|enum.*Permission" src/Services/{service}/ --include="*.cs" -n | head -20
Build actor catalog: [Role1, Role2,...]. Authorization TC minimum = actor count × 2 (authorized succeeds + unauthorized rejected). Every actor MUST appear in ≥1 authorization TC.
grep -r "class.*Command.*:" src/Services/{service}/Update mode (post-change / post-bugfix / post-PR):
[BLOCKING]: Run Use Case Inventory on full module BEFORE git diff. Check existing TC count in Section 15.
# Write-side
grep -r "ICommandHandler\|CommandHandler\b" src/Services/{service}/ --include="*.cs" -l
grep -r "\[HttpPost\]\|\[HttpPut\]\|\[HttpPatch\]\|\[HttpDelete\]" src/Services/{service}/ --include="*.cs" -l
grep -r "IConsumer\|EventHandler\|IMessageConsumer\|BackgroundJob\|IHostedService" src/Services/{service}/ --include="*.cs" -l
# Read-side
grep -r "IQueryHandler\|QueryHandler\b" src/Services/{service}/ --include="*.cs" -l
grep -r "\[HttpGet\]" src/Services/{service}/ --include="*.cs" -l
"Pre-existing gap: {existing}/{minimum} TCs". Generate gap-filling TCs in addition to update-triggered TCs.git diff or git diff main...HEAD (for PRs) — find code changes since last TC updateTC-ORD-040: Regression — order total calculation bypass)[REQUIRED] Spec-Wrong? Decision Gate (UPDATE mode only)
Before updating TCs to match the current code, determine: Did the code drift from the spec, or was the spec wrong?
Scenario Signal Action Code was wrong (spec described correct behavior) Bug was fixed; spec + TCs describe what SHOULD happen Proceed — update TCs only if code now matches spec. If code still differs, the fix is incomplete. Spec was wrong (code implements correct behavior that spec misdescribed) Spec described behavior that never worked correctly; the “fix” is actually a clarification STOP — do NOT update TCs yet. First: run $spec-discovery [update]to correct the engineering spec. Then: run$feature-docs [update]on affected sections (Section 3, 4, 5 — business rules, user journeys, API contracts). THEN return here to update TCs.Behavior is a new requirement (neither spec nor code was wrong before) Feature change approved; both spec and TCs need updating Update feature doc Section 3/4 first (new behavior description), then update TCs here. Uncertain Cannot determine without stakeholder input Escalate: document the ambiguity in this session’s summary. Write TCs in both GIVEN old behaviorandGIVEN new behaviorvariants with[PENDING REVIEW]tag.Checkpoint: Answer this question before proceeding: “Is the code change intentional and approved?” If yes, update TCs. If no (regression), the code needs fixing — do not update TCs to document broken behavior.
docs/specs/ dashboard[RECOMMENDED] After updating TCs for the target feature, scan for other features whose TCs may be invalidated by the same code change.
Run these greps against docs/business-features/:
# 1. Find API endpoint references in other feature docs
grep -rl "{endpoint}" docs/business-features/ | grep -v "{current-module}"
# Replace {endpoint} with the main API path changed (e.g., /api/employees, /api/invitations)
# 2. Find entity references in other feature docs
grep -rl "{entity-name}" docs/business-features/ | grep -v "{current-module}"
# Replace {entity-name} with key domain entities changed (e.g., Employee, Invitation)
# 3. Find event references in other feature docs
grep -rl "{event-name}" docs/business-features/ | grep -v "{current-module}"
# Replace {event-name} with events fired by the changed code
Output: List of potentially affected feature docs. For each hit:
Summary format for watzup/session end:
TC Blast Radius Analysis:
- Changed: {current-feature} ({N} TCs updated)
- Potentially affected: {module-A} (references {entity/endpoint})
- Potentially affected: {module-B} (references {entity/endpoint})
- Action needed: Review TCs in affected modules before next release
Skip when:
Sync mode (bidirectional reconciliation):
docs/specs/{Module}/README.md TCssrc/Services/{service}*.IntegrationTests/| TC ID | In Feature Doc? | In specs/? | In Test Code? | Action Needed |
|-------|----------------|------------|---------------|---------------|
| TC-FEAT-001 | ✅ | ✅ | ✅ | None |
| TC-FEAT-025 | ✅ | ❌ | ✅ | Add to specs/ |
| TC-FEAT-030 | ❌ | ✅ | ❌ | Add to feature doc |
From-integration-tests mode (reverse-engineer specs from existing tests):
[Trait("TestSpec", "TC-...")] in target test project[BLOCKING] Do NOT start Phase 3 until all rows in this table show PASS:
| Gate | Check | Required | Actual | Status |
|---|---|---|---|---|
| Write-op coverage | TC count for CRUD/write ops | ≥ N (write ops from inventory) | {n} | PASS/FAIL |
| Read-op coverage | TC count for query/view ops | ≥ M (read ops from inventory) | {n} | PASS/FAIL |
| Event/job coverage | TC count for events + background jobs | ≥ K (event/job count) | {n} | PASS/FAIL |
| Permission coverage | TC count for authorization | ≥ actor_count × 2 | {n} | PASS/FAIL |
| Total floor | Total planned TCs | ≥ N + M + K (Grand Total) | {n} | PASS/FAIL |
FAIL action: task tracking for each FAIL row — list specific missing TC categories. NEVER proceed to Phase 3 until all gates PASS.
Operation group decomposition: If Grand Total > 20, split TC generation into batches of ≤20 related operations:
Task tracking: "Generate CRUD TCs for {feature} — ops {1-N}: {CommandA}, {CommandB}, {CommandC}"
Task tracking: "Generate Read TCs for {feature} — ops {1-M}: {QueryA}, {QueryB}"
Task tracking: "Generate Event TCs for {feature} — ops {1-K}: {EventConsumerA}, {BackgroundJobA}"
Task tracking: "Generate Permission TCs for {feature} — actors: {Role1}, {Role2}"
Task tracking: "Generate Edge Case TCs for {feature} — boundary conditions from inventory"
Each batch task completes before starting the next. Final ask the user directly review covers all batches together.
| TC ID | Name | Priority | Category | Status |
|-------|------|----------|----------|--------|
| TC-ORD-037 | Create order with multiple line items | P0 | CRUD | New |
| TC-ORD-038 | Reject order without required fields | P1 | Validation | New |
| TC-ORD-039 | Unauthenticated user cannot access orders | P0 | Permission | New |
Question: "These {N} test cases cover {feature}. Review the list:
[Coverage context: Use Case Inventory found {total_ops} total operations ({write_ops} write, {read_ops} read, {event_ops} event/background). {N} TCs planned = {coverage_pct}% operation coverage.]"
Options:
- "Approve as-is (Recommended)" — Proceed to writing
- "Add missing scenario" — Describe what's missing
- "Adjust priorities" — Change P0/P1/P2 assignments
- "Regenerate" — Re-analyze and try again
Coverage context calculation: coverage_pct = (N / total_ops) × 100. If coverage_pct < 80%: flag ⚠️ Coverage below 80% threshold and suggest adding TCs before approving.
Canonical write — feature docs own TCs. NEVER overwrite existing TCs.
Edit tool to upsertTC format (from tdd-spec-template.md):
#### TC-{FEATURE}-{NNN}: {Descriptive Test Name} [{Priority}]
**Objective:** {What this test verifies}
**Preconditions:**
- {Setup requirement}
**Test Steps:**
\`\`\`gherkin
Given {initial state}
And {additional context}
When {action}
Then {expected outcome}
And {additional verification}
\`\`\`
**Acceptance Criteria:**
- ✅ {Success behavior}
- ❌ {Failure behavior}
**Test Data:**
\`\`\`json
{ "field": "value" }
\`\`\`
**Edge Cases:**
- {Boundary condition}
**Evidence:** `{FilePath}:{LineRange}` or `TBD (pre-implementation)`
Evidence rules by mode:
Evidence: TBD (pre-implementation) — will be updated after implementationEvidence: {actual file}:{actual lines} — trace to real codeIf docs/specs/{Module}/README.md exists:
$integration-test)PRIORITY-INDEX.md with new TC entries in correct priority tierSkip if user says "skip dashboard" or no docs/specs/ file exists for module.
Based on mode, suggest via a direct user question:
TDD-first:
1. "$tdd-spec-review — Validate TC quality before generating tests (Recommended)"
2. "$integration-test — Generate test stubs from these TCs (skip review)"
3. "$plan-hard — Plan the feature implementation"
4. "Done for now — I'll implement later"
Implement-first:
1. "$tdd-spec-review — Validate TC quality before generating tests (Recommended)"
2. "$integration-test — Generate integration tests (skip review)"
3. "$workflow-review-changes — Review all changes"
4. "Done for now"
Update (post-change/PR):
1. "$tdd-spec-review — Validate updated TCs before regenerating tests (Recommended)"
2. "$integration-test — Generate/update tests for changed TCs (skip review)"
3. "$test — Run existing tests to verify coverage"
4. "$tdd-spec [direction=sync] — Sync dashboard with updated TCs"
5. "Done for now"
Sync:
1. "$tdd-spec [direction=sync] — Sync dashboard after reconciliation (Recommended)"
2. "$integration-test — Generate tests for any TCs missing test coverage"
3. "Done for now"
From-integration-tests:
1. "$tdd-spec [direction=sync] — Sync dashboard with newly documented TCs (Recommended)"
2. "$test — Run tests to verify all documented TCs pass"
3. "Done for now"
[BLOCKING] Before assigning any TC ID: Read all existing TC IDs in the feature doc's Section 15. Find the next available decade slot.
| NNN Range | Category |
|---|---|
| 001–009 | CRUD / Core operations (P0-P1) |
| 011–019 | Validation / Business rules (P1-P2) |
| 021–029 | Authorization / Permissions (P0-P1) |
| 031–039 | Events / Background jobs (P1-P2) |
| 041–049 | Cross-service / Integration (P1-P2) — See SYNC:cross-service-check above for full boundary scan checklist before writing these TCs |
| 051–059 | Edge cases / Error scenarios (P2-P3) |
| 061–069 | UI / User journey flows (P2-P3) |
| 071–099 | Reserved for feature-specific groups |
Collision prevention:
TC-{FEAT}- to list all existing IDsAuthoritative reference:
.claude/skills/shared/tc-format.md— Decade-Based Numbering section
When feature behavior removed or significantly changed:
[DEPRECATED: {YYYY-MM-DD} — {reason}] to title**Status:** → DeprecatedTC-{ID} deprecated — {reason}[Obsolete("TC deprecated: {reason}")] attribute and skip test$tdd-spec [direction=sync]) auto-handles deprecated TCs in QA dashboardExample:
#### TC-USR-021: User Can View Profile [P1] [DEPRECATED: 2026-04-21 — Field removed per privacy policy]
**Status:** Deprecated
docs/specs/ as the primary destination (use feature docs Section 15)TC-{SVC}-{NNN} or TC-{SVC}-{FEATURE}-{NNN} format (use unified TC-{FEATURE}-{NNN})TBD)tdd-spec-review — TC quality review (use AFTER this skill to validate TC coverage and correctness)tdd-spec [direction=sync] — Native dashboard sync mode (aggregates TCs from feature docs to docs/specs/ — replaces test-specs-docs)integration-test — Integration test code generator (use AFTER this skill to generate test stubs)feature-docs — Feature doc creator (creates the Section 15 that this skill populates)refine — PBI refinement (feeds acceptance criteria into this skill's TDD-first mode)Triggered when: "sync test specs", "update dashboard", "sync to feature docs", "reverse sync", "full sync", or [direction=sync|forward|reverse|full].
Engineering specs live at
docs/specs/{app-bucket}/{system-name}/. This mode manages ONLY QA dashboard atdocs/specs/{Module}/. NEVER sync engineering specs here — maintained byworkflow-spec-driven-dev.
| Trigger phrase | Direction | Behavior |
|---|---|---|
"sync test specs" / "update dashboard" / direction=sync / direction=forward | Forward | Feature docs → docs/specs/ dashboard |
"sync to feature docs" / "reverse sync" / direction=reverse | Reverse | docs/specs/ → feature docs Section 15 |
"full sync" / "bidirectional" / direction=full | Full | Both directions sequentially |
Default (no direction specified): forward.
[BLOCKING] Scan all TCs in module and flag:
Evidence = TBD AND Status = Tested (contradiction)Produce quality report alongside sync output. Do NOT block sync — surface gaps and continue.
TC-{FEAT}-{NNN} entries from feature doc Section 15 (canonical source)docs/specs/{Module}/README.md — extract existing TC IDs[REQUIRED] IntegrationTest field in dashboard rows:
When writing or updating TC rows in the QA dashboard, always populate the
IntegrationTest:field with the traceability link format:IntegrationTest: {TestProject}::{TestClass}::{TestMethodName}If no integration test exists yet for this TC, write:
IntegrationTest: (not yet implemented — run $integration-test [from-prompt] TC-{FEATURE}-{NNN})This creates a navigable link from the QA dashboard directly to the test code, and a TODO marker for TCs lacking test coverage. The "not yet implemented" text is detectable by tools scanning for coverage gaps.
Also add to dashboard header block:
| Related Feature Doc | [docs/business-features/{Module}/README.md](../../business-features/{Module}/README.md) | | Engineering Spec | [docs/specs/{app-bucket}/{system-name}/](../{app-bucket}/{system-name}/) |
docs/specs/{Module}/README.md:
last_synced: YYYY-MM-DD
last_synced_source: docs/business-features/{Module}/detailed-features/README.{FeatureName}.md
tc_count: N
PRIORITY-INDEX.md — add/update TCs in appropriate priority sectiondocs/specs/README.md links to moduledocs/specs/{Module}/README.mdTC orphaned when exists in docs/specs/{Module}/README.md but NOT in feature doc Section 15.
orphans = dashboard_ids - feature_doc_ids⚠ Orphaned TCs detected: {count} TCs in dashboard have no canonical source### Quarantined TCs subsection in dashboard (NEVER delete)<!-- Orphaned {date}: no matching TC in feature docs Section 15 -->[DEPRECATED] in title → silently remove from dashboardDrift detection: git log --since={last_synced} shows changes → flag stale before proceeding.
git log --since={last_synced} -- docs/business-features/{Module}/detailed-features/README.{FeatureName}.md
Non-empty output → warn: ⚠ Source feature doc changed since last sync on {last_synced}. Proceeding with forward sync.
[BLOCKING] NOT in a workflow? a direct user question — do NOT decide complexity yourself. User decides:
pbi-to-testsworkflow (Recommended) — tdd-spec → tdd-spec-review → quality-gate → workflow-end$tdd-specdirectly — standalone
[BLOCKING] After completing, a direct user question — do NOT skip:
| Skill | Relationship | When to Call |
|---|---|---|
$spec-discovery | Upstream spec — engineering spec bundle is the source of truth for domain model | When TCs reveal implementation doesn’t match spec-discovery output: run spec-discovery audit/update |
$feature-docs | TC host — Section 15 is where TCs live; feature-docs creates/updates the doc structure | Before calling tdd-spec, feature doc must exist; run $feature-docs if missing |
$tdd-spec-review | Reviewer — audits TC coverage, GIVEN/WHEN/THEN quality, no duplicates | Always call after tdd-spec (CREATE or UPDATE) — never ship TCs without review |
$integration-test | Consumer — generates test code from TCs | After tdd-spec + review, integration-test converts TCs to .cs test files |
$tdd-spec [direction=sync] | Self (sync mode) — syncs QA dashboard from Section 15 | Always call after tdd-spec UPDATE; syncs docs/specs/{Module}/README.md |
$docs-update | Orchestrator — calls tdd-spec as Phase 3 of doc sync chain | Run $docs-update for full automated sync (calls tdd-spec UPDATE + sync internally) |
When called outside a workflow, follow this chain. Each step is required unless marked [RECOMMENDED].
tdd-spec (you are here)
│
├─ PREREQUISITE:
│ [REQUIRED] feature-docs doc must exist at docs/business-features/{Module}/README.md
│ If not found → run $feature-docs init first
│
├─ CREATE mode (new feature):
│ tdd-spec CREATE → $tdd-spec-review → $tdd-spec [direction=sync] → $integration-test [from-prompt]
│
├─ UPDATE mode (code changed):
│ *** Spec-Wrong? Gate first (see above) ***
│ tdd-spec UPDATE → Step UPDATE-FINAL (Blast Radius) → $tdd-spec-review → $tdd-spec [direction=sync] → $integration-test [from-changes]
│
├─ [REQUIRED] → $tdd-spec-review
│ Always run after CREATE or UPDATE. Validates coverage and format.
│
├─ [REQUIRED] → $tdd-spec [direction=sync]
│ Always run after UPDATE to sync QA dashboard.
│
├─ [REQUIRED] → $integration-test [from-changes or from-prompt]
│ Generate/update integration test code for changed TCs.
│
└─ [RECOMMENDED] → $docs-update
For full chain including feature-docs (Phase 2) and spec-discovery (Phase 2.5).
Call when multiple doc layers may be stale.
When tdd-spec is called in REGRESSION mode (bugfix workflow):
Anti-pattern to avoid:
# WRONG: Documenting the bug as expected behavior
TC-REG-001: GIVEN payment processed WHEN amount > limit THEN allow (← this was the bug)
# RIGHT: Documenting the fix as expected behavior
TC-REG-001: GIVEN payment processed WHEN amount > limit THEN reject with PaymentLimitExceededException
AI Mistake Prevention — Failure modes to avoid on every task:
Check downstream references before deleting. Deleting components causes documentation and code staleness cascades. Map all referencing files before removal. Verify AI-generated content against actual code. AI hallucinates APIs, class names, and method signatures. Always grep to confirm existence before documenting or referencing. Trace full dependency chain after edits. Changing a definition misses downstream variables and consumers derived from it. Always trace the full chain. Trace ALL code paths when verifying correctness. Confirming code exists is not confirming it executes. Always trace early exits, error branches, and conditional skips — not just happy path. When debugging, ask "whose responsibility?" before fixing. Trace whether bug is in caller (wrong data) or callee (wrong handling). Fix at responsible layer — never patch symptom site. Assume existing values are intentional — ask WHY before changing. Before changing any constant, limit, flag, or pattern: read comments, check git blame, examine surrounding code. Verify ALL affected outputs, not just the first. Changes touching multiple stacks require verifying EVERY output. One green check is not all green checks. Holistic-first debugging — resist nearest-attention trap. When investigating any failure, list EVERY precondition first (config, env vars, DB names, endpoints, DI registrations, data preconditions), then verify each against evidence before forming any code-layer hypothesis. Surgical changes — apply the diff test. Bug fix: every changed line must trace directly to the bug. Don't restyle or improve adjacent code. Enhancement task: implement improvements AND announce them explicitly. Surface ambiguity before coding — don't pick silently. If request has multiple interpretations, present each with effort estimate and ask. Never assume all-records, file-based, or more complex path.
Rationalization Prevention — AI skips steps via these evasions. Recognize and reject:
Evasion Rebuttal "Too simple for a plan" Simple + wrong assumptions = wasted time. Plan anyway. "I'll test after" RED before GREEN. Write/verify test first. "Already searched" Show grep evidence with file:line. No proof = no search."Just do it" Still need task tracking. Skip depth, never skip tracking. "Just a small fix" Small fix in wrong location cascades. Verify file:line first. "Code is self-explanatory" Future readers need evidence trail. Document anyway. "Combine steps to save time" Combined steps dilute focus. Each step has distinct purpose.
Cross-Service Check — Microservices/event-driven: MANDATORY before concluding investigation, plan, spec, or feature doc. Missing downstream consumer = silent regression.
Boundary Grep terms Event producers Publish,Dispatch,Send,emit,EventBus,outbox,IntegrationEventEvent consumers Consumer,EventHandler,Subscribe,@EventListener,inboxSagas/orchestration Saga,ProcessManager,Choreography,Workflow,OrchestratorSync service calls HTTP/gRPC calls to/from other services Shared contracts OpenAPI spec, proto, shared DTO — flag breaking changes Data ownership Other service reads/writes same table/collection → Shared-DB anti-pattern Per touchpoint: owner service · message name · consumers · risk (NONE / ADDITIVE / BREAKING).
BLOCKED until: Producers scanned · Consumers scanned · Sagas checked · Contracts reviewed · Breaking-change risk flagged
Estimation Framework — Bottom-up first; SP DERIVED; output min-max range when likely ≥3d. Stack-agnostic. Baseline: 3-5yr dev, 6 productive hrs/day. AI estimate assumes Claude Code + project context.
Method:
- Blast Radius pass (below) — drives code AND test cost
- Decompose phases → hours/phase →
bottom_up_hours = Σ phase_hourslikely_days = ceil(bottom_up_hours / 6) × productivity_factor- Sum Risk Margin (base + add-ons) →
max_days = likely_days × (1 + margin)min_days = likely_days × 0.9- Output as range when
likely_days ≥3; single point allowed<3(still record margin)man_days_ai= same range × AI speedupstory_pointsDERIVED fromlikely_daysvia SP-Days — NEVER driver. Disagreement >50% → trust bottom-upProductivity factor: 0.8 strong scaffolding+codegen+AI hooks · 1.0 mature default · 1.2 weak patterns · 1.5 greenfield
Cost Driver Heuristic (apply BEFORE work-type row):
- UI dominates in CRUD/business apps — 1.5-3x backend (states, validation, responsive, a11y, polish)
- Backend dominates ONLY: multi-aggregate invariants, cross-service contracts, schema migrations, heavy query/perf, new event flows
Reuse-vs-Create axis (PRIMARY lever, per layer):
UI tier Cost Reuse component on existing screen 0.1-0.3d Add control/column to existing screen 0.3-0.8d Compose components into NEW screen 1-2d NEW screen, custom layout/states/validation 2-4d NEW shared/common component (themed, tested) 3-6d+
Backend tier Cost Reuse query/handler from new place 0.1-0.3d Small update existing handler/entity 0.3-0.8d NEW query on existing repo/model 0.5-1d NEW command/handler on existing aggregate (additive) 1-2d NEW aggregate/entity (repo, validation, events) 2-4d NEW cross-service contract OR schema migration 2-4d each Multi-aggregate invariant / heavy domain rule 3-5d Rule: Sum tiers across UI+backend+tests, apply productivity factor. Reuse short-circuits tiers — call out.
Test-Scope drivers (compute test_count EXPLICITLY — "+tests" hand-wave is #1 failure):
Driver Count Happy-path journeys 1 per story / AC main flow State-machine transitions reachable transitions × allowed actors Multi-entity state combos state(A) × state(B) — REACHABLE only, not Cartesian Authorization matrix (owner, non-owner, elevated, unauth) × each mutation Validation rules 1 per required field / boundary / format / cross-field UI states (per new screen/dialog) happy, loading, empty, error, partial — present only Negative paths / invariants 1 per violatable business rule
Test tier (Trad, incl. setup+assert+flake) Cost 1-5 cases, fixtures reused 0.3-0.5d 6-12 cases, 1 new fixture 0.5-1d 13-25 cases, multi-entity setup 1-2d 26-50 cases OR new state-machine coverage 2-3d >50 cases OR full E2E journey 3-5d Test multipliers: new fixture/seed harness +0.5d · cross-service/bus assertion +0.3d each · UI E2E ×1.5 · each new role +1-2 cases
Blast Radius (mandatory pre-pass — affects code AND test):
- Files/components directly modified — count
- Of those, "complex" (>500 LOC, multi-handler, central, frequently-modified) — count
- Downstream consumers (callers, event subscribers, cross-service) — list
- Shared/common code touched (multi-app blast) — yes/no
- Regression scope — areas needing re-test
Rule: Complex touch → add
risk_factors. Each downstream consumer → +1-3 regression cases. Blast >5 areas OR >2 complex → re-evaluate SPLIT before estimating.Risk Margin (drives max bound):
likely_days Base margin <1d trivial +10% 1-2d small additive +20% 3-4d real feature +35% 5-7d large +50% 8-10d very large +75% >10d +100% AND flag SHOULD SPLIT Risk-factor add-ons (additive — enumerate in
risk_factors):
Factor +margin touches-complex-existing-feature(>500 LOC, multi-handler, central)+20% cross-service-contractchange+25% schema-migration-on-populated-data+25% new-tech-or-unfamiliar-pattern+30% regression-fan-out(≥3 downstream areas re-test)+20% performance-or-latency-critical+20% concurrency-race-event-ordering+25% shared-common-code(multi-consumer/multi-app)+25% unclear-requirements-or-design+30% Collapse rule: total margin >100% → STOP, split (padding past 2x is dishonesty). Margin <15% on
likely_days ≥5→ under-estimated, widen.Work-Type Caps (hard ceilings on
likely_days):
Work type Max SP Max likely Single field / config flag / style fix 1 0.5d Add property to existing model + bind to existing UI 2 1d Additive endpoint + minor UI control (button/menu/column), reuses fixtures 3 2-3d Additive endpoint + NEW UI surface OR additive multi-layer + new domain rule + 2+ test files 5 3-5d NEW model/aggregate OR migration OR cross-module contract OR heavy test (>1.5d) OR NEW UI + non-trivial backend 8 5-7d NEW UI surface + (NEW aggregate OR migration OR cross-service contract) 13 SHOULD split Cross-service contract + migration combined 13 SHOULD split Beyond 21 MUST split SP→Days (validation only): 1=0.5d/0.25d · 2=1d/0.35d · 3=2d/0.65d · 5=4d/1.0d · 8=6d/1.5d · 13=10d/2.0d (Trad/AI likely) AI speedup: SP 1≈2x · 2-3≈3x · 5-8≈4x · 13+≈5x. AI cost =
(code_gen × 1.3) + (test_gen × 1.3)(30% review overhead).MANDATORY frontmatter:
story_points: <n> complexity: low | medium | high | critical man_days_traditional: '<min>-<max>d' # range when likely ≥3d; '<N>d' when <3d man_days_ai: '<min>-<max>d' risk_margin_pct: <n> # base + add-ons risk_factors: [touches-complex-existing-feature, regression-fan-out] # closed-list from add-ons; [] if none blast_radius: touched_areas: <n> complex_touched: <n> downstream_consumers: [list or count] shared_common_code: yes | no estimate_scope_included: [code, integration-tests, frontend, i18n, docs] estimate_scope_excluded: [unit-tests, e2e, perf, deployment, code-review-rounds] estimate_reasoning: | 5-7 lines covering: (a) UI tier — row applied (b) Backend tier — row applied (c) Test scope — case breakdown by driver, file count, fixtures, tier row (d) Cost driver — dominant tier + why (e) Blast radius — touched, complex, regression scope (f) Risk factors — list driving margin; why not larger/smaller Example: "UI: compose Form/Table/Dialog → NEW screen (~1.5d). Backend: NEW command on existing aggregate, reuses validation+repo (~1d). Tests: 4 transitions × 2 actors + 3 validation + 2 UI states = 13 cases, 1 new fixture → tier 13-25 ~1.5d. Driver: UI composition + new states. Blast: 4 areas, 1 complex. Risk: base 35% + touches-complex +20% = 55% → max 3.9d → range 2.5-4d."Sanity self-check:
likely_days ≥3dand single-point? → reject, must be range- Margin <15% on
likely_days ≥5d? → under-estimated, widen- Margin >100%? → STOP, split instead of buffer
- Complex existing feature touched, no regression budget in
(c)? → reject- Blast
>5areas OR>2complex, no split discussion? → reject- Purely additive on existing model AND existing UI? → cap SP 3 unless tests >1.5d
- NEW UI surface (page/complex form/dashboard)? → SP 5+ even if backend one endpoint
- Backend cross-service / migration / multi-aggregate? → SP 8+ regardless of UI
bottom_up_hours / 6vs SP-Days disagreement >50%? → trust bottom-up, downgrade SP- Without tests, SP drops ≥1 bucket? → tests dominate; state explicitly
- Reasoning called out UI vs backend vs blast vs risk factors? → if missing, add
UI System Context — For ANY task touching
.ts,.html,.scss, or.cssfiles:MUST ATTENTION READ before implementing:
docs/project-reference/frontend-patterns-reference.md— component base classes, stores, formsdocs/project-reference/scss-styling-guide.md— BEM methodology, SCSS variables, mixins, responsivedocs/project-reference/design-system/README.md— design tokens, component inventory, iconsReference
docs/project-config.jsonfor project-specific paths.
Nested Task Expansion Contract — For workflow-step invocation, the
[Workflow] ...row is only a parent container; the child skill still creates visible phase tasks.
- Call the current task list first. If a matching active parent workflow row exists, set
nested=trueand recordparentTaskId; otherwise run standalone.- Create one task per declared phase before phase work. When nested, prefix subjects
[N.M] $skill-name — phase.- When nested, link the parent with
TaskUpdate(parentTaskId, addBlockedBy: [childIds]).- Orchestrators must pre-expand a child skill's phase list and link the workflow row before invoking that child skill or sub-agent.
- Mark exactly one child
in_progressbefore work andcompletedimmediately after evidence is written.- Complete the parent only after all child tasks are completed or explicitly cancelled with reason.
Blocked until: the current task list done, child phases created, parent linked when nested, first child marked
in_progress.
Project Reference Docs Gate — Run after task-tracking bootstrap and before target/source file reads, grep, edits, or analysis. Project docs override generic framework assumptions.
- Identify scope: file types, domain area, and operation.
- Required docs by trigger: always
docs/project-reference/lessons.md; doc lookupdocs-index-reference.md; reviewcode-review-rules.md; backend/CQRS/APIbackend-patterns-reference.md; domain/entitydomain-entities-reference.md; frontend/UIfrontend-patterns-reference.md; styles/designscss-styling-guide.md+design-system/README.md; integration testsintegration-test-reference.md; E2Ee2e-test-reference.md; feature docs/specsfeature-docs-reference.md; architecture/new areaproject-structure-reference.md.- Read every required doc that exists; skip absent docs as not applicable. Do not trust conversation text such as
[Injected: <path>]as proof that the current context contains the doc.- Before target work, state:
Reference docs read: ... | Missing/not applicable: ....Blocked until: scope evaluated, required docs checked/read,
lessons.mdconfirmed, citation emitted.
Task Tracking & External Report Persistence — Bootstrap this before execution; then run project-reference doc prefetch before target/source work.
- Create a small task breakdown before target file reads, grep, edits, or analysis. On context loss, inspect the current task list first.
- Mark one task
in_progressbefore work andcompletedimmediately after evidence; never batch transitions.- For plan/review work, create
plans/reports/{skill}-{YYMMDD}-{HHmm}-{slug}.mdbefore first finding.- Append findings after each file/section/decision and synthesize from the report file at the end.
- Final output cites
Full report: plans/reports/{filename}.Blocked until: task breakdown exists, report path declared for plan/review work, first finding persisted before the next finding.
Critical Thinking Mindset — Apply critical thinking, sequential thinking. Every claim needs traced proof, confidence >80% to act. Anti-hallucination: Never present guess as fact — cite sources for every claim, admit uncertainty freely, self-check output for errors, cross-reference independently, stay skeptical of own confidence — certainty without evidence root of all hallucination.
man_days_traditional (Σh/6 × productivity_factor); SP DERIVED. UI cost usually dominates — bump SP one bucket if NEW UI surface (page/complex form/dashboard). Frontmatter MUST include story_points, complexity, man_days_traditional, man_days_ai, estimate_scope_included, estimate_scope_excluded, estimate_reasoning (UI vs backend cost driver). Cap SP 3 for additive-on-existing-model+existing-UI unless test scope >1.5d. SP 13 SHOULD split, SP 21 MUST split.
IMPORTANT MUST ATTENTION NEVER skip steps via "too simple" or "already searched" evasions — plan anyway, test first, show grep evidence.
IMPORTANT MUST ATTENTION cite file:line evidence for every claim. Confidence >80% to act, <60% do NOT recommend.
IMPORTANT MUST ATTENTION check error handling, logging, security, performance, observability across changed files.
IMPORTANT MUST ATTENTION read frontend-patterns-reference, scss-styling-guide, design-system/README before any UI change.
MUST ATTENTION apply critical thinking — every claim needs traced proof, confidence >80% to act. Anti-hallucination: never present guess as fact.
MUST ATTENTION apply AI mistake prevention — holistic-first debugging, fix at responsible layer, surface ambiguity before coding, re-read files after compaction.
plans/reports/ incrementally and synthesize from disk.Reference docs read: ....lessons.md; project conventions override generic defaults.[N.M] $skill-name — phase prefixes and one-in_progress discipline.IMPORTANT MUST ATTENTION follow declared step order for this skill; NEVER skip, reorder, or merge steps without explicit user approval
IMPORTANT MUST ATTENTION for every step/sub-skill call: set in_progress before execution, set completed after execution
IMPORTANT MUST ATTENTION every skipped step MUST include explicit reason; every completed step MUST include concise evidence
IMPORTANT MUST ATTENTION if Task tools unavailable, maintain an equivalent step-by-step plan tracker with synchronized statuses
[BLOCKING] task tracking — break ALL work into small tasks BEFORE starting. [BLOCKING] a direct user question — validate decisions with user. NEVER auto-decide. [REQUIRED] Add final review todo task to verify work quality. [BLOCKING] READ reference files before starting.
IMPORTANT MUST ATTENTION NEVER write TCs to docs/specs/ as primary destination — Section 15 is canonical.
IMPORTANT MUST ATTENTION NEVER generate TCs without reading existing Section 15 — ID collisions corrupt registry.
IMPORTANT MUST ATTENTION run Spec-Wrong? Gate in UPDATE mode — NEVER update TCs to document broken behavior.
IMPORTANT MUST ATTENTION NEVER skip interactive review (a direct user question) — user must approve TC list before writing.
IMPORTANT MUST ATTENTION authorization TCs are MANDATORY — every role must appear in ≥1 authorization TC.
Source: .claude/hooks/lib/prompt-injections.cjs + .claude/.ck.json
$workflow-start <workflowId> for standard; sequence custom steps manually[CRITICAL] Hard-won project debugging/architecture rules. MUST ATTENTION apply BEFORE forming hypothesis or writing code.
Goal: Prevent recurrence of known failure patterns — debugging, architecture, naming, AI orchestration, environment.
Top Rules (apply always):
ExecuteInjectScopedAsync for parallel async + repo/UoW — NEVER ExecuteUowTaskwhere python/where py) — NEVER assume python/python3 resolvesExecuteInjectScopedAsync, NEVER ExecuteUowTask. ExecuteUowTask creates new UoW but reuses outer DI scope (same DbContext) — parallel iterations sharing non-thread-safe DbContext silently corrupt data. ExecuteInjectScopedAsync creates new UoW + new DI scope (fresh repo per iteration).AccountUserEntityEventBusMessage = Accounts owns). Core services (Accounts, Communication) are leaders. Feature services (Growth, Talents) sending to core MUST use {CoreServiceName}...RequestBusMessage — never define own event for core to consume.HrManagerOrHrOrPayrollHrOperationsPolicy names set members, not what it guards. Add role → rename = broken abstraction. Rule: names express DOES/GUARDS, not CONTAINS. Test: adding/removing member forces rename? YES = content-driven = bad → rename to purpose (e.g., HrOperationsAccessPolicy). Nuance: "Or" fine in behavioral idioms (FirstOrDefault, SuccessOrThrow) — expresses HAPPENS, not membership.python/python3 resolves — verify alias first. Python may not be in bash PATH under those names. Check: where python / where py. Prefer py (Windows Python Launcher) for one-liners, node if JS alternative exists.Test-specific lessons →
docs/project-reference/integration-test-reference.mdLessons Learned section. Production-code anti-patterns →docs/project-reference/backend-patterns-reference.mdAnti-Patterns section. Generic debugging/refactoring reminders → System Lessons in.claude/hooks/lib/prompt-injections.cjs.
ExecuteInjectScopedAsync, NEVER ExecuteUowTask (shared DbContext = silent data corruption){CoreServiceName}...RequestBusMessagepython/python3 resolves — run where python/where py first, use py launcher or nodeBreak work into small tasks (task tracking) before starting. Add final task: "Analyze AI mistakes & lessons learned".
Extract lessons — ROOT CAUSE ONLY, not symptom fixes:
$learn.$code-review/$code-simplifier/$security/$lint catch this?" — Yes → improve review skill instead.$learn.
[TASK-PLANNING] [MANDATORY] BEFORE executing any workflow or skill step, create/update task tracking for all planned steps, then keep it synchronized as each step starts/completes.