feat: 決定論的ロジック層への TDD ハーネスを導入 - #465

Merged
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness
Jul 5, 2026
Merged

feat: 決定論的ロジック層への TDD ハーネスを導入#465
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • 決定論的ビジネスロジック層(mutmut/stryker のミューテーションテスト対象と同一スコープ)の実装変更を TDD(red → green → refactor) で行う方針を導入(ADR-0019)
  • ワークフロー正本 .claude/rules/common/tdd.md(backend/web 編集時に自動ロード)を新設し、既存の backend/test.md / web/test.md / CLAUDE.md から誘導
  • 機械ゲート scripts/lint-tdd.shmake lint-tdd)を新設。TDD 対象の実装変更にテスト差分が随伴しているかを検証し、make lint / make ci および CI(test.yml の test-backend ジョブ)に組み込み。振る舞いを変えない変更は Tdd-Exempt: <理由> コミットトレーラーで除外可能
  • AI 向け段階制御スキル /tdd.claude/skills/tdd/SKILL.md)を新設。対象判定 → テスト設計提示 → red(失敗確認)→ green → refactor の各フェーズで停止・報告する
  • docs/development.md / CONTRIBUTING.md に人間向けの概説を追記、docs/adr/README.md / docs/design-principles.md の索引を更新

設計判断

  • TDD 適用スコープは新規リストを作らず、既存の mutation 設定(backend/pyproject.toml[tool.mutmut] only_mutate / web/stryker.conf.jsonmutate)を SSoT として共有(ADR-0017 と対になる事前プロセス)
  • 機械ゲートは「テストファーストの証明」ではなく「テスト差分の随伴」という検証可能な必要条件に限定(限界は ADR-0019 に明記)

Test plan

  • make lint-adr-index green(ADR 索引の drift なし)
  • make lint-tdd の動作確認: 対象ファイルのみ変更→fail / テスト随伴→pass / Tdd-Exempt トレーラー→skip / TDD_EXEMPT=1→skip / stryker 除外パターン(pdfjs.ts)→対象外
  • make ci(lint + backend pytest + web vitest 365 件 + build)green
  • ドキュメント・スクリプト変更のみで backend/web の実行時挙動に影響しないため E2E・smoke は対象外。CI 上で test.yml の新ステップが期待どおり動くことは本 PR の CI 結果で確認する

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a standardized TDD workflow for deterministic logic changes, including red → green → refactor guidance and an exemption path for behavior-only edits.
    • Added a new lint check to verify test coverage stays aligned with implementation changes.
  • Documentation
    • Updated development and contributing guidance to explain when the TDD workflow applies and how to validate it.
    • Expanded architecture and design-principles docs to reflect the new quality process.

ミューテーションテスト対象(mutmut/stryker)と同一スコープの実装変更を
red→green→refactor で行う方針を導入する。ワークフロー正本
(.claude/rules/common/tdd.md)、機械ゲート(scripts/lint-tdd.sh /
make lint-tdd、test.yml に組み込み)、AI 向け段階制御スキル(/tdd)を
新設し、既存ルール・development.md・CONTRIBUTING.md から誘導する。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22cbd120-2bdc-4f14-b87d-4868259a0028

📥 Commits

Reviewing files that changed from the base of the PR and between ff27798 and 9501a1d.

📒 Files selected for processing (2)
  • docs/adr/README.md
  • docs/design-principles.md
📝 Walkthrough

Walkthrough

This PR introduces ADR-0019 to mandate test-driven development (red→green→refactor) for changes to deterministic logic layers identified via mutmut (backend) and Stryker (web) mutation-test configurations. It adds a lint-tdd.sh enforcement script wired into make lint/CI, new rule/skill docs, and updates supporting documentation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Changes

TDD Gate Introduction

Layer / File(s)Summary
ADR-0019 decision document
docs/adr/0019-tdd-for-logic-layer.md
Adds ADR defining TDD scope (reusing ADR-0017 mutation targets), workflow, make lint-tdd gate, Tdd-Exempt mechanism, trade-offs, and links to design principles.
TDD rule and skill documents
.claude/rules/common/tdd.md, .claude/rules/backend/test.md, .claude/rules/web/test.md, .claude/skills/tdd/SKILL.md
Adds common TDD workflow rule, scope-determination sections in backend/web test rules, and a phase-based TDD skill document.
lint-tdd.sh enforcement script
scripts/lint-tdd.sh
Adds a script that resolves base ref, honors Tdd-Exempt/TDD_EXEMPT, parses mutmut/Stryker globs, classifies changed files, and fails when matched implementation changes lack test diffs.
Makefile and CI wiring
Makefile, .github/workflows/test.yml
Adds lint-tdd target wired into lint/help output; CI checkout now uses fetch-depth: 0 and runs a new "Lint SSoT" step invoking the script.
Documentation and agent instruction updates
.claude/CLAUDE.md, CONTRIBUTING.md, docs/development.md, docs/design-principles.md, docs/adr/README.md
Updates commit/PR flow, contributing guide, development docs, principle matrix, and ADR index to reference ADR-0019 and the TDD gate.

Sequence Diagram(s)

sequenceDiagram
participant CI as CI Workflow
participant Script as lint-tdd.sh
participant Git as Git
CI->>Script: bash scripts/lint-tdd.sh
Script->>Git: resolve base ref / merge-base
Script->>Script: check Tdd-Exempt trailer or TDD_EXEMPT=1
alt exempt
Script-->>CI: exit 0 (skip)
else not exempt
Script->>Git: diff changed files vs base
Script->>Script: parse mutmut/stryker globs
Script->>Script: classify impl vs test file changes
alt missing test diff for matched impl
Script-->>CI: ERROR + exit 1
else
Script-->>CI: OK + exit 0
end
end
Loading

Possibly related PRs

  • yusuke0610/devforge#297: Both PRs update .claude/CLAUDE.md's commit/PR flow "stage" instructions.
  • yusuke0610/devforge#398: Both PRs update .claude/CLAUDE.md's commit/PR workflow documentation without overlapping on the TDD gate logic.
  • yusuke0610/devforge#450: Introduces/adjusts backend/pyproject.toml mutmut and web/stryker.conf.json mutation configs that this PR's lint-tdd.sh and TDD rules directly reference.

Suggested labels:documentation, feature, test, agent, ci

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly matches the main change: introducing a TDD harness for deterministic logic-layer changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/tdd-harness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

main に取り込まれた ADR-0018(GitHub連携経歴書ドラフト生成)と
本ブランチの ADR-0019(TDD 導入)が docs/adr/README.md と
docs/design-principles.md で衝突していたため解消(番号順に両方保持)。
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation ci CI / ワークフロー and removed feature 新機能 labels Jul 5, 2026
@yusuke0610
yusuke0610 merged commit f3258b7 into mainJul 5, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the docs/tdd-harness branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciCI / ワークフローdocumentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: 決定論的ロジック層への TDD ハーネスを導入 - #465

Merged
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness
Jul 5, 2026
Merged

feat: 決定論的ロジック層への TDD ハーネスを導入#465
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • 決定論的ビジネスロジック層(mutmut/stryker のミューテーションテスト対象と同一スコープ)の実装変更を TDD(red → green → refactor) で行う方針を導入(ADR-0019)
  • ワークフロー正本 .claude/rules/common/tdd.md(backend/web 編集時に自動ロード)を新設し、既存の backend/test.md / web/test.md / CLAUDE.md から誘導
  • 機械ゲート scripts/lint-tdd.shmake lint-tdd)を新設。TDD 対象の実装変更にテスト差分が随伴しているかを検証し、make lint / make ci および CI(test.yml の test-backend ジョブ)に組み込み。振る舞いを変えない変更は Tdd-Exempt: <理由> コミットトレーラーで除外可能
  • AI 向け段階制御スキル /tdd.claude/skills/tdd/SKILL.md)を新設。対象判定 → テスト設計提示 → red(失敗確認)→ green → refactor の各フェーズで停止・報告する
  • docs/development.md / CONTRIBUTING.md に人間向けの概説を追記、docs/adr/README.md / docs/design-principles.md の索引を更新

設計判断

  • TDD 適用スコープは新規リストを作らず、既存の mutation 設定(backend/pyproject.toml[tool.mutmut] only_mutate / web/stryker.conf.jsonmutate)を SSoT として共有(ADR-0017 と対になる事前プロセス)
  • 機械ゲートは「テストファーストの証明」ではなく「テスト差分の随伴」という検証可能な必要条件に限定(限界は ADR-0019 に明記)

Test plan

  • make lint-adr-index green(ADR 索引の drift なし)
  • make lint-tdd の動作確認: 対象ファイルのみ変更→fail / テスト随伴→pass / Tdd-Exempt トレーラー→skip / TDD_EXEMPT=1→skip / stryker 除外パターン(pdfjs.ts)→対象外
  • make ci(lint + backend pytest + web vitest 365 件 + build)green
  • ドキュメント・スクリプト変更のみで backend/web の実行時挙動に影響しないため E2E・smoke は対象外。CI 上で test.yml の新ステップが期待どおり動くことは本 PR の CI 結果で確認する

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a standardized TDD workflow for deterministic logic changes, including red → green → refactor guidance and an exemption path for behavior-only edits.
    • Added a new lint check to verify test coverage stays aligned with implementation changes.
  • Documentation
    • Updated development and contributing guidance to explain when the TDD workflow applies and how to validate it.
    • Expanded architecture and design-principles docs to reflect the new quality process.

ミューテーションテスト対象(mutmut/stryker)と同一スコープの実装変更を
red→green→refactor で行う方針を導入する。ワークフロー正本
(.claude/rules/common/tdd.md)、機械ゲート(scripts/lint-tdd.sh /
make lint-tdd、test.yml に組み込み)、AI 向け段階制御スキル(/tdd)を
新設し、既存ルール・development.md・CONTRIBUTING.md から誘導する。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22cbd120-2bdc-4f14-b87d-4868259a0028

📥 Commits

Reviewing files that changed from the base of the PR and between ff27798 and 9501a1d.

📒 Files selected for processing (2)
  • docs/adr/README.md
  • docs/design-principles.md
📝 Walkthrough

Walkthrough

This PR introduces ADR-0019 to mandate test-driven development (red→green→refactor) for changes to deterministic logic layers identified via mutmut (backend) and Stryker (web) mutation-test configurations. It adds a lint-tdd.sh enforcement script wired into make lint/CI, new rule/skill docs, and updates supporting documentation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Changes

TDD Gate Introduction

Layer / File(s)Summary
ADR-0019 decision document
docs/adr/0019-tdd-for-logic-layer.md
Adds ADR defining TDD scope (reusing ADR-0017 mutation targets), workflow, make lint-tdd gate, Tdd-Exempt mechanism, trade-offs, and links to design principles.
TDD rule and skill documents
.claude/rules/common/tdd.md, .claude/rules/backend/test.md, .claude/rules/web/test.md, .claude/skills/tdd/SKILL.md
Adds common TDD workflow rule, scope-determination sections in backend/web test rules, and a phase-based TDD skill document.
lint-tdd.sh enforcement script
scripts/lint-tdd.sh
Adds a script that resolves base ref, honors Tdd-Exempt/TDD_EXEMPT, parses mutmut/Stryker globs, classifies changed files, and fails when matched implementation changes lack test diffs.
Makefile and CI wiring
Makefile, .github/workflows/test.yml
Adds lint-tdd target wired into lint/help output; CI checkout now uses fetch-depth: 0 and runs a new "Lint SSoT" step invoking the script.
Documentation and agent instruction updates
.claude/CLAUDE.md, CONTRIBUTING.md, docs/development.md, docs/design-principles.md, docs/adr/README.md
Updates commit/PR flow, contributing guide, development docs, principle matrix, and ADR index to reference ADR-0019 and the TDD gate.

Sequence Diagram(s)

sequenceDiagram
participant CI as CI Workflow
participant Script as lint-tdd.sh
participant Git as Git
CI->>Script: bash scripts/lint-tdd.sh
Script->>Git: resolve base ref / merge-base
Script->>Script: check Tdd-Exempt trailer or TDD_EXEMPT=1
alt exempt
Script-->>CI: exit 0 (skip)
else not exempt
Script->>Git: diff changed files vs base
Script->>Script: parse mutmut/stryker globs
Script->>Script: classify impl vs test file changes
alt missing test diff for matched impl
Script-->>CI: ERROR + exit 1
else
Script-->>CI: OK + exit 0
end
end
Loading

Possibly related PRs

  • yusuke0610/devforge#297: Both PRs update .claude/CLAUDE.md's commit/PR flow "stage" instructions.
  • yusuke0610/devforge#398: Both PRs update .claude/CLAUDE.md's commit/PR workflow documentation without overlapping on the TDD gate logic.
  • yusuke0610/devforge#450: Introduces/adjusts backend/pyproject.toml mutmut and web/stryker.conf.json mutation configs that this PR's lint-tdd.sh and TDD rules directly reference.

Suggested labels:documentation, feature, test, agent, ci

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly matches the main change: introducing a TDD harness for deterministic logic-layer changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/tdd-harness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

main に取り込まれた ADR-0018(GitHub連携経歴書ドラフト生成)と
本ブランチの ADR-0019(TDD 導入)が docs/adr/README.md と
docs/design-principles.md で衝突していたため解消(番号順に両方保持)。
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation ci CI / ワークフロー and removed feature 新機能 labels Jul 5, 2026
@yusuke0610
yusuke0610 merged commit f3258b7 into mainJul 5, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the docs/tdd-harness branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciCI / ワークフローdocumentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: 決定論的ロジック層への TDD ハーネスを導入 - #465

Merged
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness
Jul 5, 2026
Merged

feat: 決定論的ロジック層への TDD ハーネスを導入#465
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • 決定論的ビジネスロジック層(mutmut/stryker のミューテーションテスト対象と同一スコープ)の実装変更を TDD(red → green → refactor) で行う方針を導入(ADR-0019)
  • ワークフロー正本 .claude/rules/common/tdd.md(backend/web 編集時に自動ロード)を新設し、既存の backend/test.md / web/test.md / CLAUDE.md から誘導
  • 機械ゲート scripts/lint-tdd.shmake lint-tdd)を新設。TDD 対象の実装変更にテスト差分が随伴しているかを検証し、make lint / make ci および CI(test.yml の test-backend ジョブ)に組み込み。振る舞いを変えない変更は Tdd-Exempt: <理由> コミットトレーラーで除外可能
  • AI 向け段階制御スキル /tdd.claude/skills/tdd/SKILL.md)を新設。対象判定 → テスト設計提示 → red(失敗確認)→ green → refactor の各フェーズで停止・報告する
  • docs/development.md / CONTRIBUTING.md に人間向けの概説を追記、docs/adr/README.md / docs/design-principles.md の索引を更新

設計判断

  • TDD 適用スコープは新規リストを作らず、既存の mutation 設定(backend/pyproject.toml[tool.mutmut] only_mutate / web/stryker.conf.jsonmutate)を SSoT として共有(ADR-0017 と対になる事前プロセス)
  • 機械ゲートは「テストファーストの証明」ではなく「テスト差分の随伴」という検証可能な必要条件に限定(限界は ADR-0019 に明記)

Test plan

  • make lint-adr-index green(ADR 索引の drift なし)
  • make lint-tdd の動作確認: 対象ファイルのみ変更→fail / テスト随伴→pass / Tdd-Exempt トレーラー→skip / TDD_EXEMPT=1→skip / stryker 除外パターン(pdfjs.ts)→対象外
  • make ci(lint + backend pytest + web vitest 365 件 + build)green
  • ドキュメント・スクリプト変更のみで backend/web の実行時挙動に影響しないため E2E・smoke は対象外。CI 上で test.yml の新ステップが期待どおり動くことは本 PR の CI 結果で確認する

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a standardized TDD workflow for deterministic logic changes, including red → green → refactor guidance and an exemption path for behavior-only edits.
    • Added a new lint check to verify test coverage stays aligned with implementation changes.
  • Documentation
    • Updated development and contributing guidance to explain when the TDD workflow applies and how to validate it.
    • Expanded architecture and design-principles docs to reflect the new quality process.

ミューテーションテスト対象(mutmut/stryker)と同一スコープの実装変更を
red→green→refactor で行う方針を導入する。ワークフロー正本
(.claude/rules/common/tdd.md)、機械ゲート(scripts/lint-tdd.sh /
make lint-tdd、test.yml に組み込み)、AI 向け段階制御スキル(/tdd)を
新設し、既存ルール・development.md・CONTRIBUTING.md から誘導する。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22cbd120-2bdc-4f14-b87d-4868259a0028

📥 Commits

Reviewing files that changed from the base of the PR and between ff27798 and 9501a1d.

📒 Files selected for processing (2)
  • docs/adr/README.md
  • docs/design-principles.md
📝 Walkthrough

Walkthrough

This PR introduces ADR-0019 to mandate test-driven development (red→green→refactor) for changes to deterministic logic layers identified via mutmut (backend) and Stryker (web) mutation-test configurations. It adds a lint-tdd.sh enforcement script wired into make lint/CI, new rule/skill docs, and updates supporting documentation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Changes

TDD Gate Introduction

Layer / File(s)Summary
ADR-0019 decision document
docs/adr/0019-tdd-for-logic-layer.md
Adds ADR defining TDD scope (reusing ADR-0017 mutation targets), workflow, make lint-tdd gate, Tdd-Exempt mechanism, trade-offs, and links to design principles.
TDD rule and skill documents
.claude/rules/common/tdd.md, .claude/rules/backend/test.md, .claude/rules/web/test.md, .claude/skills/tdd/SKILL.md
Adds common TDD workflow rule, scope-determination sections in backend/web test rules, and a phase-based TDD skill document.
lint-tdd.sh enforcement script
scripts/lint-tdd.sh
Adds a script that resolves base ref, honors Tdd-Exempt/TDD_EXEMPT, parses mutmut/Stryker globs, classifies changed files, and fails when matched implementation changes lack test diffs.
Makefile and CI wiring
Makefile, .github/workflows/test.yml
Adds lint-tdd target wired into lint/help output; CI checkout now uses fetch-depth: 0 and runs a new "Lint SSoT" step invoking the script.
Documentation and agent instruction updates
.claude/CLAUDE.md, CONTRIBUTING.md, docs/development.md, docs/design-principles.md, docs/adr/README.md
Updates commit/PR flow, contributing guide, development docs, principle matrix, and ADR index to reference ADR-0019 and the TDD gate.

Sequence Diagram(s)

sequenceDiagram
participant CI as CI Workflow
participant Script as lint-tdd.sh
participant Git as Git
CI->>Script: bash scripts/lint-tdd.sh
Script->>Git: resolve base ref / merge-base
Script->>Script: check Tdd-Exempt trailer or TDD_EXEMPT=1
alt exempt
Script-->>CI: exit 0 (skip)
else not exempt
Script->>Git: diff changed files vs base
Script->>Script: parse mutmut/stryker globs
Script->>Script: classify impl vs test file changes
alt missing test diff for matched impl
Script-->>CI: ERROR + exit 1
else
Script-->>CI: OK + exit 0
end
end
Loading

Possibly related PRs

  • yusuke0610/devforge#297: Both PRs update .claude/CLAUDE.md's commit/PR flow "stage" instructions.
  • yusuke0610/devforge#398: Both PRs update .claude/CLAUDE.md's commit/PR workflow documentation without overlapping on the TDD gate logic.
  • yusuke0610/devforge#450: Introduces/adjusts backend/pyproject.toml mutmut and web/stryker.conf.json mutation configs that this PR's lint-tdd.sh and TDD rules directly reference.

Suggested labels:documentation, feature, test, agent, ci

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly matches the main change: introducing a TDD harness for deterministic logic-layer changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/tdd-harness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

main に取り込まれた ADR-0018(GitHub連携経歴書ドラフト生成)と
本ブランチの ADR-0019(TDD 導入)が docs/adr/README.md と
docs/design-principles.md で衝突していたため解消(番号順に両方保持)。
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation ci CI / ワークフロー and removed feature 新機能 labels Jul 5, 2026
@yusuke0610
yusuke0610 merged commit f3258b7 into mainJul 5, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the docs/tdd-harness branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciCI / ワークフローdocumentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: 決定論的ロジック層への TDD ハーネスを導入 - #465

Merged
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness
Jul 5, 2026
Merged

feat: 決定論的ロジック層への TDD ハーネスを導入#465
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • 決定論的ビジネスロジック層(mutmut/stryker のミューテーションテスト対象と同一スコープ)の実装変更を TDD(red → green → refactor) で行う方針を導入(ADR-0019)
  • ワークフロー正本 .claude/rules/common/tdd.md(backend/web 編集時に自動ロード)を新設し、既存の backend/test.md / web/test.md / CLAUDE.md から誘導
  • 機械ゲート scripts/lint-tdd.shmake lint-tdd)を新設。TDD 対象の実装変更にテスト差分が随伴しているかを検証し、make lint / make ci および CI(test.yml の test-backend ジョブ)に組み込み。振る舞いを変えない変更は Tdd-Exempt: <理由> コミットトレーラーで除外可能
  • AI 向け段階制御スキル /tdd.claude/skills/tdd/SKILL.md)を新設。対象判定 → テスト設計提示 → red(失敗確認)→ green → refactor の各フェーズで停止・報告する
  • docs/development.md / CONTRIBUTING.md に人間向けの概説を追記、docs/adr/README.md / docs/design-principles.md の索引を更新

設計判断

  • TDD 適用スコープは新規リストを作らず、既存の mutation 設定(backend/pyproject.toml[tool.mutmut] only_mutate / web/stryker.conf.jsonmutate)を SSoT として共有(ADR-0017 と対になる事前プロセス)
  • 機械ゲートは「テストファーストの証明」ではなく「テスト差分の随伴」という検証可能な必要条件に限定(限界は ADR-0019 に明記)

Test plan

  • make lint-adr-index green(ADR 索引の drift なし)
  • make lint-tdd の動作確認: 対象ファイルのみ変更→fail / テスト随伴→pass / Tdd-Exempt トレーラー→skip / TDD_EXEMPT=1→skip / stryker 除外パターン(pdfjs.ts)→対象外
  • make ci(lint + backend pytest + web vitest 365 件 + build)green
  • ドキュメント・スクリプト変更のみで backend/web の実行時挙動に影響しないため E2E・smoke は対象外。CI 上で test.yml の新ステップが期待どおり動くことは本 PR の CI 結果で確認する

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a standardized TDD workflow for deterministic logic changes, including red → green → refactor guidance and an exemption path for behavior-only edits.
    • Added a new lint check to verify test coverage stays aligned with implementation changes.
  • Documentation
    • Updated development and contributing guidance to explain when the TDD workflow applies and how to validate it.
    • Expanded architecture and design-principles docs to reflect the new quality process.

ミューテーションテスト対象(mutmut/stryker)と同一スコープの実装変更を
red→green→refactor で行う方針を導入する。ワークフロー正本
(.claude/rules/common/tdd.md)、機械ゲート(scripts/lint-tdd.sh /
make lint-tdd、test.yml に組み込み)、AI 向け段階制御スキル(/tdd)を
新設し、既存ルール・development.md・CONTRIBUTING.md から誘導する。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22cbd120-2bdc-4f14-b87d-4868259a0028

📥 Commits

Reviewing files that changed from the base of the PR and between ff27798 and 9501a1d.

📒 Files selected for processing (2)
  • docs/adr/README.md
  • docs/design-principles.md
📝 Walkthrough

Walkthrough

This PR introduces ADR-0019 to mandate test-driven development (red→green→refactor) for changes to deterministic logic layers identified via mutmut (backend) and Stryker (web) mutation-test configurations. It adds a lint-tdd.sh enforcement script wired into make lint/CI, new rule/skill docs, and updates supporting documentation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Changes

TDD Gate Introduction

Layer / File(s)Summary
ADR-0019 decision document
docs/adr/0019-tdd-for-logic-layer.md
Adds ADR defining TDD scope (reusing ADR-0017 mutation targets), workflow, make lint-tdd gate, Tdd-Exempt mechanism, trade-offs, and links to design principles.
TDD rule and skill documents
.claude/rules/common/tdd.md, .claude/rules/backend/test.md, .claude/rules/web/test.md, .claude/skills/tdd/SKILL.md
Adds common TDD workflow rule, scope-determination sections in backend/web test rules, and a phase-based TDD skill document.
lint-tdd.sh enforcement script
scripts/lint-tdd.sh
Adds a script that resolves base ref, honors Tdd-Exempt/TDD_EXEMPT, parses mutmut/Stryker globs, classifies changed files, and fails when matched implementation changes lack test diffs.
Makefile and CI wiring
Makefile, .github/workflows/test.yml
Adds lint-tdd target wired into lint/help output; CI checkout now uses fetch-depth: 0 and runs a new "Lint SSoT" step invoking the script.
Documentation and agent instruction updates
.claude/CLAUDE.md, CONTRIBUTING.md, docs/development.md, docs/design-principles.md, docs/adr/README.md
Updates commit/PR flow, contributing guide, development docs, principle matrix, and ADR index to reference ADR-0019 and the TDD gate.

Sequence Diagram(s)

sequenceDiagram
participant CI as CI Workflow
participant Script as lint-tdd.sh
participant Git as Git
CI->>Script: bash scripts/lint-tdd.sh
Script->>Git: resolve base ref / merge-base
Script->>Script: check Tdd-Exempt trailer or TDD_EXEMPT=1
alt exempt
Script-->>CI: exit 0 (skip)
else not exempt
Script->>Git: diff changed files vs base
Script->>Script: parse mutmut/stryker globs
Script->>Script: classify impl vs test file changes
alt missing test diff for matched impl
Script-->>CI: ERROR + exit 1
else
Script-->>CI: OK + exit 0
end
end
Loading

Possibly related PRs

  • yusuke0610/devforge#297: Both PRs update .claude/CLAUDE.md's commit/PR flow "stage" instructions.
  • yusuke0610/devforge#398: Both PRs update .claude/CLAUDE.md's commit/PR workflow documentation without overlapping on the TDD gate logic.
  • yusuke0610/devforge#450: Introduces/adjusts backend/pyproject.toml mutmut and web/stryker.conf.json mutation configs that this PR's lint-tdd.sh and TDD rules directly reference.

Suggested labels:documentation, feature, test, agent, ci

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly matches the main change: introducing a TDD harness for deterministic logic-layer changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/tdd-harness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

main に取り込まれた ADR-0018(GitHub連携経歴書ドラフト生成)と
本ブランチの ADR-0019(TDD 導入)が docs/adr/README.md と
docs/design-principles.md で衝突していたため解消(番号順に両方保持)。
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation ci CI / ワークフロー and removed feature 新機能 labels Jul 5, 2026
@yusuke0610
yusuke0610 merged commit f3258b7 into mainJul 5, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the docs/tdd-harness branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciCI / ワークフローdocumentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: 決定論的ロジック層への TDD ハーネスを導入 - #465

Merged
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness
Jul 5, 2026
Merged

feat: 決定論的ロジック層への TDD ハーネスを導入#465
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • 決定論的ビジネスロジック層(mutmut/stryker のミューテーションテスト対象と同一スコープ)の実装変更を TDD(red → green → refactor) で行う方針を導入(ADR-0019)
  • ワークフロー正本 .claude/rules/common/tdd.md(backend/web 編集時に自動ロード)を新設し、既存の backend/test.md / web/test.md / CLAUDE.md から誘導
  • 機械ゲート scripts/lint-tdd.shmake lint-tdd)を新設。TDD 対象の実装変更にテスト差分が随伴しているかを検証し、make lint / make ci および CI(test.yml の test-backend ジョブ)に組み込み。振る舞いを変えない変更は Tdd-Exempt: <理由> コミットトレーラーで除外可能
  • AI 向け段階制御スキル /tdd.claude/skills/tdd/SKILL.md)を新設。対象判定 → テスト設計提示 → red(失敗確認)→ green → refactor の各フェーズで停止・報告する
  • docs/development.md / CONTRIBUTING.md に人間向けの概説を追記、docs/adr/README.md / docs/design-principles.md の索引を更新

設計判断

  • TDD 適用スコープは新規リストを作らず、既存の mutation 設定(backend/pyproject.toml[tool.mutmut] only_mutate / web/stryker.conf.jsonmutate)を SSoT として共有(ADR-0017 と対になる事前プロセス)
  • 機械ゲートは「テストファーストの証明」ではなく「テスト差分の随伴」という検証可能な必要条件に限定(限界は ADR-0019 に明記)

Test plan

  • make lint-adr-index green(ADR 索引の drift なし)
  • make lint-tdd の動作確認: 対象ファイルのみ変更→fail / テスト随伴→pass / Tdd-Exempt トレーラー→skip / TDD_EXEMPT=1→skip / stryker 除外パターン(pdfjs.ts)→対象外
  • make ci(lint + backend pytest + web vitest 365 件 + build)green
  • ドキュメント・スクリプト変更のみで backend/web の実行時挙動に影響しないため E2E・smoke は対象外。CI 上で test.yml の新ステップが期待どおり動くことは本 PR の CI 結果で確認する

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a standardized TDD workflow for deterministic logic changes, including red → green → refactor guidance and an exemption path for behavior-only edits.
    • Added a new lint check to verify test coverage stays aligned with implementation changes.
  • Documentation
    • Updated development and contributing guidance to explain when the TDD workflow applies and how to validate it.
    • Expanded architecture and design-principles docs to reflect the new quality process.

ミューテーションテスト対象(mutmut/stryker)と同一スコープの実装変更を
red→green→refactor で行う方針を導入する。ワークフロー正本
(.claude/rules/common/tdd.md)、機械ゲート(scripts/lint-tdd.sh /
make lint-tdd、test.yml に組み込み)、AI 向け段階制御スキル(/tdd)を
新設し、既存ルール・development.md・CONTRIBUTING.md から誘導する。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22cbd120-2bdc-4f14-b87d-4868259a0028

📥 Commits

Reviewing files that changed from the base of the PR and between ff27798 and 9501a1d.

📒 Files selected for processing (2)
  • docs/adr/README.md
  • docs/design-principles.md
📝 Walkthrough

Walkthrough

This PR introduces ADR-0019 to mandate test-driven development (red→green→refactor) for changes to deterministic logic layers identified via mutmut (backend) and Stryker (web) mutation-test configurations. It adds a lint-tdd.sh enforcement script wired into make lint/CI, new rule/skill docs, and updates supporting documentation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Changes

TDD Gate Introduction

Layer / File(s)Summary
ADR-0019 decision document
docs/adr/0019-tdd-for-logic-layer.md
Adds ADR defining TDD scope (reusing ADR-0017 mutation targets), workflow, make lint-tdd gate, Tdd-Exempt mechanism, trade-offs, and links to design principles.
TDD rule and skill documents
.claude/rules/common/tdd.md, .claude/rules/backend/test.md, .claude/rules/web/test.md, .claude/skills/tdd/SKILL.md
Adds common TDD workflow rule, scope-determination sections in backend/web test rules, and a phase-based TDD skill document.
lint-tdd.sh enforcement script
scripts/lint-tdd.sh
Adds a script that resolves base ref, honors Tdd-Exempt/TDD_EXEMPT, parses mutmut/Stryker globs, classifies changed files, and fails when matched implementation changes lack test diffs.
Makefile and CI wiring
Makefile, .github/workflows/test.yml
Adds lint-tdd target wired into lint/help output; CI checkout now uses fetch-depth: 0 and runs a new "Lint SSoT" step invoking the script.
Documentation and agent instruction updates
.claude/CLAUDE.md, CONTRIBUTING.md, docs/development.md, docs/design-principles.md, docs/adr/README.md
Updates commit/PR flow, contributing guide, development docs, principle matrix, and ADR index to reference ADR-0019 and the TDD gate.

Sequence Diagram(s)

sequenceDiagram
participant CI as CI Workflow
participant Script as lint-tdd.sh
participant Git as Git
CI->>Script: bash scripts/lint-tdd.sh
Script->>Git: resolve base ref / merge-base
Script->>Script: check Tdd-Exempt trailer or TDD_EXEMPT=1
alt exempt
Script-->>CI: exit 0 (skip)
else not exempt
Script->>Git: diff changed files vs base
Script->>Script: parse mutmut/stryker globs
Script->>Script: classify impl vs test file changes
alt missing test diff for matched impl
Script-->>CI: ERROR + exit 1
else
Script-->>CI: OK + exit 0
end
end
Loading

Possibly related PRs

  • yusuke0610/devforge#297: Both PRs update .claude/CLAUDE.md's commit/PR flow "stage" instructions.
  • yusuke0610/devforge#398: Both PRs update .claude/CLAUDE.md's commit/PR workflow documentation without overlapping on the TDD gate logic.
  • yusuke0610/devforge#450: Introduces/adjusts backend/pyproject.toml mutmut and web/stryker.conf.json mutation configs that this PR's lint-tdd.sh and TDD rules directly reference.

Suggested labels:documentation, feature, test, agent, ci

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly matches the main change: introducing a TDD harness for deterministic logic-layer changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/tdd-harness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

main に取り込まれた ADR-0018(GitHub連携経歴書ドラフト生成)と
本ブランチの ADR-0019(TDD 導入)が docs/adr/README.md と
docs/design-principles.md で衝突していたため解消(番号順に両方保持)。
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation ci CI / ワークフロー and removed feature 新機能 labels Jul 5, 2026
@yusuke0610
yusuke0610 merged commit f3258b7 into mainJul 5, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the docs/tdd-harness branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciCI / ワークフローdocumentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: 決定論的ロジック層への TDD ハーネスを導入 - #465

Merged
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness
Jul 5, 2026
Merged

feat: 決定論的ロジック層への TDD ハーネスを導入#465
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • 決定論的ビジネスロジック層(mutmut/stryker のミューテーションテスト対象と同一スコープ)の実装変更を TDD(red → green → refactor) で行う方針を導入(ADR-0019)
  • ワークフロー正本 .claude/rules/common/tdd.md(backend/web 編集時に自動ロード)を新設し、既存の backend/test.md / web/test.md / CLAUDE.md から誘導
  • 機械ゲート scripts/lint-tdd.shmake lint-tdd)を新設。TDD 対象の実装変更にテスト差分が随伴しているかを検証し、make lint / make ci および CI(test.yml の test-backend ジョブ)に組み込み。振る舞いを変えない変更は Tdd-Exempt: <理由> コミットトレーラーで除外可能
  • AI 向け段階制御スキル /tdd.claude/skills/tdd/SKILL.md)を新設。対象判定 → テスト設計提示 → red(失敗確認)→ green → refactor の各フェーズで停止・報告する
  • docs/development.md / CONTRIBUTING.md に人間向けの概説を追記、docs/adr/README.md / docs/design-principles.md の索引を更新

設計判断

  • TDD 適用スコープは新規リストを作らず、既存の mutation 設定(backend/pyproject.toml[tool.mutmut] only_mutate / web/stryker.conf.jsonmutate)を SSoT として共有(ADR-0017 と対になる事前プロセス)
  • 機械ゲートは「テストファーストの証明」ではなく「テスト差分の随伴」という検証可能な必要条件に限定(限界は ADR-0019 に明記)

Test plan

  • make lint-adr-index green(ADR 索引の drift なし)
  • make lint-tdd の動作確認: 対象ファイルのみ変更→fail / テスト随伴→pass / Tdd-Exempt トレーラー→skip / TDD_EXEMPT=1→skip / stryker 除外パターン(pdfjs.ts)→対象外
  • make ci(lint + backend pytest + web vitest 365 件 + build)green
  • ドキュメント・スクリプト変更のみで backend/web の実行時挙動に影響しないため E2E・smoke は対象外。CI 上で test.yml の新ステップが期待どおり動くことは本 PR の CI 結果で確認する

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a standardized TDD workflow for deterministic logic changes, including red → green → refactor guidance and an exemption path for behavior-only edits.
    • Added a new lint check to verify test coverage stays aligned with implementation changes.
  • Documentation
    • Updated development and contributing guidance to explain when the TDD workflow applies and how to validate it.
    • Expanded architecture and design-principles docs to reflect the new quality process.

ミューテーションテスト対象(mutmut/stryker)と同一スコープの実装変更を
red→green→refactor で行う方針を導入する。ワークフロー正本
(.claude/rules/common/tdd.md)、機械ゲート(scripts/lint-tdd.sh /
make lint-tdd、test.yml に組み込み)、AI 向け段階制御スキル(/tdd)を
新設し、既存ルール・development.md・CONTRIBUTING.md から誘導する。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22cbd120-2bdc-4f14-b87d-4868259a0028

📥 Commits

Reviewing files that changed from the base of the PR and between ff27798 and 9501a1d.

📒 Files selected for processing (2)
  • docs/adr/README.md
  • docs/design-principles.md
📝 Walkthrough

Walkthrough

This PR introduces ADR-0019 to mandate test-driven development (red→green→refactor) for changes to deterministic logic layers identified via mutmut (backend) and Stryker (web) mutation-test configurations. It adds a lint-tdd.sh enforcement script wired into make lint/CI, new rule/skill docs, and updates supporting documentation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Changes

TDD Gate Introduction

Layer / File(s)Summary
ADR-0019 decision document
docs/adr/0019-tdd-for-logic-layer.md
Adds ADR defining TDD scope (reusing ADR-0017 mutation targets), workflow, make lint-tdd gate, Tdd-Exempt mechanism, trade-offs, and links to design principles.
TDD rule and skill documents
.claude/rules/common/tdd.md, .claude/rules/backend/test.md, .claude/rules/web/test.md, .claude/skills/tdd/SKILL.md
Adds common TDD workflow rule, scope-determination sections in backend/web test rules, and a phase-based TDD skill document.
lint-tdd.sh enforcement script
scripts/lint-tdd.sh
Adds a script that resolves base ref, honors Tdd-Exempt/TDD_EXEMPT, parses mutmut/Stryker globs, classifies changed files, and fails when matched implementation changes lack test diffs.
Makefile and CI wiring
Makefile, .github/workflows/test.yml
Adds lint-tdd target wired into lint/help output; CI checkout now uses fetch-depth: 0 and runs a new "Lint SSoT" step invoking the script.
Documentation and agent instruction updates
.claude/CLAUDE.md, CONTRIBUTING.md, docs/development.md, docs/design-principles.md, docs/adr/README.md
Updates commit/PR flow, contributing guide, development docs, principle matrix, and ADR index to reference ADR-0019 and the TDD gate.

Sequence Diagram(s)

sequenceDiagram
participant CI as CI Workflow
participant Script as lint-tdd.sh
participant Git as Git
CI->>Script: bash scripts/lint-tdd.sh
Script->>Git: resolve base ref / merge-base
Script->>Script: check Tdd-Exempt trailer or TDD_EXEMPT=1
alt exempt
Script-->>CI: exit 0 (skip)
else not exempt
Script->>Git: diff changed files vs base
Script->>Script: parse mutmut/stryker globs
Script->>Script: classify impl vs test file changes
alt missing test diff for matched impl
Script-->>CI: ERROR + exit 1
else
Script-->>CI: OK + exit 0
end
end
Loading

Possibly related PRs

  • yusuke0610/devforge#297: Both PRs update .claude/CLAUDE.md's commit/PR flow "stage" instructions.
  • yusuke0610/devforge#398: Both PRs update .claude/CLAUDE.md's commit/PR workflow documentation without overlapping on the TDD gate logic.
  • yusuke0610/devforge#450: Introduces/adjusts backend/pyproject.toml mutmut and web/stryker.conf.json mutation configs that this PR's lint-tdd.sh and TDD rules directly reference.

Suggested labels:documentation, feature, test, agent, ci

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly matches the main change: introducing a TDD harness for deterministic logic-layer changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/tdd-harness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

main に取り込まれた ADR-0018(GitHub連携経歴書ドラフト生成)と
本ブランチの ADR-0019(TDD 導入)が docs/adr/README.md と
docs/design-principles.md で衝突していたため解消(番号順に両方保持)。
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation ci CI / ワークフロー and removed feature 新機能 labels Jul 5, 2026
@yusuke0610
yusuke0610 merged commit f3258b7 into mainJul 5, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the docs/tdd-harness branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciCI / ワークフローdocumentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: 決定論的ロジック層への TDD ハーネスを導入 - #465

Merged
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness
Jul 5, 2026
Merged

feat: 決定論的ロジック層への TDD ハーネスを導入#465
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • 決定論的ビジネスロジック層(mutmut/stryker のミューテーションテスト対象と同一スコープ)の実装変更を TDD(red → green → refactor) で行う方針を導入(ADR-0019)
  • ワークフロー正本 .claude/rules/common/tdd.md(backend/web 編集時に自動ロード)を新設し、既存の backend/test.md / web/test.md / CLAUDE.md から誘導
  • 機械ゲート scripts/lint-tdd.shmake lint-tdd)を新設。TDD 対象の実装変更にテスト差分が随伴しているかを検証し、make lint / make ci および CI(test.yml の test-backend ジョブ)に組み込み。振る舞いを変えない変更は Tdd-Exempt: <理由> コミットトレーラーで除外可能
  • AI 向け段階制御スキル /tdd.claude/skills/tdd/SKILL.md)を新設。対象判定 → テスト設計提示 → red(失敗確認)→ green → refactor の各フェーズで停止・報告する
  • docs/development.md / CONTRIBUTING.md に人間向けの概説を追記、docs/adr/README.md / docs/design-principles.md の索引を更新

設計判断

  • TDD 適用スコープは新規リストを作らず、既存の mutation 設定(backend/pyproject.toml[tool.mutmut] only_mutate / web/stryker.conf.jsonmutate)を SSoT として共有(ADR-0017 と対になる事前プロセス)
  • 機械ゲートは「テストファーストの証明」ではなく「テスト差分の随伴」という検証可能な必要条件に限定(限界は ADR-0019 に明記)

Test plan

  • make lint-adr-index green(ADR 索引の drift なし)
  • make lint-tdd の動作確認: 対象ファイルのみ変更→fail / テスト随伴→pass / Tdd-Exempt トレーラー→skip / TDD_EXEMPT=1→skip / stryker 除外パターン(pdfjs.ts)→対象外
  • make ci(lint + backend pytest + web vitest 365 件 + build)green
  • ドキュメント・スクリプト変更のみで backend/web の実行時挙動に影響しないため E2E・smoke は対象外。CI 上で test.yml の新ステップが期待どおり動くことは本 PR の CI 結果で確認する

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a standardized TDD workflow for deterministic logic changes, including red → green → refactor guidance and an exemption path for behavior-only edits.
    • Added a new lint check to verify test coverage stays aligned with implementation changes.
  • Documentation
    • Updated development and contributing guidance to explain when the TDD workflow applies and how to validate it.
    • Expanded architecture and design-principles docs to reflect the new quality process.

ミューテーションテスト対象(mutmut/stryker)と同一スコープの実装変更を
red→green→refactor で行う方針を導入する。ワークフロー正本
(.claude/rules/common/tdd.md)、機械ゲート(scripts/lint-tdd.sh /
make lint-tdd、test.yml に組み込み)、AI 向け段階制御スキル(/tdd)を
新設し、既存ルール・development.md・CONTRIBUTING.md から誘導する。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22cbd120-2bdc-4f14-b87d-4868259a0028

📥 Commits

Reviewing files that changed from the base of the PR and between ff27798 and 9501a1d.

📒 Files selected for processing (2)
  • docs/adr/README.md
  • docs/design-principles.md
📝 Walkthrough

Walkthrough

This PR introduces ADR-0019 to mandate test-driven development (red→green→refactor) for changes to deterministic logic layers identified via mutmut (backend) and Stryker (web) mutation-test configurations. It adds a lint-tdd.sh enforcement script wired into make lint/CI, new rule/skill docs, and updates supporting documentation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Changes

TDD Gate Introduction

Layer / File(s)Summary
ADR-0019 decision document
docs/adr/0019-tdd-for-logic-layer.md
Adds ADR defining TDD scope (reusing ADR-0017 mutation targets), workflow, make lint-tdd gate, Tdd-Exempt mechanism, trade-offs, and links to design principles.
TDD rule and skill documents
.claude/rules/common/tdd.md, .claude/rules/backend/test.md, .claude/rules/web/test.md, .claude/skills/tdd/SKILL.md
Adds common TDD workflow rule, scope-determination sections in backend/web test rules, and a phase-based TDD skill document.
lint-tdd.sh enforcement script
scripts/lint-tdd.sh
Adds a script that resolves base ref, honors Tdd-Exempt/TDD_EXEMPT, parses mutmut/Stryker globs, classifies changed files, and fails when matched implementation changes lack test diffs.
Makefile and CI wiring
Makefile, .github/workflows/test.yml
Adds lint-tdd target wired into lint/help output; CI checkout now uses fetch-depth: 0 and runs a new "Lint SSoT" step invoking the script.
Documentation and agent instruction updates
.claude/CLAUDE.md, CONTRIBUTING.md, docs/development.md, docs/design-principles.md, docs/adr/README.md
Updates commit/PR flow, contributing guide, development docs, principle matrix, and ADR index to reference ADR-0019 and the TDD gate.

Sequence Diagram(s)

sequenceDiagram
participant CI as CI Workflow
participant Script as lint-tdd.sh
participant Git as Git
CI->>Script: bash scripts/lint-tdd.sh
Script->>Git: resolve base ref / merge-base
Script->>Script: check Tdd-Exempt trailer or TDD_EXEMPT=1
alt exempt
Script-->>CI: exit 0 (skip)
else not exempt
Script->>Git: diff changed files vs base
Script->>Script: parse mutmut/stryker globs
Script->>Script: classify impl vs test file changes
alt missing test diff for matched impl
Script-->>CI: ERROR + exit 1
else
Script-->>CI: OK + exit 0
end
end
Loading

Possibly related PRs

  • yusuke0610/devforge#297: Both PRs update .claude/CLAUDE.md's commit/PR flow "stage" instructions.
  • yusuke0610/devforge#398: Both PRs update .claude/CLAUDE.md's commit/PR workflow documentation without overlapping on the TDD gate logic.
  • yusuke0610/devforge#450: Introduces/adjusts backend/pyproject.toml mutmut and web/stryker.conf.json mutation configs that this PR's lint-tdd.sh and TDD rules directly reference.

Suggested labels:documentation, feature, test, agent, ci

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly matches the main change: introducing a TDD harness for deterministic logic-layer changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/tdd-harness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

main に取り込まれた ADR-0018(GitHub連携経歴書ドラフト生成)と
本ブランチの ADR-0019(TDD 導入)が docs/adr/README.md と
docs/design-principles.md で衝突していたため解消(番号順に両方保持)。
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation ci CI / ワークフロー and removed feature 新機能 labels Jul 5, 2026
@yusuke0610
yusuke0610 merged commit f3258b7 into mainJul 5, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the docs/tdd-harness branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciCI / ワークフローdocumentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: 決定論的ロジック層への TDD ハーネスを導入 - #465

Merged
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness
Jul 5, 2026
Merged

feat: 決定論的ロジック層への TDD ハーネスを導入#465
yusuke0610 merged 2 commits into
mainfrom
docs/tdd-harness

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • 決定論的ビジネスロジック層(mutmut/stryker のミューテーションテスト対象と同一スコープ)の実装変更を TDD(red → green → refactor) で行う方針を導入(ADR-0019)
  • ワークフロー正本 .claude/rules/common/tdd.md(backend/web 編集時に自動ロード)を新設し、既存の backend/test.md / web/test.md / CLAUDE.md から誘導
  • 機械ゲート scripts/lint-tdd.shmake lint-tdd)を新設。TDD 対象の実装変更にテスト差分が随伴しているかを検証し、make lint / make ci および CI(test.yml の test-backend ジョブ)に組み込み。振る舞いを変えない変更は Tdd-Exempt: <理由> コミットトレーラーで除外可能
  • AI 向け段階制御スキル /tdd.claude/skills/tdd/SKILL.md)を新設。対象判定 → テスト設計提示 → red(失敗確認)→ green → refactor の各フェーズで停止・報告する
  • docs/development.md / CONTRIBUTING.md に人間向けの概説を追記、docs/adr/README.md / docs/design-principles.md の索引を更新

設計判断

  • TDD 適用スコープは新規リストを作らず、既存の mutation 設定(backend/pyproject.toml[tool.mutmut] only_mutate / web/stryker.conf.jsonmutate)を SSoT として共有(ADR-0017 と対になる事前プロセス)
  • 機械ゲートは「テストファーストの証明」ではなく「テスト差分の随伴」という検証可能な必要条件に限定(限界は ADR-0019 に明記)

Test plan

  • make lint-adr-index green(ADR 索引の drift なし)
  • make lint-tdd の動作確認: 対象ファイルのみ変更→fail / テスト随伴→pass / Tdd-Exempt トレーラー→skip / TDD_EXEMPT=1→skip / stryker 除外パターン(pdfjs.ts)→対象外
  • make ci(lint + backend pytest + web vitest 365 件 + build)green
  • ドキュメント・スクリプト変更のみで backend/web の実行時挙動に影響しないため E2E・smoke は対象外。CI 上で test.yml の新ステップが期待どおり動くことは本 PR の CI 結果で確認する

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a standardized TDD workflow for deterministic logic changes, including red → green → refactor guidance and an exemption path for behavior-only edits.
    • Added a new lint check to verify test coverage stays aligned with implementation changes.
  • Documentation
    • Updated development and contributing guidance to explain when the TDD workflow applies and how to validate it.
    • Expanded architecture and design-principles docs to reflect the new quality process.

ミューテーションテスト対象(mutmut/stryker)と同一スコープの実装変更を
red→green→refactor で行う方針を導入する。ワークフロー正本
(.claude/rules/common/tdd.md)、機械ゲート(scripts/lint-tdd.sh /
make lint-tdd、test.yml に組み込み)、AI 向け段階制御スキル(/tdd)を
新設し、既存ルール・development.md・CONTRIBUTING.md から誘導する。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yusuke0610, you've reached your PR review limit, so we couldn't start this review.

Next review available in:22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22cbd120-2bdc-4f14-b87d-4868259a0028

📥 Commits

Reviewing files that changed from the base of the PR and between ff27798 and 9501a1d.

📒 Files selected for processing (2)
  • docs/adr/README.md
  • docs/design-principles.md
📝 Walkthrough

Walkthrough

This PR introduces ADR-0019 to mandate test-driven development (red→green→refactor) for changes to deterministic logic layers identified via mutmut (backend) and Stryker (web) mutation-test configurations. It adds a lint-tdd.sh enforcement script wired into make lint/CI, new rule/skill docs, and updates supporting documentation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Changes

TDD Gate Introduction

Layer / File(s)Summary
ADR-0019 decision document
docs/adr/0019-tdd-for-logic-layer.md
Adds ADR defining TDD scope (reusing ADR-0017 mutation targets), workflow, make lint-tdd gate, Tdd-Exempt mechanism, trade-offs, and links to design principles.
TDD rule and skill documents
.claude/rules/common/tdd.md, .claude/rules/backend/test.md, .claude/rules/web/test.md, .claude/skills/tdd/SKILL.md
Adds common TDD workflow rule, scope-determination sections in backend/web test rules, and a phase-based TDD skill document.
lint-tdd.sh enforcement script
scripts/lint-tdd.sh
Adds a script that resolves base ref, honors Tdd-Exempt/TDD_EXEMPT, parses mutmut/Stryker globs, classifies changed files, and fails when matched implementation changes lack test diffs.
Makefile and CI wiring
Makefile, .github/workflows/test.yml
Adds lint-tdd target wired into lint/help output; CI checkout now uses fetch-depth: 0 and runs a new "Lint SSoT" step invoking the script.
Documentation and agent instruction updates
.claude/CLAUDE.md, CONTRIBUTING.md, docs/development.md, docs/design-principles.md, docs/adr/README.md
Updates commit/PR flow, contributing guide, development docs, principle matrix, and ADR index to reference ADR-0019 and the TDD gate.

Sequence Diagram(s)

sequenceDiagram
participant CI as CI Workflow
participant Script as lint-tdd.sh
participant Git as Git
CI->>Script: bash scripts/lint-tdd.sh
Script->>Git: resolve base ref / merge-base
Script->>Script: check Tdd-Exempt trailer or TDD_EXEMPT=1
alt exempt
Script-->>CI: exit 0 (skip)
else not exempt
Script->>Git: diff changed files vs base
Script->>Script: parse mutmut/stryker globs
Script->>Script: classify impl vs test file changes
alt missing test diff for matched impl
Script-->>CI: ERROR + exit 1
else
Script-->>CI: OK + exit 0
end
end
Loading

Possibly related PRs

  • yusuke0610/devforge#297: Both PRs update .claude/CLAUDE.md's commit/PR flow "stage" instructions.
  • yusuke0610/devforge#398: Both PRs update .claude/CLAUDE.md's commit/PR workflow documentation without overlapping on the TDD gate logic.
  • yusuke0610/devforge#450: Introduces/adjusts backend/pyproject.toml mutmut and web/stryker.conf.json mutation configs that this PR's lint-tdd.sh and TDD rules directly reference.

Suggested labels:documentation, feature, test, agent, ci

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly matches the main change: introducing a TDD harness for deterministic logic-layer changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/tdd-harness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

main に取り込まれた ADR-0018(GitHub連携経歴書ドラフト生成)と
本ブランチの ADR-0019(TDD 導入)が docs/adr/README.md と
docs/design-principles.md で衝突していたため解消(番号順に両方保持)。
@github-actionsgithub-actionsBot added feature 新機能 documentation Improvements or additions to documentation ci CI / ワークフロー and removed feature 新機能 labels Jul 5, 2026
@yusuke0610
yusuke0610 merged commit f3258b7 into mainJul 5, 2026
20 checks passed
@yusuke0610
yusuke0610 deleted the docs/tdd-harness branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciCI / ワークフローdocumentationImprovements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yusuke0610