Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions .claude/hooks-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,23 @@ grep_recent_limit = 20 # jj log で参照する直近 commit 数
# 順位 177 (PR #197 で Tier 1 (優先実装) 格上げ) で実装。
# PostToolUse Edit/Write 直後にファイルサイズを確認し、threshold (50KB) 超過時に
# additionalContext でファイル分割を促す。Claude Code 読み取り安定性閾値 (50KB) を
# 機械強制する Layer 0.5。
# 機械強制する custom linter。
#
# ADR-039 § 1.b mechanical lint 例外で default ON (PR #203 で訂正、本 PR で適用):
# - 失敗 mode が non-blocking (additionalContext warning のみ、ブロックしない)
# - 判定が決定論的 (50KB 固定閾値、discretionary 判断なし)
# - 適用 scope が宣言的に限定 (paths glob)
# - recovery hint が明確 (todo*.md なら新 todo<N+1>.md を新設して移管)
# 同類例: 順位 147 file_length lint (hooks-post-tool-comment-lint-rust) も default ON 固定。
#
# ADR-039 § 3 opt-in pattern: default OFF (enabled = false)、明示有効化で発火。
# touch-trigger ratchet (default true): 触られたファイルのみチェック = 既存超過
# ファイルは未編集なら grandfather。strict mode (touch_trigger=false で全 enabled
# paths を scan) は MVP では受理のみ、3-5 PR の dogfood 後に判定 (bounded lifetime)
# paths を scan) は MVP では受理のみ。
#
# Kill-switch: enabled = false で完全停止。
[post_tool_use.file_size_check]
enabled = false # opt-in (明示有効化で発火、ADR-039 § 3 bounded lifetime: 3-5 PR dogfood 後に default-ON 昇格判定)
threshold_bytes = 51200 # 50KB (= 50 * 1024)
enabled = true # ADR-039 § 1.b mechanical lint 例外 (non-blocking + 決定論 + scope 限定 + recovery hint 明確)
threshold_bytes = 51200 # 50KB (= 50 * 1024)、Claude Code 読み取り安定性閾値
paths = ["docs/**/*.md", "src/**/*.rs"] # default 対象 glob
touch_trigger = true # 触られたファイルのみ check (ratchet)

Expand Down
4 changes: 0 additions & 4 deletions docs/adr/adr-007-custom-linter-layer-boundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,3 @@ PR #98 (Bundle Y2) post-merge-feedback で `post-pr-review.yaml` supervise step
- TOML rule コメントに field 拡張手順を 4 ステップで記述(grep → alternation 追加 → test helper 追加 → fixture test + TOML test 宣言追加)
- 各 field について `<rule>_detects_<field>_violation` 命名規約で個別 fixture test を確保(一括 test では削除回帰が検知不可能)
- `[rules.test_coverage.main_ext_tests]` 宣言で test 名を機械強制レイヤに接続する

## Layer 0.5 追記: file_size_check (2026-06-07、順位 177 由来)

`[post_tool_use.file_size_check]` (PR #197 land、`hooks-post-tool-linter` 統合) は本 ADR の Q1/Q2/Q3 判断フロー対象外。ファイル content を読まず metadata (`std::fs::metadata.len()`) のみで判定する **正規表現層未満の Layer 0.5** に位置し、Layer 0 (UTF-8 整合性) と Layer 1 (正規表現 custom-rules) の間で発火する。`paths` glob filter (順位 102 / Phase D D-3 と同 helper 共有) で対象を絞り、ADR-039 opt-in pattern (default OFF + bounded lifetime dogfood) で導入リスクを抑制する。同型 (metadata-only、content 非依存) の future check は同 Layer 0.5 に追加することで regex/AST 層との責務分離が維持される。
47 changes: 45 additions & 2 deletions docs/adr/adr-039-experimental-feature-standard-pattern.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,43 @@

試験運用 feature を導入する際の **標準パターン** として 3 点セットを以下の通り規定する。新規試験運用 ADR は本 ADR を **参照** し、3 点を満たすことを default とする。

### 1. Config opt-in (デフォルト無効)
### 1. Config opt-in (デフォルト無効) — 適用対象を明示

本 § は **behavior の妥当性が不確定な** experimental feature に適用する。具体的には:

- 挙動が後の dogfood で「失敗 / 却下 / 方向転換」されうるもの
- false positive 発生時に多数 user / session に影響するもの
- 採否判定 (採用 / 却下 / 継続) のフェーズが必要なもの

該当する場合:

- 設定ファイル (`*.toml`) または env var で `enabled = false` をデフォルトとする
- 明示有効化 (`enabled = true`) で feature 発動
- env var / config 値での切り替えを必ず提供 (config-only より env override 可能な方が望ましい)
- 派生プロジェクト (techbook-ledger / auto-review-fix-vc 等) への deploy 時にも default OFF が継承されるよう、`[feature]` section の追加を必須化

### 1.b 適用対象外: 決定論的 mechanical lint (default ON 許容、PR #203 post-merge-feedback 由来)

以下条件をすべて満たす機能は § 1 (default OFF) の対象外とし、**default ON で配布してよい**:

1. **失敗 mode が non-blocking**: block ではなく additionalContext / warning のみ (ユーザー操作を妨げない)
2. **判定が決定論的**: 閾値 (例: 50KB) / 文字列 match (例: regex) / metadata 演算で discretionary 判断を含まない
3. **影響範囲が宣言的に限定**: scope filter (`paths` glob / extension match 等) で適用箇所が config or const で限定済み
4. **recovery hint が明確**: 違反検出時に「次にやるべきこと」が message に含まれる

該当する例 (本リポジトリで既に default ON 稼働中):

- **順位 147 file_length lint** (`hooks-post-tool-comment-lint-rust`、Rust source 800 行 max): `const MAX_FILE_LINES = 800` で固定、config 不在 = ON 固定
- **順位 177 file_size_check** (`hooks-post-tool-linter` § Layer 0.5、metadata-only 50KB threshold): touch-trigger ratchet で grandfather + paths glob で scope 限定

該当**しない**例 (default OFF が正しい):

- post-merge-feedback (ADR-014/030): 挙動が dogfood で確定する experimental
- weekly-review (ADR-031): 採否判定要、reminder 頻度や observation rubric が dogfood で進化
- local-llm-finding-classification (ADR-038): classification 精度が dogfood で判定

**過去の誤適用**: PR #197 で順位 177 file_size_check を ADR-039 § 1 機械適用で default OFF にしたが、本 PR (PR #203 post-merge-feedback 由来) で「決定論的 mechanical lint = § 1.b 例外で default ON」へ訂正。順位 147 と同様の扱いに統一。

### 2. Kill-switch (停止経路の事前明文化)

- revert PR で `enabled = false` に戻す経路を **PR body / ADR で明文化**
Expand Down Expand Up @@ -82,7 +112,20 @@ decision trigger は **config (TOML コメント) / code comment (module doc) /

### 新規 experimental feature 追加時の self-review checklist

新規 experimental feature を追加する PR では、push 前 self-review で以下 4 点の整合を **mechanical に** 確認する。各点は discretionary 判断を含まず、config / code / docs / test の差分を機械的に照合できる:
新規 feature を追加する PR では、push 前 self-review で以下 5 点 (上位 1 件 + mechanical 4 件) の整合を確認する。**上位判定で「§ 1.b 例外」に該当した場合は 4 点 checklist を skip し、default ON で配布**する:

#### 0. 上位判定: そもそも § 1 適用対象か? (PR #203 post-merge-feedback 由来)

§ 1.b の 4 条件 (non-blocking / 決定論 / scope 限定 / recovery hint 明確) をすべて満たすか self-check する:

- **すべて満たす** → § 1.b 例外、default ON で配布 (順位 147 file_length lint / 順位 177 file_size_check と同 pattern)
- **1 つでも欠ける** → § 1 適用、以下 4 点 checklist を実施

判断に迷う場合は 4 点 checklist を実施する側 (default OFF) を選択 (= conservative default)。本判定を skip して機械的に 4 点 checklist を実施すると、決定論的 mechanical lint を誤って opt-in 化する over-application が発生する (PR #197 順位 177 で実観測、PR #203 で訂正)。

#### 1-4. § 1 適用時の mechanical 4 点 (config / code / docs / test)

各点は discretionary 判断を含まず、config / code / docs / test の差分を機械的に照合できる:

1. **config schema**: 該当 hook / module の config struct (例: `WeeklyReviewReminderConfig`) が `enabled: Option<bool>` field を持つ
2. **feature flag default OFF**: 該当 config の `enabled` の default が **OFF** (= `unwrap_or(false)`) になっている。`unwrap_or(true)` は § 決定 1 (Config opt-in) 違反
Expand Down
Loading