Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
46 changes: 46 additions & 0 deletions .claude/custom-lint-rules.toml
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,49 @@ steps = [
# 説明文中で実際の trap pattern を直接書かないため、placeholder 形式で示す
bad = "[ADR-036](DOTDOT/docs/adr/adr-036-...) <!-- DOTDOT は ../ の意。実際は `..` 2 文字 -->"
good = "[ADR-036](adr/adr-036-...)"

# ─── ルール⑨: takt workflow yaml で persona: を持つ step に model: 必須 ───
#
# 由来: Bundle Y2 (PR #98) で post-pr-review.yaml supervise step に model: が
# 未指定であることが post-merge-feedback で指摘された。persona: を持つ step で
# model: 未指定は default に落ちるため、Bundle Y2 ゴール (analyze 系 haiku /
# supervise・fix は sonnet) では現時点で偶然合致しているが、将来 default 変更や
# persona 追加で意図せぬモデル選択が混入しうる。custom-lint-rule で書いた瞬間に
# block すれば bug class が排除される。
#
# Bundle Z #B-α と同じ「決定論的防止層」哲学 (ADR-007 の正規表現層)。
#
# 検出ロジック (multi-line regex):
# persona: 行の直後の indented field 行が「model: 以外」の場合に flag する。
# field 名 enumeration 方式で takt yaml の sibling field を列挙し、新規 field が
# 増えた際は明示的に rule 拡張する形を取る (= 学習機会化)。Rust regex は lookahead
# 非対応のため negation by enumeration が pragmatic。
#
# Path filter (.takt/workflows/*.yaml 限定):
# 順位 102 (PR #148) で実装した paths filter で範囲を絞り、.github/workflows/
# 等の他 yaml への誤発火を防ぐ。

[[rules]]
id = "takt-workflow-persona-without-model"
pattern = '(?m)^[ \t]+persona:[ \t]+[\w-]+[ \t]*\r?\n[ \t]+(?:policy|instruction|edit|provider_options|knowledge|condition|rules|inputs|outputs|allowed_tools|disallowed_tools|name|type|cmd|when|description|tool|tools):'
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
severity = "error"
message = "takt workflow で persona: の直後に model: が指定されていません。default 落ち防止のため model: <sonnet|haiku|opus> を明示してください"
why = "PR #98 post-merge-feedback で post-pr-review.yaml supervise step の model: 未指定が指摘された。default 落ちは将来 default 変更や persona 追加で意図せぬモデル選択を生む。Bundle Z #B-α と同じ決定論的防止層 (ADR-007 の正規表現層)"
extensions = ["yaml"]
paths = [".takt/workflows/*.yaml"]

[rules.fix]
strategy = "persona: の直後に model: <sonnet|haiku|opus> を追加"
steps = [
"supervisor 系 step: model: sonnet を追加 (deep reasoning が必要)",
"code-reviewer 系 analyze step: model: haiku を追加 (低 cost で十分)",
"coder 系 fix step: model: sonnet を追加 (Bundle Y2 既定)",
"judge / loop_monitor block の persona: にも明示推奨 (clean baseline 維持)",
]

[rules.example]
bad = ''' persona: supervisor
instruction: loop-monitor-reviewers-fix'''
good = ''' persona: supervisor
model: sonnet
instruction: loop-monitor-reviewers-fix'''
2 changes: 2 additions & 0 deletions .takt/workflows/post-pr-review.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ loop_monitors:
threshold: 2
judge:
persona: supervisor
model: sonnet
instruction: loop-monitor-reviewers-fix
rules:
- condition: Healthy (progress being made)
Expand Down Expand Up @@ -115,6 +116,7 @@ steps:
- name: supervise
edit: false
persona: supervisor
model: sonnet
policy: review
provider_options:
claude:
Expand Down
1 change: 1 addition & 0 deletions .takt/workflows/pre-push-review.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ loop_monitors:
threshold: 2
judge:
persona: supervisor
model: sonnet
instruction: loop-monitor-reviewers-fix
rules:
- condition: Healthy (progress being made)
Expand Down
44 changes: 35 additions & 9 deletions docs/local-llm-offload-analysis.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> **位置づけ**: 本ファイルは「残作業の **次に何をするか** だけ」を持つ実行計画。完了済みの分析・実装・dogfood 計測・retrospective は [local-llm-offload-history.md](local-llm-offload-history.md) に切り出した。
>
> **状態**: 試験運用 (Phase a 完了 = PR #130 land / Phase b 完了 = conditional GO 2026-05-08, PR #131 / Phase c MVP 完了 = PR #132 land 2026-05-08 / **Phase c+ Bundle i 完了 = PR #135 land 2026-05-09 / §8.D 完了 = PR #136 land 2026-05-09 (num_ctx 8192、agreement 86.7% / verdict GO) / Phase d kickoff prep 完了 = 2026-05-10 ([docs/local-llm-offload-phase-d-guide.md](local-llm-offload-phase-d-guide.md) 参照)**、実 dogfood (3-5 PR、long-running) 待機)。
> **状態**: 試験運用 (Phase a 完了 = PR #130 land / Phase b 完了 = conditional GO 2026-05-08, PR #131 / Phase c MVP 完了 = PR #132 land 2026-05-08 / **Phase c+ Bundle i 完了 = PR #135 land 2026-05-09 / §8.D 完了 = PR #136 land 2026-05-09 (num_ctx 8192、agreement 86.7% / verdict GO) / Phase d kickoff prep 完了 = 2026-05-10 / Phase d Round 1 完遂 = 2026-05-12 (D-1〜D-3、実 dogfood は D-3 単独 1 data point) / Phase d Round 2 着手 = 2026-05-13 (D-4〜D-7、累積 5 PR で Phase E gate 充足見込み)** ([docs/local-llm-offload-phase-d-guide.md](local-llm-offload-phase-d-guide.md) 参照))。
Comment thread
coderabbitai[bot] marked this conversation as resolved.
>
> **引退条件**: 以下のいずれかで本ファイルを削除する (docs-governance.md retirement workflow 準拠)。`local-llm-offload-history.md` も同タイミングで判断する。
> - 残作業 (§8.D / §8.E / §8.F, §1 Phase b/c/d) が **すべて land または却下** された場合 → permanent value (採用された設計判断、却下理由) を ADR-038 に migrate して両ファイルを削除
Expand Down Expand Up @@ -229,11 +229,11 @@ Phase A 実装後、PR #141 (P-3 = 187 行 mixed diff) を replay → **`prompt_

`src/cli-push-runner/src/stages/lint_screen.rs` 改修: graceful fallback (exit 0) 時にも classifier stderr を `.takt/lint-screen-report.md` の `## Diagnostic` section に取込。Phase A 診断 warn log が **real pipeline 経由で visible** になる状態を確保。新 struct `ClassifierOutput { stdout, stderr }`、新 helper `render_diagnostic`、新規 smoke test 4 件 (TP / FP / edge case / parse-error path) で contract を seal。lint_screen tests 14/14 pass + workspace 全 cargo test pass。

##### Phase D: Clean dogfood validation (real pipeline 経由、計画完遂 2026-05-12)
##### 🔄 Phase D: Clean dogfood validation (real pipeline 経由、Round 1 完遂 2026-05-12 / Round 2 D-4〜D-7 着手中 2026-05-13)

Phase C fix + Phase D 前提整備 (順位 109) 完了で **real pipeline 経由 dogfood の必要十分条件が揃った**。D-1 着手時に session-only opt-in workflow が jj auto-snapshot と本質的に衝突する gap が判明したが、**順位 115 (`LINT_SCREEN_ENABLED` env var override) land で解消**。env var 経路 (`$env:LINT_SCREEN_ENABLED = "true"`) で `push-runner-config.toml` を編集せずに lint_screen を有効化できるため、D-3 で初の実 dogfood が成立し、計画 3 PR + prereq 1 PR がすべて land 完了。

**Phase D 対象 PR 構成 (2026-05-12 完遂)**:
**Phase D Round 1 対象 PR 構成 (D-1〜D-3、2026-05-12 完遂)**:

| Order | 構成 (todo-summary.md priority list より) | Effort | 実 diff 行 | Diff Profile | 状態 |
|---|---|---|---|---|---|
Expand Down Expand Up @@ -273,15 +273,41 @@ Phase C fix + Phase D 前提整備 (順位 109) 完了で **real pipeline 経由
4. **1 false positive は Phase b' agreement 75% (= 25% disagreement) と整合**: 想定範囲内、複数 PR 累積評価が前提
5. **副産物 (D-3 post-merge-feedback)**: `MAX_CUSTOM_VIOLATIONS` outer/inner loop break scope の explicit test 必要性を発見 (Tier 2-1 採用、順位 119)、rule⑧ への paths filter 適用範囲検討を順位 118 として backlog 化

**Phase D 計画完遂後の Phase E 判定材料**:
**Phase D Round 2 対象 PR 構成 (D-4〜D-7、2026-05-13 追加)**:

Round 1 で実 dogfood data point が **1 件のみ** (D-3) に留まり、ADR-038 採用条件「5 PR 以上」+ analysis.md「3-5 PR 累積」前提との乖離が判明。D-1 反省 (docs-only は lint_screen findings 0 件で metrics 価値低) + workflow gap 解消済 (順位 115 = `LINT_SCREEN_ENABLED` env var override land、PR #147) を踏まえ、**残 4 PR で Rust code 中心 + size ramp-up + 累積 5 PR (D-3 + D-4〜D-7) 達成** を狙う延長計画を策定。

| Order | 構成 (todo-summary.md priority list より) | Tier / Effort | 推定 diff 行 | Diff Profile | 状態 |
|---|---|---|---|---|---|
| **D-4** | 順位 39 単独 = takt workflow `model` 必須化 lint rule + 副次作業 (`.takt/workflows/*.yaml` の `persona:` 行 3 件に `model:` 明示追加で clean baseline 確保) | T1 / S | ~150-280 | Rust lint rule (yaml multi-line regex) + 3-5 unit tests + custom-lint-rules.toml entry + 3 yaml site touch | 未着手 |
| **D-5** | 順位 56 + 119 bundle = comment-lint hook test 拡充 + `MAX_CUSTOM_VIOLATIONS` outer/inner loop break scope explicit test | T2+T2 / S+S | ~200-350 | hooks-post-tool-linter test infra (UTF-8 multi-byte 5 パターン + block boundary 6 パターン + MAX cap regression test) | 未着手 |
| **D-6** | 順位 51 単独 = `.takt/review-diff.txt` を fix→review iteration 間で refresh | T1 / M | ~400-580 | cli-push-runner Rust impl + iteration logic refactor + integration tests | 未着手 |
| **D-7** | Bundle c-1 (順位 63 + 64 + 67) = cli-merge-pipeline Drop guard / signal handler + orphan run reaper + ADR-030 spec amendment | T1×2 + T3 / M+M+XS | ~600-800 | Rust impl + signal trap + reaper logic + ADR markdown | 未着手 |

**size ramp-up 設計 (Round 2)**: small → small-mid → mid → mid-large で num_ctx 32768 容量限界に向け漸増、各 size 帯で fallback 発生率 / Phase A diagnostic warn log 出力有無を観測。D-3 (mid, 496 行) と組合せて 5 size 帯をカバー。

**D-1 反省の適用 (Round 2)**:

- ❌ **docs-only PR を回避**: D-4〜D-7 すべて Rust impl/test 中心 (D-7 で ADR markdown 1 つを bundle 内で同梱するのみ、主成分は Rust)
- ✅ **workflow gap 解消済**: 順位 115 (`LINT_SCREEN_ENABLED` env var) で session-only opt-in が成立、`push-runner-config.toml` 編集不要
- ✅ **dogfood 実施可否を事前確認**: 各 PR 着手時に (a) env var set 確認 / (b) Ollama 起動確認 / (c) PR が code change を含むこと を check

**想定リスク (Round 2)**:

- **D-7 (Bundle c-1) size 上限超過リスク**: M+M+XS が 800 行を超えた場合、c-1a (順位 63 単独) / c-1b (順位 64+67) の 2 PR 分割に switch。その場合は D-7 → D-7a/D-7b で 5 PR に拡張 (Phase E 判定材料が 1 件増える方向で副次的に valid)
- **D-4 size の下振れリスク**: 順位 39 単独 + 3 yaml site touch + tests は ~150-280 行を見込むが、focused single-purpose PR として 250 lower bound 未達も許容
- **detail 見積もりの精度**: 各 todo`N`.md の詳細 (実装方針 / acceptance criteria) を未参照、着手時に scope 修正の必要あり
- **D-4 の re-pivot 経緯 (2026-05-13)**: 当初 D-4 = 順位 47 (`>` vs `>=` boundary lint) を予定していたが、着手直前 (memory rule `feedback_verify_task_not_already_done.md` 適用) で **PR #126 (commit `b677b9d4f54d`) で既に land 済 (`no-time-field-strict-greater` rule、custom-lint-rules.toml line 208-243)** を発見。D-5 から 順位 39 を D-4 に繰上げ、D-5 を 順位 56 + 119 bundle に再構成。stale todo7.md 順位 47 entry は同 PR の docs commit で削除

**Phase D Round 1 完遂 + Round 2 計画策定後の Phase E 判定材料**:

- ✅ pipeline integration works end-to-end (D-1 #144 smoke test + D-3 real diff 完走)
- ✅ num_ctx 32768 で 270 行 Rust diff overflow なし (Phase C reference values と整合)
- ✅ fallback rate < 50% (D-3 で 0/1)
- ✅ fallback rate < 50% (D-3 で 0/1、単発)
- ⚠️ agreement: 1 false positive 観測 (Phase b' 75% 想定範囲内、単発観測)
- **複数 PR 累積必要** (Phase E 採否判定は次回以降の通常 PR で dogfood data を蓄積)
- 🔄 **累積 PR data 充足中**: Round 1 で 1 PR (D-3) 取得済、Round 2 (D-4〜D-7) で 4 PR 追加観測予定 → **累積 5 PR で ADR-038 採用条件「5 PR 以上」+ analysis.md「3-5 PR 累積」前提を充足見込み**

Phase E 着手の前提条件は **3-5 PR 累積 dogfood**。D-3 1 PR データを取得済 = あと 2-4 PR 観測すれば判定可能。当面は通常 PR の push 時に `$env:LINT_SCREEN_ENABLED=true` を opt-in で set し、`.takt/lint-screen-report.md` を post-push で記録する運用に移行する (本 § Phase D row への追記は dogfood data 蓄積継続中の暫定方針、判定時に Phase E section へ統合)
Phase E 着手の前提条件は **3-5 PR 累積 dogfood**。D-3 (1 PR 取得済) + Round 2 (D-4〜D-7、4 PR 追加観測予定) で計画上 **累積 5 PR** に到達する見込み。各 PR push 時に `$env:LINT_SCREEN_ENABLED=true` を opt-in で set し、`.takt/lint-screen-report.md` を post-push で記録する運用を継続

**Phase D 計測手順** (各 PR 共通):

Expand Down Expand Up @@ -309,8 +335,9 @@ Phase E 着手の前提条件は **3-5 PR 累積 dogfood**。D-3 で 1 PR デー

**別案 (棚上げ)**: D-1 を順位 110+111+104 (testing.md + docs-governance routing rule + ADR-007 amendment、mixed) に変更する案もあったが、ADR codify 優先で 112+113+114 を採用。

##### 🎯 Phase E: 採否判定 + retirement (1 PR、analysis.md 削除を含む、未着手)
##### 🎯 Phase E: 採否判定 + retirement (1 PR、analysis.md 削除を含む、**Phase D Round 2 完遂後着手**)

- **着手前提**: Phase D Round 2 (D-4〜D-7) 完遂 + 累積 5 PR 分の dogfood data 揃い + 各 PR の metrics (latency p50/p95 / fallback rate / classification 妥当性) 集計済
- **採用 case**: ADR-038 を「採用」に昇格 + [docs/local-llm-offload-phase-d-guide.md](local-llm-offload-phase-d-guide.md) を削除 (試験運用ガイド役目終了) + 本 analysis.md を削除 + history.md は permanent record として保持判断
- **却下 case**: cli-finding-classifier crate revert + ADR-038 を「却下」に更新 + Phase d guide 削除 + 本 analysis.md 削除
- **継続 case**: Phase D で別問題判明等 (例: real pipeline で classifier preview と異なる挙動) なら判定延期 + 本 §「次に何をするか」を再 pivot
Expand All @@ -320,7 +347,6 @@ Phase E 着手の前提条件は **3-5 PR 累積 dogfood**。D-3 で 1 PR デー
| Task | Effort | 関連 |
|---|---|---|
| 順位 100-108 docs PR (8 entries の todo registration、bundle 1 PR で消化) | S | Phase A〜C と並行 land 可、commit chain 整理 |
| Bundle c-1 (順位 63+64+67、c-1a/c-1b 分割推奨) | L (M+M+XS、split 推奨) | Phase d とは独立、通常 Tier 1 として後で対応 |
| Bundle j-2 (順位 95+96、`.github/workflows/lint.yml` 新設) | M (S+M) | 独立 |
| Bundle f-1/f-2 (PR #120 feedback) | S+M | 独立 |
| 順位 110-114 (PR #142/#143 post-merge-feedback 採用分) | XS-S 各 | Phase D の対象 PR 候補としても活用可能 |
Expand Down
1 change: 0 additions & 1 deletion docs/todo-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
| 44 | 💎 Tier 3 | **gh CLI 使用規則を `~/.claude/rules/common/git-workflow.md` に追記 (計画書 #D-1) ★ Bundle a Sub-PR 1** | todo4.md | XS | なし (Sub-PR 1、Sub-PR 2 でも `gh api` を使うため先行 land 推奨) |
| 45 | 🔧 Tier 2 | **`check-ci-coderabbit --list-findings` Rust モード追加 (計画書 #D-3) ★ Bundle a Sub-PR 1** | todo4.md | M | なし (Sub-PR 1、cli-pr-monitor が消費する構造化 findings API を提供) |
| 46 | 🔧 Tier 2 | **CodeRabbit rate-limit auto-retry の integration test (PR #100 T2-1) ★ Bundle a Sub-PR 2** | todo4.md | M | 順位 42 と同 PR (Sub-PR 2、rate-limit auto-retry 実装と一体) |
| 47 | 🚀 Tier 1 | **`>` vs `>=` boundary inconsistency lint rule (PR #101 T1-2)** | todo7.md | S | なし (PR #101 直接対策、同一ファイル内 3 関数で latent drift が実証済の高頻度問題) |
| 49 | 🔧 Tier 2 | **`parse_findings` 系の error-path test infrastructure (PR #101 T2-1) ★ Bundle a Sub-PR 2** | todo7.md | M | 順位 42 / 43 / 46 と同 PR (Sub-PR 2、`unwrap_or_else(\|_\| empty)` silent fail 抑止 + cli-pr-monitor mock infra 流用) |
| 51 | 🚀 Tier 1 | **`.takt/review-diff.txt` を fix→review iteration 間で refresh (PR #103 観測)** | todo7.md | M | なし (PR #103 で stale-diff false positive による wasted iter ×2 = ~10 分浪費を実観測、6-iter outlier の構造的根因対策、Bundle Z 3 層では塞げない独立改善) |
| 52 | 💎 Tier 3 | **comment-lint hook の MultiEdit 対応 (順位 50 follow-up)** | todo7.md | S | なし (順位 50 で v1 = Edit のみ実装、MultiEdit は whole-file fallback で no-regression、利用頻度低く優先度は低) |
Expand Down
40 changes: 0 additions & 40 deletions docs/todo7.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,6 @@

## 現在進行中

### `>` vs `>=` boundary inconsistency lint rule (PR #101 T1-2)

> **動機**: PR #101 で `parse_listed_findings` の `created_at > push_time` が CodeRabbit から境界 inclusive (`>=`) への揃え修正を指摘された。auto-fix が同一ファイル内 `parse_new_comments` / `parse_findings` にも `>=` を適用 (= 3 関数 latent drift)。`parse_rate_limit` だけが既に `>=` で、後続関数を書くたびに著者が意識せず `>` を選ぶ構造的問題。custom-lint-rule で書いた瞬間に block すれば bug class が排除される。
>
> **本タスクの位置づけ**: PR #101 post-merge-feedback Tier 1 #2 採用 (高頻度 finding)。Bundle Z #B-α (Rust comment lint hook) と同じ「決定論的防止層」哲学。AST 解析ではなく正規表現層 (ADR-007) で対応可能。
>
> **参照**: `.claude/feedback-reports/101.md` Tier 1 #2、ADR-007 (custom lint rule の正規表現 / AST 層線引き)、CodeRabbit PR #101 round 1 Minor finding
>
> **実行優先度**: 🚀 **Tier 1** — Effort S。`.claude/custom-lint-rules.toml` への regex rule 追加。

#### 設計決定 (案)

- **配置先**: `.claude/custom-lint-rules.toml` に新規 rule entry
- **検出パターン (正規表現案)**:
- 狭め: `\.(created_at|submitted_at|updated_at)\b.*\.map\(\|\w+\|\s*\w+\s*[><](?!=)\s*(push_time|since)`
- 広め: `\b(created_at|submitted_at|updated_at|comment_event_time|event_time)\b.*[><](?!=)` で時刻フィールドの strict inequality 全般を flag
- **適用対象**: `.rs` ファイル
- **rule 名 (案)**: `time-boundary-strict-inequality`
- **suppress マーカー**: `// SAFETY: <理由>` 行末付与で suppression (例: 意図的に exclusive 比較する場合)

#### 作業計画

- [ ] 既存 `.claude/custom-lint-rules.toml` の rule 構造を確認
- [ ] regex + path filter を新 rule として記述
- [ ] PostToolUse hook の lint runner で synthetic test (修正前 `parse_findings` 系の `>` パターンを再現してマッチ確認)
- [ ] 既存 codebase で false positive 影響範囲をグレップして確認
- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) への deploy 確認
- [ ] 本 todo7.md エントリを削除

#### 完了基準

- `.claude/custom-lint-rules.toml` に新 rule が追加され `.rs` ファイル内の時刻フィールド strict inequality を検出
- 1〜2 PR で dogfood し false positive がないこと

#### 詰まっている箇所

- false positive の評価 (時刻フィールド以外で legitimate な `>` が誤 block されないか)。着手時に実 codebase でグレップして影響範囲を確認。

---

### `parse_findings` 系の error-path test infrastructure (PR #101 T2-1) ★ Bundle a Sub-PR 2

> **動機**: PR #101 で `run_list_findings` が `unwrap_or_else(|_| "[]")` で gh api 失敗を `[]` に潰していて CR Major finding を受けた。99.md でも `silent fail` (Windows path mismatch で early return) として類似言及あり。**`unwrap_or_else(|_| empty)` の anti-pattern が複数 PR で再発**。test 層で機械検証することで未然に塞ぐ。本タスクは Bundle a Sub-PR 2 (cli-pr-monitor の rate-limit auto-retry) で同 API を消費するので、同一 PR land で test 二重投資なし。
Expand Down
Loading