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
42 changes: 42 additions & 0 deletions .claude/custom-lint-rules.toml
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,45 @@ steps = [
[rules.example]
bad = "comments.iter().filter(|c| c.created_at > push_time)"
good = "comments.iter().filter(|c| c.created_at >= push_time)"

# ─── ルール⑧: docs/ 内 Markdown の `../docs/` 相対パストラップ検出 ───
#
# 由来: PR #133 (50KB 分割系列、Bundle j-1 = 順位 94 採用) で
# `[ADR-036](../docs/adr/adr-036-...)` 形式の壊れ link が docs/ 配下で混入し
# CodeRabbit Minor 指摘。docs/ 配下のファイルから `../docs/` を辿ると `docs/docs/` を
# 指すため directory nesting mismatch で必ず broken link。pre-existing bug が分割で
# 表面化した経緯。Custom lint rule で書いた瞬間に block すれば本 bug class が排除される。
#
# Bundle Z #B-α と同じ「決定論的防止層」哲学 (ADR-007 の正規表現層)。
#
# 自己限定設計 (extensions = ["md"] のみ、`paths` filter なし):
# pattern `](../docs/` は parent-directory 参照を伴う `docs/` への back-link で、
# 文書 が docs/ 配下 (または同等位置) にある場合のみ意味を持つ。root-level README.md
# 等の通常 Markdown では `](docs/...)` 形式が自然で `](../docs/...)` は出現しない
# ため、pattern semantics で自己限定される。
#
# Self-exclusion: 本 TOML の message / why / example で説明文として `](../docs/`
# 形式を直接記述しないこと (lint 対象は extensions = ["md"] のみで .toml は対象外
# だが、説明用に書く場合も backtick code 内の同パターンが他文書に流れる事故を予防)。

[[rules]]
id = "no-docs-relative-back-to-docs"
# case-insensitive で safety margin (URL fragment / Windows path 大文字違い等)
pattern = '(?i)\]\(\.\./docs/'
severity = "error"
message = "`docs/` 配下から `../docs/` への相対参照は directory nesting mismatch で必ず broken link になります"
why = "PR #133 で同パターンの壊れ link が混入し CodeRabbit Minor 指摘 (docs/ 内 file から `../docs/` を辿ると `docs/docs/` を指すため必ず not found)。`(filename.md)` (同階層) または `adr/file.md` (sub-dir) で書く"
extensions = ["md"]

[rules.fix]
strategy = "相対パスを正しい階層に置き換え"
steps = [
"同階層の場合: `[text](filename.md)` (相対参照なし)",
"サブディレクトリの場合: `[text](adr/filename.md)` 等の forward path",
"親ディレクトリ (docs/ の外) を参照したい場合: `../<外側>/` (docs/ を再参照しない)",
]

[rules.example]
# 説明文中で実際の trap pattern を直接書かないため、placeholder 形式で示す
bad = "[ADR-036](DOTDOT/docs/adr/adr-036-...) <!-- DOTDOT は ../ の意。実際は `..` 2 文字 -->"
good = "[ADR-036](adr/adr-036-...)"
14 changes: 13 additions & 1 deletion docs/local-llm-offload-analysis.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,24 @@ cargo test -p cli-finding-classifier --test lint_screen_evals -- \

| Order | 構成 | Effort | Diff Profile | dogfood signal |
|---|---|---|---|---|
| P-1 | Bundle h (順位 89+90) + Bundle g-2 (順位 87+88) | M | global rules markdown 4 file (うち project diff には ADR-039 + cross-link + todo cleanup のみ) | docs-only で `informational` 期待、false-positive 検証 baseline。**本 PR では config switch を commit に乗せない方針 (Phase d guide §1) のため pipeline 経由の lint_screen は未実行、cli-finding-classifier 直叩きでの classifier preview のみ取得**: latency 23s / findings 0 / fallback (JSON parse error: missing field `screen_decision`) — 順位 98 (`num_ctx` overflow detection) の必要性を再確認する signal。real pipeline 経由の P-1 metric は後続 dogfood で取得 (P-2 移行時に再検討) |
| P-1 | Bundle h (順位 89+90) + Bundle g-2 (順位 87+88) ✅ **完了 (PR #139、2026-05-10)** | M | global rules markdown 4 file (project diff ADR-039 + cross-link + todo cleanup のみ) | classifier preview のみ取得 (real pipeline 未実行)。詳細は本 table 直後の **P-1 dogfood outcome** 参照 |
| P-2 | Bundle j-1 (順位 94 — `../docs/` 相対パス detect lint rule) | S | TOML config + 軽い Rust regex | 小規模 mixed diff |
| P-3 | Bundle g-1 (順位 85+86 — cli-pr-monitor verdict guard + transition test) | M | Rust impl + Rust test | 中規模 Rust、`auto_fix` 期待 |
| P-4 | Bundle d (順位 68 — no-ephemeral-todo-reference self-exclusion test) | S | Rust test only | 狭 scope test diff |
| P-5 | Bundle c-1 (順位 63+64+67 — cli-merge-pipeline Drop guard + reaper + ADR) | L | Rust impl ×2 + ADR | 大規模 Rust (PR #132 868 行 stress 再現候補) |

**P-1 dogfood outcome (PR #139、2026-05-10)**:

- **classifier preview metrics** (cli-finding-classifier 直叩き、real pipeline 経由ではない):
- latency: 23s (eval baseline p95=8.4s の ~3x、337-line diff サイズ起因の推定)
- findings: 0 (空配列)
- screen_decision: `human_review` (fallback path activated)
- fallback_reason: `JSON parse error: missing field 'screen_decision'` — num_ctx=8192 でも 337-line diff で出力 truncate の可能性
- **Phase d 学習**: 順位 98 (`num_ctx` overflow detection diagnostic warn log) の必要性を再確認 = mistral:7b 出力崩壊を runtime hint で即診断する優先度が確定
- **post-merge-feedback (10 findings → 1 件採用)**: T3 #1 (development-workflow.md に 「同一ファイル複数編集の 1 task 統合」 + 「partial completion + 後続 PR 追補明記」 の 2 pattern 追補) を採用 → **順位 100** として登録済。様子見 3 件 / 却下 5 件 (詳細は `.claude/feedback-reports/139.md`)
- **観測 caveat**: post-merge-feedback agent が PR #139 で初観測した `baselinebaseline` (table cell 内連続単語重複) は session/prepush 間で観測が矛盾 (jj cache stale 疑い、未確定)。Frequency Low 単独で T1 #1 連続重複単語 lint / T1 #2 jj cache validation は様子見 / 却下。3 PR 観測閾値で再評価
- **real pipeline 経由 P-1 metric**: P-2 (Bundle j-1) 移行時に再検討 = lint_screen を session-only opt-in で動かす機会を改めて作る (commit pollution 回避と integration test の trade-off は P-2 で再判断)

**設計判断のポイント**:
- **Effort 分布 M→S→M→S→L**: 前半小規模 / 後半大規模で kill-switch (fallback > 50%) signal の質を切り分け可能 (小規模で発動 = 設計 issue / 大規模で発動 = num_ctx 再到達)
- **Bundle h + g-2 を 1 PR に統合**: 共通テーマ「global rules consolidation (process/lifecycle codification)」、reviewer も「rule 追加 4 件まとめ」として認識しやすい
Expand Down
4 changes: 2 additions & 2 deletions docs/todo-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@
| 91 | 🔧 Tier 2 | **`[lint_screen]` config parse テスト (PR #132 T2-#4 採用) ★ Bundle i** | todo6.md | S | なし (PR #132 で追加した push-runner-config.toml の `[lint_screen]` section に対する toml::from_str テスト、CodeRabbit nitpick 起点、silent field rename 防止) |
| 92 | 🔧 Tier 2 | **scale-aware eval fixtures (200+ 行) — Phase d 投入前の必須 infrastructure (PR #132 T2-#5 採用) ★ Bundle i** | todo6.md | M | 順位 91 と同 PR 推奨 (Bundle i コア、PR #132 smoke で観測した mistral:7b 大規模 diff JSON 不完全 (`missing field 'screen_decision'`) を fixture 化、Phase d 着手前の改善 ループ reference point 確保) |
| 93 | 💎 Tier 3 | **`coding-style.md` Cross-File Reference Lifecycle に partial fix 例を追記 (PR #132 T3-#8 採用)** | todo6.md | XS | なし (PR #94 / #111 / #132 で反復した「変更差分外ファイルへの partial fix 再発」パターンを anti-pattern 例として codify、独立並列実施可) |
| 94 | 🚀 Tier 1 | **`docs/` 内 Markdown の `../docs/` 相対パストラップ検出 lint rule (PR #133 T1-1 採用) ★ Bundle j** | todo6.md | S | なし (PR #133 で `docs/todo7.md` L103 が `../docs/adr/...` で broken link 化した実例。`docs/` 配下から `../docs/` は常に誤りで FP 極小、`(?i)\]\(\.\./docs/` の regex 1 行で決定論的に防止) |
| 95 | 🔧 Tier 2 | **`docs/todo*.md` preamble file count 自動照合スクリプト (PR #133 T2-#4 採用) ★ Bundle j** | todo6.md | S | なし (PR #133 で todo6.md「六つ」/ todo7.md「七つ」が実 8 ファイルと乖離した実例。todo*.md 分割が今後も繰り返す pattern (todo3 → 4 → 5 → 6 → 7) のため CI 層で自動検証) |
| 96 | 🔧 Tier 2 | **Markdown cross-reference validator CI step (PR #133 T2-#3 採用) ★ Bundle j** | todo6.md | M | 順位 10 (ADR-032 PR-broken-link) と方向性が近接、fold-in 検討の余地あり。順位 94 (regex 規約) + 順位 95 (count 照合) と組み合わせて docs/ 整合性の多層検証 |
| 97 | 🔧 Tier 2 | **`with_num_ctx(X)` override 値 serialization 検証テスト (PR #136 T2-#1 採用)** | todo6.md | S | なし (PR #136 で追加した builder method の wiring を mockito で seal、Phase d で num_ctx tweak する局面の silent degrade 防止、CodeRabbit が見逃した test gap を post-merge-feedback agent が独立発見) |
| 98 | 🚀 Tier 1 | **`num_ctx` overflow detection — JSON parse error 検知時の context window 診断ログ (PR #137 T1-#1 採用)** | todo6.md | M | なし (PR #136 で誤診 pivot を発生させた blind spot を decisive に塞ぐ runtime hint、`lib-ollama-client` の response validation 層に warn log 追加、`prompt_eval_count` ≈ `num_ctx` cap で truncation を即診断) |
| 99 | 💎 Tier 3 | **ADR-038 に PR #138 learning 2 件を追記 (cost-aware 実装層選択 + attention dilution pitfall) (PR #138 T3-#1+#2 採用)** | todo6.md | S | なし (lint_screen が takt facet → Rust stage に pivot した cost 根拠 + Phase b' v2 の diff header full 追加で agreement 75%→50% 33pt 低下した attention dilution 観測の 2 件を ADR に codify、次回 LLM 系 feature 開発時の prior assumption に) |
| 100 | 💎 Tier 3 | **`development-workflow.md` に 「同一ファイル複数編集の 1 task 統合」 + 「partial completion + 後続 PR 追補明記」 を追補 (PR #139 T3-#1 採用)** | todo6.md | XS | なし (PR #119/#120/#121 sub-PR 分割 + PR #139 partial completion で systemic に観測された 2 暗黙知を `~/.claude/rules/common/development-workflow.md` に codify、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化のため非機械強制でも採用相当) |

**戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。

Expand Down Expand Up @@ -110,4 +110,4 @@

**PR #114 (Bb-2 + 順位 75 = Bundle b PR-2 + T2-2) post-merge-feedback (2026-05-05)** ✅ 完了: 9 findings に対して **2 件採用 / 5 件様子見 / 3 件却下**。**Bb-3 (順位 55) で fold-in する採用提案**: T2-2 (Parity test coverage 拡張 = `finalize_park_siblings_have_symmetric_write_state_handling` テストに `finalize_initial_review_park` を追加、self-violation 解消、Effort S)。T2-1 (Legacy JSON deserialize test) は **PR #114 で既に実装済** (`state_legacy_json_without_new_fields_deserializes_with_defaults`、Bb-3 以降の新フィールド追加時に同 pattern を継続するための reference として保存)。**様子見 (5 件)**: T1-1 (finalize_* parity lint、Effort M + NLP 必要、簡易プロキシで再評価) / T1-2 (polling block lint、FP リスクで dogfood 後判断) / T2-3 (env override コメント強化、XS Low) / T2-4 (CI parallel race 確認、preventive only) / T3-1 (Wakeup Resume Invariant ADR) / T3-2 (DI 戦略 ADR、Bb-3 着手時に再検討)。**却下 (3 件)**: T1-3 (Serde schema lint、ROI 低、T2-1 で代替) / T3-3 (parity invariant の global rules 追加) / T3-4 (test-only env var prefix rule) — 後 2 件は **memory: feedback_no_unenforced_rules.md** を直接引用してアナライザが正しく即却下判定。Bb-2 land 時点で Bundle b の核 (CronCreate park モデル) 完成、残る Bb-3 は config 整理 + SessionStart catch-up + T2-2 follow-up を bundled。

**Bundle j (PR #133 post-merge-feedback、docs/ 整合性多層検証、2026-05-09)**: PR #133 (todo.md / todo5.md 50KB 分割) merge 後の post-merge-feedback で 9 findings 中 **3 件採用** (Tier 1 #1 / Tier 2 #3, #4) で **3 層対策**: (1) **規約層** = 順位 94 (`(?i)\]\(\.\./docs/` regex 1 行で `docs/` 配下からの逆戻り参照を block) は CodeRabbit が PR #133 で実検出した broken link を決定論的に防止、(2) **CI 検証層** = 順位 95 (preamble file count 自動照合) は todo*.md 分割が今後反復する pattern (todo3 → 4 → 5 → 6 → 7) のため Frequency Medium で採用、(3) **包括的 link 検証層** = 順位 96 (Markdown cross-reference validator、directory-aware resolution) は順位 10 (ADR-032 PR-broken-link) と方向性近接で fold-in 検討余地あり。**Sub-PR 分割推奨**: j-1 (順位 94、`.claude/custom-lint-rules.toml` 規約追加、Effort S、独立) / j-2 (順位 95 + 96、`.github/workflows/lint.yml` 新設 = workflows 未存在 repo の最初の workflow 整備、Effort S+M、まとめて land が効率的)。**却下** (2 件): T1 #2 (prose 数詞 lint、NLP 必要 + FP 確実) / T3 #5/#6 (機械検知不可ルール追加、`feedback_no_unenforced_rules.md` 適用)。**様子見** (3 件): T3 #7 (ADR-035 not_applicable と GitHub thread state の乖離明文化、1 観測のみ) / T3 #8 (ADR-030 AFK wakeup 時 PR body intent ルール化、1 観測のみ) / T3 #9 (50KB 分割原則 CLAUDE.md 明文化、機械検知不可)。**本 PR 含意**: 順位 94 = 「決定論的防止層」哲学 (Bundle Z #B-α 系譜)、順位 95-96 = 「規約だけでは塞げない構造的検証は CI で」(ADR-031 週次レビューと相補)。`.github/workflows/` 未存在 repo に最初の workflow を追加する転換点でもあり、scope 慎重判断が必要。
**Bundle j (PR #133 post-merge-feedback、docs/ 整合性多層検証、2026-05-09)**: PR #133 (todo.md / todo5.md 50KB 分割) merge 後の post-merge-feedback で 9 findings 中 **3 件採用** (Tier 1 #1 / Tier 2 #3, #4) で **3 層対策**: (1) **規約層** = 順位 94 (`(?i)\]\(\.\./docs/` regex 1 行で `docs/` 配下からの逆戻り参照を block) は CodeRabbit が PR #133 で実検出した broken link を決定論的に防止、(2) **CI 検証層** = 順位 95 (preamble file count 自動照合) は todo*.md 分割が今後反復する pattern (todo3 → 4 → 5 → 6 → 7) のため Frequency Medium で採用、(3) **包括的 link 検証層** = 順位 96 (Markdown cross-reference validator、directory-aware resolution) は順位 10 (ADR-032 PR-broken-link) と方向性近接で fold-in 検討余地あり。**Sub-PR 構成**: **j-1 (順位 94、`.claude/custom-lint-rules.toml` 規約追加) は land 済 (Phase d P-2)** / j-2 (順位 95 + 96、`.github/workflows/lint.yml` 新設 = workflows 未存在 repo の最初の workflow 整備、Effort S+M、まとめて land が効率的)。**却下** (2 件): T1 #2 (prose 数詞 lint、NLP 必要 + FP 確実) / T3 #5/#6 (機械検知不可ルール追加、`feedback_no_unenforced_rules.md` 適用)。**様子見** (3 件): T3 #7 (ADR-035 not_applicable と GitHub thread state の乖離明文化、1 観測のみ) / T3 #8 (ADR-030 AFK wakeup 時 PR body intent ルール化、1 観測のみ) / T3 #9 (50KB 分割原則 CLAUDE.md 明文化、機械検知不可)。**本 PR 含意**: 順位 94 = 「決定論的防止層」哲学 (Bundle Z #B-α 系譜)、順位 95-96 = 「規約だけでは塞げない構造的検証は CI で」(ADR-031 週次レビューと相補)。`.github/workflows/` 未存在 repo に最初の workflow を追加する転換点でもあり、scope 慎重判断が必要。
Loading