[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71E33K7JRF6XPW34R1FC8ZF":3,"skill-same:01M71E33K7JRF6XPW34R1FC8ZF":76},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":41,"linkOnly":42,"markdownContent":43,"markdownBody":44,"frontMatter":45,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":50,"repositoryHtmlUrl":51,"repositoryHomepageUrl":6,"ownerHtmlUrl":52,"ownerBlogUrl":53,"ownerDescription":54,"updatedAt":55,"install":56,"resources":69},"01M71E33K7JRF6XPW34R1FC8ZF","tdd",null,"Enforce test-driven development with RED→GREEN→REFACTOR cycle and coverage validation","indigoai-us\u002Fhq-core","indigoai-us","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F122242446?v=4","01M71DTQ5NGD10GT1Z7E6XKWC5","HQ","01M71DTQ6BKSYYBNC9RAKT3YDK",94,"MIT","https:\u002F\u002Fgithub.com\u002Findigoai-us\u002Fhq-core\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftdd\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000007","代码审查","SCENARIO","使用场景",[5,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],"refactor","driven","red","grep","validation","test","with","enforce","development","edit","write","read","Bash","cycle","green","test-driven","coverage","2026-11-10 10:12:30",false,"---\nname: tdd\ndescription: Enforce test-driven development with RED→GREEN→REFACTOR cycle and coverage validation\nallowed-tools: Read, Write, Edit, Bash, Glob, Grep\n---\n\n# \u002Ftdd - Test-Driven Development Workflow\n\nDevelop a feature using strict test-driven development: write failing tests first, implement minimal code, refactor, and verify coverage.\n\n**What a good test is:** tests verify behavior through public interfaces, read like a specification, and survive refactors.\n\n**Task description:** $ARGUMENTS\n\n## TDD Cycle (MANDATORY)\n\n```\nRED → GREEN → REFACTOR → REPEAT\n```\n\n1. **RED**: Write a failing test FIRST (verify test fails before implementation)\n2. **GREEN**: Write minimal code to pass the test (no over-engineering)\n3. **REFACTOR**: Improve code quality while keeping tests green\n4. **REPEAT**: Continue until feature is complete and coverage meets requirements\n\n---\n\n## Seams — where tests go\n\nA **seam** is the public boundary you test at: the interface where you observe behavior without reaching inside. Tests live at seams, never against internals.\n\n**Test only at pre-agreed seams.** Before writing any test, write down the seams under test and confirm them with the user. No test is written at an unconfirmed seam. You can't test everything — agreeing the seams up front is how testing effort lands on the critical paths and complex logic instead of every edge case.\n\nAsk: \"What's the public interface, and which seams should we test?\" Give each proposed seam a one-line note on what it catches and what it misses.\n\n---\n\n## Process\n\n### Step 1: Framework Detection & Setup\n\nAuto-detect the test framework and package manager from the project:\n\n**Package managers** (check in priority order):\n- `bun.lockb` → `bun test`\n- `pnpm-lock.yaml` → `pnpm test`\n- `yarn.lock` → `yarn test`\n- `package-lock.json` → `npm test`\n- `Cargo.lock` → `cargo test`\n- `go.mod` → `go test .\u002F...`\n\n**Test frameworks** (infer from project files):\n- `package.json` with `jest` → Jest (Node\u002FTypeScript)\n- `package.json` with `vitest` → Vitest (Vite-based)\n- `pyproject.toml` or `requirements.txt` → pytest (Python)\n- `go.mod` → Go's `testing` package\n- `Cargo.toml` → Rust's built-in test framework\n\n**If no framework detected:** Ask the user which test framework and runner to use. Do not proceed without a confirmed test runner.\n\n**Store the detected runner** as `{TEST_CMD}` (e.g., `bun test`, `pnpm test`, `pytest`) and use it for all subsequent test commands in this workflow.\n\n**Report detected framework and package manager to the user before proceeding.**\n\n### Step 2: Define Interfaces (Scaffold)\n\nCreate the function\u002Fclass definition with empty implementation:\n\n- Write TypeScript interfaces (or equivalent) for inputs and outputs\n- Define the function signature with placeholder implementation\n- Include JSDoc comments describing behavior\n\nExample (TypeScript):\n```typescript\n\u002F**\n * Validates an email address format.\n * @param email - The email string to validate\n * @returns true if email is valid, false otherwise\n * @throws Error if email is null\u002Fundefined\n *\u002F\nexport function validateEmail(email: string): boolean {\n  throw new Error('Not implemented');\n}\n```\n\n### Step 3: Write Failing Tests (RED Phase)\n\nRead `\u003Crepo>\u002FGLOSSARY.md` if present so test names and interface vocabulary match the project's domain language (ties into `\u002Fdomain-modeling`).\n\nWrite comprehensive test suite BEFORE implementation:\n\n**Test types to include:**\n- Happy path (valid input → expected output)\n- Edge cases (empty, null, undefined, boundary values, max length)\n- Error conditions (invalid formats, type errors)\n- Integration tests (API endpoints, database operations if applicable)\n\n**Requirements:**\n- Tests must FAIL before implementation\n- Each test should be independent (no shared state)\n- Use meaningful assertion messages\n- Run tests and **VERIFY RED status** (all fail as expected)\n\n**Example test structure (Jest\u002FVitest):**\n```typescript\ndescribe('validateEmail', () => {\n  describe('happy path', () => {\n    it('accepts valid email addresses', () => {\n      expect(validateEmail('user@example.com')).toBe(true);\n      expect(validateEmail('test.name+tag@domain.co.uk')).toBe(true);\n    });\n  });\n\n  describe('edge cases', () => {\n    it('rejects empty string', () => {\n      expect(validateEmail('')).toBe(false);\n    });\n\n    it('rejects email without @', () => {\n      expect(validateEmail('invalidemail.com')).toBe(false);\n    });\n\n    it('rejects email without domain', () => {\n      expect(validateEmail('user@')).toBe(false);\n    });\n\n    it('rejects email with spaces', () => {\n      expect(validateEmail('user @example.com')).toBe(false);\n    });\n\n    it('handles special characters', () => {\n      expect(validateEmail('user+tag@example.com')).toBe(true);\n      expect(validateEmail('user.name@sub.domain.com')).toBe(true);\n    });\n  });\n\n  describe('error conditions', () => {\n    it('throws error if email is null', () => {\n      expect(() => validateEmail(null as any)).toThrow();\n    });\n\n    it('throws error if email is undefined', () => {\n      expect(() => validateEmail(undefined as any)).toThrow();\n    });\n\n    it('rejects excessively long email', () => {\n      const longEmail = 'a'.repeat(255) + '@example.com';\n      expect(validateEmail(longEmail)).toBe(false);\n    });\n  });\n});\n```\n\n**Run tests and verify RED:**\n```bash\n{TEST_CMD}        # Use the detected test runner from Step 1\n# Expected: ALL tests FAIL (red output)\n# If ANY test passes, you haven't written the test correctly — fix it before proceeding\n```\n\n### Step 4: Implement Minimal Code (GREEN Phase)\n\nWrite **only the minimum code needed** to pass the tests:\n\n- No premature optimization\n- No extra features beyond test requirements\n- Focus on making tests pass\n- Keep code simple and readable\n\n**Example minimal implementation:**\n```typescript\nexport function validateEmail(email: string): boolean {\n  if (email === null || email === undefined) {\n    throw new Error('Email cannot be null or undefined');\n  }\n\n  if (email.length === 0 || email.length > 254) {\n    return false;\n  }\n\n  \u002F\u002F Basic email regex pattern\n  const emailRegex = \u002F^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\u002F;\n  return emailRegex.test(email);\n}\n```\n\n**Run tests and verify GREEN:**\n```bash\n{TEST_CMD}        # Use the detected test runner from Step 1\n# Expected: ALL tests PASS (green output)\n```\n\n### Step 5: Refactor (IMPROVE Phase)\n\nImprove code quality while keeping tests green:\n\n- Extract constants and magic strings\n- Improve variable\u002Ffunction names\n- Remove duplication\n- Optimize performance (if needed)\n- Add comments for complex logic\n\n**Requirements:**\n- Run tests after each refactoring step\n- Verify all tests still PASS\n- Refactoring should not add new functionality\n- Keep in-loop refactors small and local. For deeper **structural** refactors (moving seams, reshaping modules), hand off to `\u002Freview` rather than expanding this cycle.\n\n**Example refactored implementation:**\n```typescript\nconst EMAIL_MAX_LENGTH = 254;\nconst EMAIL_PATTERN = \u002F^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\u002F;\n\n\u002F**\n * Validates an email address format following RFC 5321 basic rules.\n * @param email - The email string to validate\n * @returns true if email matches expected format, false otherwise\n * @throws Error if email is null or undefined\n *\u002F\nexport function validateEmail(email: string): boolean {\n  if (email == null) {\n    throw new Error('Email cannot be null or undefined');\n  }\n\n  if (email.length === 0 || email.length > EMAIL_MAX_LENGTH) {\n    return false;\n  }\n\n  return EMAIL_PATTERN.test(email);\n}\n```\n\n**Run tests after EACH refactoring step:**\n```bash\n{TEST_CMD}        # Use the detected test runner from Step 1\n# Expected: ALL tests still PASS (green output)\n# Refactor one concern at a time. Stop when code is clean and readable.\n```\n\n### Step 6: Verify Coverage\n\nCheck code coverage and add tests for any uncovered paths:\n\n**Coverage requirements by code type:**\n\n| Code Type | Minimum Coverage |\n|-----------|------------------|\n| Standard application code | 80% |\n| Financial calculations | 100% |\n| Authentication\u002Fauthorization | 100% |\n| Security-critical code | 100% |\n| Encryption\u002Fdecryption | 100% |\n\n**Run coverage check:**\n```bash\n# Jest\nnpm test -- --coverage\n\n# Vitest\nnpx vitest run --coverage\n\n# pytest\npytest --cov=. --cov-report=term-missing\n\n# Go\ngo test -cover .\u002F...\n\n# Rust\ncargo tarpaulin --out Html\n```\n\n**Acceptance criteria:**\n- Lines covered: ≥ target percentage\n- Branches covered: ≥ target percentage\n- Functions covered: ≥ target percentage\n- Any uncovered lines documented with rationale (if intentional)\n\n**If coverage is below target:**\n1. Identify uncovered code paths\n2. Write additional tests for those paths\n3. Run tests again (verify GREEN)\n4. Re-check coverage\n\n---\n\n## Worked Example: Email Validator (Complete Walkthrough)\n\n### RED Phase Output\n\n```\n$ npm test\n\nFAIL  src\u002Femail-validator.test.ts\n  validateEmail\n    happy path\n      ✕ accepts valid email addresses (0ms)\n      ✕ accepts variation formats (1ms)\n    edge cases\n      ✕ rejects empty string (0ms)\n      ✕ rejects email without @ (1ms)\n      ✕ rejects email without domain (0ms)\n      ✕ rejects email with spaces (0ms)\n      ✕ handles special characters (1ms)\n    error conditions\n      ✕ throws error if email is null (0ms)\n      ✕ throws error if email is undefined (0ms)\n      ✕ rejects excessively long email (0ms)\n\nTests:       0 passed, 10 failed, 10 total\n```\n\n### GREEN Phase Output (After Implementation)\n\n```\n$ npm test\n\nPASS  src\u002Femail-validator.test.ts\n  validateEmail\n    happy path\n      ✓ accepts valid email addresses (2ms)\n      ✓ accepts variation formats (1ms)\n    edge cases\n      ✓ rejects empty string (0ms)\n      ✓ rejects email without @ (0ms)\n      ✓ rejects email without domain (1ms)\n      ✓ rejects email with spaces (0ms)\n      ✓ handles special characters (1ms)\n    error conditions\n      ✓ throws error if email is null (0ms)\n      ✓ throws error if email is undefined (0ms)\n      ✓ rejects excessively long email (0ms)\n\nTests:       10 passed, 10 total (18ms)\n```\n\n### Coverage Report (After Implementation & Refactoring)\n\n```\n$ npm test -- --coverage\n\n------------|----------|----------|----------|----------|-------------|\nFile        | % Stmts  | % Branch | % Funcs  | % Lines   | Uncovered   |\n------------|----------|----------|----------|----------|-------------|\nAll files   |   100    |   100    |   100    |   100     |             |\n email-...ts |   100    |   100    |   100    |   100     |             |\n------------|----------|----------|----------|----------|-------------|\n```\n\n---\n\n## Anti-Patterns to Avoid\n\n- **Testing implementation details**: Test behavior, not internal state\n- **Shared test state**: Each test must be independent (no `beforeAll` side effects)\n- **Insufficient assertions**: Verify specific outputs, not just \"no error\"\n- **Untested error paths**: Include tests for error conditions, not just happy path\n- **No mocking of external dependencies**: Mock API calls, database, file system, etc.\n- **Skipped tests**: Never commit `xit()` or `.skip` — fix the test or remove it\n- **Tautological**: The assertion recomputes the expected value the way the code does (`expect(add(a, b)).toBe(a + b)`, or a snapshot derived by hand the same way) — it passes by construction and can never disagree with the code. Expected values must come from an **independent source of truth** (a known-good literal, a worked example, the spec).\n- **Horizontal slicing**: Writing all tests first, then all implementation. Bulk tests verify *imagined* behavior and commit you to test structure before you understand the implementation. Work in **vertical slices** instead — one test → one implementation → repeat, each test a **tracer bullet** that responds to what the last cycle taught you.\n\n---\n\n## Tips for Success\n\n1. **Write tests first, always** — This forces you to think about the interface before implementation\n2. **Fail fast** — The RED phase should show clear test failures before coding\n3. **Minimal code** — The simplest code that passes tests is usually the best code\n4. **Refactor fearlessly** — Tests are your safety net; they prevent regressions\n5. **Coverage is a tool, not a goal** — 80% coverage is a checkpoint, not a target\n6. **Test the interface, not the implementation** — Users care about behavior, not how you achieve it\n\n---\n\n## Framework-Specific Commands\n\n### Jest (Node.js\u002FTypeScript)\n```bash\n# Run all tests\nnpm test\n\n# Run tests in watch mode\nnpm test -- --watch\n\n# Run coverage\nnpm test -- --coverage\n\n# Run specific test file\nnpm test email-validator.test.ts\n```\n\n### Vitest (Vite\u002FTypeScript)\n```bash\n# Run all tests\nnpx vitest run\n\n# Run tests in watch mode\nnpx vitest\n\n# Run coverage\nnpx vitest run --coverage\n\n# Run specific test file\nnpx vitest email-validator.test.ts\n```\n\n### pytest (Python)\n```bash\n# Run all tests\npytest\n\n# Run tests in watch mode\npytest --lf (runs last-failed)\n\n# Run coverage\npytest --cov=. --cov-report=term-missing\n\n# Run specific test file\npytest tests\u002Ftest_email_validator.py\n```\n\n### go test (Go)\n```bash\n# Run all tests\ngo test .\u002F...\n\n# Run with verbose output\ngo test -v .\u002F...\n\n# Run coverage\ngo test -cover .\u002F...\n\n# Run specific test\ngo test -run TestValidateEmail .\u002F...\n```\n\n### cargo test (Rust)\n```bash\n# Run all tests\ncargo test\n\n# Run tests in release mode\ncargo test --release\n\n# Run with coverage (requires tarpaulin)\ncargo tarpaulin --out Html\n\n# Run specific test\ncargo test validate_email\n```\n\n---\n\n## Success Checklist\n\nAfter completing the TDD workflow, verify:\n\n- [ ] Framework detected correctly\n- [ ] Tests written BEFORE implementation (RED phase confirmed)\n- [ ] All tests PASS (GREEN phase confirmed)\n- [ ] Code refactored for clarity and quality\n- [ ] Coverage meets requirements (80%+ standard, 100% for critical paths)\n- [ ] Test suite includes: happy path, edge cases, error conditions\n- [ ] No shared state between tests\n- [ ] Meaningful assertion messages\n- [ ] Code committed with comprehensive test suite\n\n## Upstream\n\nSeam and anti-pattern guidance adapted from [mattpocock\u002Fskills](https:\u002F\u002Fgithub.com\u002Fmattpocock\u002Fskills) (skills\u002Fengineering\u002Ftdd), synced to upstream commit f3fc563. HQ keeps its RED, GREEN, REFACTOR cycle and coverage gates.\n","# \u002Ftdd - Test-Driven Development Workflow\n\nDevelop a feature using strict test-driven development: write failing tests first, implement minimal code, refactor, and verify coverage.\n\n**What a good test is:** tests verify behavior through public interfaces, read like a specification, and survive refactors.\n\n**Task description:** $ARGUMENTS\n\n## TDD Cycle (MANDATORY)\n\n```\nRED → GREEN → REFACTOR → REPEAT\n```\n\n1. **RED**: Write a failing test FIRST (verify test fails before implementation)\n2. **GREEN**: Write minimal code to pass the test (no over-engineering)\n3. **REFACTOR**: Improve code quality while keeping tests green\n4. **REPEAT**: Continue until feature is complete and coverage meets requirements\n\n---\n\n## Seams — where tests go\n\nA **seam** is the public boundary you test at: the interface where you observe behavior without reaching inside. Tests live at seams, never against internals.\n\n**Test only at pre-agreed seams.** Before writing any test, write down the seams under test and confirm them with the user. No test is written at an unconfirmed seam. You can't test everything — agreeing the seams up front is how testing effort lands on the critical paths and complex logic instead of every edge case.\n\nAsk: \"What's the public interface, and which seams should we test?\" Give each proposed seam a one-line note on what it catches and what it misses.\n\n---\n\n## Process\n\n### Step 1: Framework Detection & Setup\n\nAuto-detect the test framework and package manager from the project:\n\n**Package managers** (check in priority order):\n- `bun.lockb` → `bun test`\n- `pnpm-lock.yaml` → `pnpm test`\n- `yarn.lock` → `yarn test`\n- `package-lock.json` → `npm test`\n- `Cargo.lock` → `cargo test`\n- `go.mod` → `go test .\u002F...`\n\n**Test frameworks** (infer from project files):\n- `package.json` with `jest` → Jest (Node\u002FTypeScript)\n- `package.json` with `vitest` → Vitest (Vite-based)\n- `pyproject.toml` or `requirements.txt` → pytest (Python)\n- `go.mod` → Go's `testing` package\n- `Cargo.toml` → Rust's built-in test framework\n\n**If no framework detected:** Ask the user which test framework and runner to use. Do not proceed without a confirmed test runner.\n\n**Store the detected runner** as `{TEST_CMD}` (e.g., `bun test`, `pnpm test`, `pytest`) and use it for all subsequent test commands in this workflow.\n\n**Report detected framework and package manager to the user before proceeding.**\n\n### Step 2: Define Interfaces (Scaffold)\n\nCreate the function\u002Fclass definition with empty implementation:\n\n- Write TypeScript interfaces (or equivalent) for inputs and outputs\n- Define the function signature with placeholder implementation\n- Include JSDoc comments describing behavior\n\nExample (TypeScript):\n```typescript\n\u002F**\n * Validates an email address format.\n * @param email - The email string to validate\n * @returns true if email is valid, false otherwise\n * @throws Error if email is null\u002Fundefined\n *\u002F\nexport function validateEmail(email: string): boolean {\n  throw new Error('Not implemented');\n}\n```\n\n### Step 3: Write Failing Tests (RED Phase)\n\nRead `\u003Crepo>\u002FGLOSSARY.md` if present so test names and interface vocabulary match the project's domain language (ties into `\u002Fdomain-modeling`).\n\nWrite comprehensive test suite BEFORE implementation:\n\n**Test types to include:**\n- Happy path (valid input → expected output)\n- Edge cases (empty, null, undefined, boundary values, max length)\n- Error conditions (invalid formats, type errors)\n- Integration tests (API endpoints, database operations if applicable)\n\n**Requirements:**\n- Tests must FAIL before implementation\n- Each test should be independent (no shared state)\n- Use meaningful assertion messages\n- Run tests and **VERIFY RED status** (all fail as expected)\n\n**Example test structure (Jest\u002FVitest):**\n```typescript\ndescribe('validateEmail', () => {\n  describe('happy path', () => {\n    it('accepts valid email addresses', () => {\n      expect(validateEmail('user@example.com')).toBe(true);\n      expect(validateEmail('test.name+tag@domain.co.uk')).toBe(true);\n    });\n  });\n\n  describe('edge cases', () => {\n    it('rejects empty string', () => {\n      expect(validateEmail('')).toBe(false);\n    });\n\n    it('rejects email without @', () => {\n      expect(validateEmail('invalidemail.com')).toBe(false);\n    });\n\n    it('rejects email without domain', () => {\n      expect(validateEmail('user@')).toBe(false);\n    });\n\n    it('rejects email with spaces', () => {\n      expect(validateEmail('user @example.com')).toBe(false);\n    });\n\n    it('handles special characters', () => {\n      expect(validateEmail('user+tag@example.com')).toBe(true);\n      expect(validateEmail('user.name@sub.domain.com')).toBe(true);\n    });\n  });\n\n  describe('error conditions', () => {\n    it('throws error if email is null', () => {\n      expect(() => validateEmail(null as any)).toThrow();\n    });\n\n    it('throws error if email is undefined', () => {\n      expect(() => validateEmail(undefined as any)).toThrow();\n    });\n\n    it('rejects excessively long email', () => {\n      const longEmail = 'a'.repeat(255) + '@example.com';\n      expect(validateEmail(longEmail)).toBe(false);\n    });\n  });\n});\n```\n\n**Run tests and verify RED:**\n```bash\n{TEST_CMD}        # Use the detected test runner from Step 1\n# Expected: ALL tests FAIL (red output)\n# If ANY test passes, you haven't written the test correctly — fix it before proceeding\n```\n\n### Step 4: Implement Minimal Code (GREEN Phase)\n\nWrite **only the minimum code needed** to pass the tests:\n\n- No premature optimization\n- No extra features beyond test requirements\n- Focus on making tests pass\n- Keep code simple and readable\n\n**Example minimal implementation:**\n```typescript\nexport function validateEmail(email: string): boolean {\n  if (email === null || email === undefined) {\n    throw new Error('Email cannot be null or undefined');\n  }\n\n  if (email.length === 0 || email.length > 254) {\n    return false;\n  }\n\n  \u002F\u002F Basic email regex pattern\n  const emailRegex = \u002F^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\u002F;\n  return emailRegex.test(email);\n}\n```\n\n**Run tests and verify GREEN:**\n```bash\n{TEST_CMD}        # Use the detected test runner from Step 1\n# Expected: ALL tests PASS (green output)\n```\n\n### Step 5: Refactor (IMPROVE Phase)\n\nImprove code quality while keeping tests green:\n\n- Extract constants and magic strings\n- Improve variable\u002Ffunction names\n- Remove duplication\n- Optimize performance (if needed)\n- Add comments for complex logic\n\n**Requirements:**\n- Run tests after each refactoring step\n- Verify all tests still PASS\n- Refactoring should not add new functionality\n- Keep in-loop refactors small and local. For deeper **structural** refactors (moving seams, reshaping modules), hand off to `\u002Freview` rather than expanding this cycle.\n\n**Example refactored implementation:**\n```typescript\nconst EMAIL_MAX_LENGTH = 254;\nconst EMAIL_PATTERN = \u002F^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\u002F;\n\n\u002F**\n * Validates an email address format following RFC 5321 basic rules.\n * @param email - The email string to validate\n * @returns true if email matches expected format, false otherwise\n * @throws Error if email is null or undefined\n *\u002F\nexport function validateEmail(email: string): boolean {\n  if (email == null) {\n    throw new Error('Email cannot be null or undefined');\n  }\n\n  if (email.length === 0 || email.length > EMAIL_MAX_LENGTH) {\n    return false;\n  }\n\n  return EMAIL_PATTERN.test(email);\n}\n```\n\n**Run tests after EACH refactoring step:**\n```bash\n{TEST_CMD}        # Use the detected test runner from Step 1\n# Expected: ALL tests still PASS (green output)\n# Refactor one concern at a time. Stop when code is clean and readable.\n```\n\n### Step 6: Verify Coverage\n\nCheck code coverage and add tests for any uncovered paths:\n\n**Coverage requirements by code type:**\n\n| Code Type | Minimum Coverage |\n|-----------|------------------|\n| Standard application code | 80% |\n| Financial calculations | 100% |\n| Authentication\u002Fauthorization | 100% |\n| Security-critical code | 100% |\n| Encryption\u002Fdecryption | 100% |\n\n**Run coverage check:**\n```bash\n# Jest\nnpm test -- --coverage\n\n# Vitest\nnpx vitest run --coverage\n\n# pytest\npytest --cov=. --cov-report=term-missing\n\n# Go\ngo test -cover .\u002F...\n\n# Rust\ncargo tarpaulin --out Html\n```\n\n**Acceptance criteria:**\n- Lines covered: ≥ target percentage\n- Branches covered: ≥ target percentage\n- Functions covered: ≥ target percentage\n- Any uncovered lines documented with rationale (if intentional)\n\n**If coverage is below target:**\n1. Identify uncovered code paths\n2. Write additional tests for those paths\n3. Run tests again (verify GREEN)\n4. Re-check coverage\n\n---\n\n## Worked Example: Email Validator (Complete Walkthrough)\n\n### RED Phase Output\n\n```\n$ npm test\n\nFAIL  src\u002Femail-validator.test.ts\n  validateEmail\n    happy path\n      ✕ accepts valid email addresses (0ms)\n      ✕ accepts variation formats (1ms)\n    edge cases\n      ✕ rejects empty string (0ms)\n      ✕ rejects email without @ (1ms)\n      ✕ rejects email without domain (0ms)\n      ✕ rejects email with spaces (0ms)\n      ✕ handles special characters (1ms)\n    error conditions\n      ✕ throws error if email is null (0ms)\n      ✕ throws error if email is undefined (0ms)\n      ✕ rejects excessively long email (0ms)\n\nTests:       0 passed, 10 failed, 10 total\n```\n\n### GREEN Phase Output (After Implementation)\n\n```\n$ npm test\n\nPASS  src\u002Femail-validator.test.ts\n  validateEmail\n    happy path\n      ✓ accepts valid email addresses (2ms)\n      ✓ accepts variation formats (1ms)\n    edge cases\n      ✓ rejects empty string (0ms)\n      ✓ rejects email without @ (0ms)\n      ✓ rejects email without domain (1ms)\n      ✓ rejects email with spaces (0ms)\n      ✓ handles special characters (1ms)\n    error conditions\n      ✓ throws error if email is null (0ms)\n      ✓ throws error if email is undefined (0ms)\n      ✓ rejects excessively long email (0ms)\n\nTests:       10 passed, 10 total (18ms)\n```\n\n### Coverage Report (After Implementation & Refactoring)\n\n```\n$ npm test -- --coverage\n\n------------|----------|----------|----------|----------|-------------|\nFile        | % Stmts  | % Branch | % Funcs  | % Lines   | Uncovered   |\n------------|----------|----------|----------|----------|-------------|\nAll files   |   100    |   100    |   100    |   100     |             |\n email-...ts |   100    |   100    |   100    |   100     |             |\n------------|----------|----------|----------|----------|-------------|\n```\n\n---\n\n## Anti-Patterns to Avoid\n\n- **Testing implementation details**: Test behavior, not internal state\n- **Shared test state**: Each test must be independent (no `beforeAll` side effects)\n- **Insufficient assertions**: Verify specific outputs, not just \"no error\"\n- **Untested error paths**: Include tests for error conditions, not just happy path\n- **No mocking of external dependencies**: Mock API calls, database, file system, etc.\n- **Skipped tests**: Never commit `xit()` or `.skip` — fix the test or remove it\n- **Tautological**: The assertion recomputes the expected value the way the code does (`expect(add(a, b)).toBe(a + b)`, or a snapshot derived by hand the same way) — it passes by construction and can never disagree with the code. Expected values must come from an **independent source of truth** (a known-good literal, a worked example, the spec).\n- **Horizontal slicing**: Writing all tests first, then all implementation. Bulk tests verify *imagined* behavior and commit you to test structure before you understand the implementation. Work in **vertical slices** instead — one test → one implementation → repeat, each test a **tracer bullet** that responds to what the last cycle taught you.\n\n---\n\n## Tips for Success\n\n1. **Write tests first, always** — This forces you to think about the interface before implementation\n2. **Fail fast** — The RED phase should show clear test failures before coding\n3. **Minimal code** — The simplest code that passes tests is usually the best code\n4. **Refactor fearlessly** — Tests are your safety net; they prevent regressions\n5. **Coverage is a tool, not a goal** — 80% coverage is a checkpoint, not a target\n6. **Test the interface, not the implementation** — Users care about behavior, not how you achieve it\n\n---\n\n## Framework-Specific Commands\n\n### Jest (Node.js\u002FTypeScript)\n```bash\n# Run all tests\nnpm test\n\n# Run tests in watch mode\nnpm test -- --watch\n\n# Run coverage\nnpm test -- --coverage\n\n# Run specific test file\nnpm test email-validator.test.ts\n```\n\n### Vitest (Vite\u002FTypeScript)\n```bash\n# Run all tests\nnpx vitest run\n\n# Run tests in watch mode\nnpx vitest\n\n# Run coverage\nnpx vitest run --coverage\n\n# Run specific test file\nnpx vitest email-validator.test.ts\n```\n\n### pytest (Python)\n```bash\n# Run all tests\npytest\n\n# Run tests in watch mode\npytest --lf (runs last-failed)\n\n# Run coverage\npytest --cov=. --cov-report=term-missing\n\n# Run specific test file\npytest tests\u002Ftest_email_validator.py\n```\n\n### go test (Go)\n```bash\n# Run all tests\ngo test .\u002F...\n\n# Run with verbose output\ngo test -v .\u002F...\n\n# Run coverage\ngo test -cover .\u002F...\n\n# Run specific test\ngo test -run TestValidateEmail .\u002F...\n```\n\n### cargo test (Rust)\n```bash\n# Run all tests\ncargo test\n\n# Run tests in release mode\ncargo test --release\n\n# Run with coverage (requires tarpaulin)\ncargo tarpaulin --out Html\n\n# Run specific test\ncargo test validate_email\n```\n\n---\n\n## Success Checklist\n\nAfter completing the TDD workflow, verify:\n\n- [ ] Framework detected correctly\n- [ ] Tests written BEFORE implementation (RED phase confirmed)\n- [ ] All tests PASS (GREEN phase confirmed)\n- [ ] Code refactored for clarity and quality\n- [ ] Coverage meets requirements (80%+ standard, 100% for critical paths)\n- [ ] Test suite includes: happy path, edge cases, error conditions\n- [ ] No shared state between tests\n- [ ] Meaningful assertion messages\n- [ ] Code committed with comprehensive test suite\n\n## Upstream\n\nSeam and anti-pattern guidance adapted from [mattpocock\u002Fskills](https:\u002F\u002Fgithub.com\u002Fmattpocock\u002Fskills) (skills\u002Fengineering\u002Ftdd), synced to upstream commit f3fc563. HQ keeps its RED, GREEN, REFACTOR cycle and coverage gates.\n",{"name":5,"description":7,"allowed-tools":46},"Read, Write, Edit, Bash, Glob, Grep","main","205cf61728a27ef15e9153aa38df5856fc8d82f5",".claude\u002Fskills\u002Ftdd",18,"https:\u002F\u002Fgithub.com\u002Findigoai-us\u002Fhq-core","https:\u002F\u002Fgithub.com\u002Findigoai-us","https:\u002F\u002Fhqforwork.com\u002F","The AI Context Layer for Teams","2026-11-12 06:53:38",{"source":8,"skillName":5,"commands":57,"prompt":67,"zipAvailable":68},[58,61,64],{"tool":59,"command":60},"npx","npx skills add indigoai-us\u002Fhq-core --skill tdd",{"tool":62,"command":63},"bunx","bunx skills add indigoai-us\u002Fhq-core --skill tdd",{"tool":65,"command":66},"pnpm","pnpm dlx skills add indigoai-us\u002Fhq-core --skill tdd","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Findigoai-us\u002Fhq-core\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftdd\u002FSKILL.md",true,[70],{"path":71,"resourceType":72,"resourceTypeDesc":73,"sizeBytes":74,"sourceHtmlUrl":75},"agents\u002Fopenai.yaml","REFERENCE","参考文档",111,"https:\u002F\u002Fgithub.com\u002Findigoai-us\u002Fhq-core\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftdd\u002Fagents\u002Fopenai.yaml",[77,95,123,147,158,168],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":41},"01M71E4MQ04WPK1EVDS7VKJ3E8","social-graphic","Generate 1080x1080 HTML social graphics for HQ update posts.","https:\u002F\u002Fgithub.com\u002Findigoai-us\u002Fhq-core\u002Fblob\u002Fmain\u002Fcore\u002Fworkers\u002Fpublic\u002Fsocial-strategist\u002Fskills\u002Fsocial-graphic\u002FSKILL.md",[],[84,85,36,86,33,34,35,87,88,89,90,91,92,93,94],"social","social graphic","html","update","generate","graphics","browser","open","agent-browser","for","posts",{"skillNo":96,"name":92,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":106,"publishedAt":41},"01M71E4H33K4P5H5M7ENPTMFSC","Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to \"open a website\", \"fill out a form\", \"click a button\", \"take a screenshot\", \"scrape data from a page\", \"test this web app\", \"login to a site\", \"automate browser actions\", or any task requiring programmatic web interaction.","https:\u002F\u002Fgithub.com\u002Findigoai-us\u002Fhq-core\u002Fblob\u002Fmain\u002Fcore\u002Fworkers\u002Fpublic\u002Fqa-tester\u002Fskills\u002Fagent-browser\u002FSKILL.md",[100,103],{"categoryNo":101,"categoryName":102,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":104,"categoryName":105,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[107,90,108,109,110,111,36,112,113,114,115,116,91,117,92,118,119,120,121,122],"agent browser","click","ai agents","app","scrape","when","apps","actions","extracting","take a screenshot","testing","programmatic","browser automation","website","cli","interaction",{"skillNo":124,"name":125,"nameZh":6,"description":126,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":127,"categories":128,"keywords":129,"publishedAt":41},"01M71E4FDBD7J8Y45JJ9KMMYGN","work-mesh","Work Mesh Live — automatic presence via hq mesh daemon; context reconcile\u002Forganize; manual session task-status, blocked, and note only.","https:\u002F\u002Fgithub.com\u002Findigoai-us\u002Fhq-core\u002Fblob\u002Fmain\u002Fcore\u002Fskills\u002Fwork-mesh\u002FSKILL.md",[],[130,131,132,36,133,134,135,136,137,138,139,140,141,142,35,143,144,145,146],"work mesh","work","mesh","status","context","note","live","presence","automatic","reconcile","only","organize","task","session","manual","daemon","via",{"skillNo":148,"name":149,"nameZh":6,"description":150,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":41},"01M71E4EGHNAAGWAPV6KGBMQ9W","review","Parity worker review skill (materialization fixture).","https:\u002F\u002Fgithub.com\u002Findigoai-us\u002Fhq-core\u002Fblob\u002Fmain\u002Fcore\u002Fscripts\u002Ftests\u002Ffixtures\u002Fagent-session\u002Fworker-materialization\u002Fparity-worker\u002Fskills\u002Freview\u002FSKILL.md",[],[149,154,155,156,157],"review skill","fixture","parity","worker",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":162,"categories":163,"keywords":164,"publishedAt":41},"01M71E4D1FZDJPDC15DRERKX8Y","run","Run or list HQ workers (parity fixture).","https:\u002F\u002Fgithub.com\u002Findigoai-us\u002Fhq-core\u002Fblob\u002Fmain\u002Fcore\u002Fscripts\u002Ftests\u002Ffixtures\u002Fagent-session\u002Fskills\u002Frun\u002FSKILL.md",[],[160,165,166,156,167,155],"parity fixture","workers","list",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":174,"publishedAt":41},"01M71E4BF4MV5SEWZJZ4T1QPQW","handoff","Preserve session state for a follow-up agent (parity fixture).","https:\u002F\u002Fgithub.com\u002Findigoai-us\u002Fhq-core\u002Fblob\u002Fmain\u002Fcore\u002Fscripts\u002Ftests\u002Ffixtures\u002Fagent-session\u002Fskills\u002Fhandoff\u002FSKILL.md",[],[170,165,175,176,143,177,93,156,178,179,155],"up","preserve","session state","follow-up","state"]