Skip to content

feat(post-merge-feedback): takt workflow + 4 facets で L1 Floor を実装 (ADR-030 Phase B)#77

Merged
aloekun merged 2 commits intomasterfrom
feat/adr-030-phase-b
Apr 25, 2026
Merged

feat(post-merge-feedback): takt workflow + 4 facets で L1 Floor を実装 (ADR-030 Phase B)#77
aloekun merged 2 commits intomasterfrom
feat/adr-030-phase-b

Conversation

@aloekun
Copy link
Copy Markdown
Owner

@aloekun aloekun commented Apr 25, 2026

Summary

ADR-030 で起案した決定論的 post-merge-feedback 機構の L1 Floor (Phase B) を実装する。旧 ADR-029 の pending file → Stop hook → skill 経路を、cli-merge-pipeline が takt workflow を同期 spawn する経路に置き換え、silent loss を取り除く。

  • L1 Floor: takt workflow post-merge-feedbackcli-merge-pipeline から同期実行 (session lifecycle 非依存の決定論実行)
  • 4 facets を順次 chain: analyze-pranalyze-sessionanalyze-prepush-reportsaggregate-feedback
  • 入力ハンドオフは .takt/post-merge-feedback-context.json + .takt/post-merge-feedback-transcript.jsonl (Rust が事前 filter)
  • 出力は .claude/feedback-reports/<pr>.md、失敗時は <pr>.md.failed marker (soft fail、merge は成功扱い)

L2 Recovery (UserPromptSubmit hook) は Phase C で別 PR として実装する。

主な変更

  • .takt/workflows/post-merge-feedback.yaml: 4 facet を順次 chain (loop_monitors なし — コードではなくレポート生成のため fix loop は不要)
  • .takt/facets/instructions/{analyze-pr,analyze-session,analyze-prepush-reports,aggregate-feedback}.md: 旧 /analyze-pr skill + /post-merge-feedback skill Phase 4 から port
  • src/cli-merge-pipeline/src/feedback.rs (新規): transcript 時刻 range filter + context handoff + takt spawn + report copy + failure marker
  • src/cli-merge-pipeline/src/main.rs: run_ai_step を pending file 書込から feedback::run に置換
  • src/cli-merge-pipeline/src/pending_file.rs: 削除 (takt-fix の simplification 提案を受け入れ、Phase E の dead code 削除を前倒し)
  • .gitignore: .claude/feedback-reports/ + .takt/post-merge-feedback-* を除外
  • docs/todo.md: Phase B 該当セクションを削除 (運用ルール「完了タスクは ADR/仕組みに反映後に削除」)

設計判断

  • pass_previous_response: false: aggregate-feedback は前 step の response ではなく Report Directory 経由で 3 つの先行レポートを Read する (supervise.md パターンに揃える)
  • transcript 抽出戦略: jj detached state により gitBranchHEAD 固定のため、時刻 range filter ([first_commit_time, merged_at]) が唯一の確定的経路 (Phase 0 で実証済み)
  • soft fail: takt 失敗時も cli-merge-pipeline は exit 0。merge 完了済の PR を巻き戻せないため、.failed marker + L2 recovery (Phase C で実装) で取りこぼしを拾う
  • report の出力先: takt run dir の feedback-report.md を Rust が .claude/feedback-reports/<pr>.md にコピーする (ADR-022「機械的 = Rust」原則に整合、facet は出力先 convention を知らない)

Test plan

  • cargo test workspace 全 green (cli-merge-pipeline: 32 passed、feedback module の単体テスト 9 件)
  • cargo clippy --workspace -- -D warnings 通過
  • cargo fmt --check 通過
  • release build 成功
  • cargo test -- --ignored --test-threads=1 通過 (cli-pr-monitor 7 ignored integration tests)
  • pnpm exec takt prompt post-merge-feedback で workflow YAML が parse 成功
  • pre-push-review pipeline (takt) が approve

dogfood (Phase F) は Phase C の L2 Recovery 実装後の数回マージで検証する。

References

  • ADR-030: 決定論的 Post-Merge Feedback (試験運用)
  • ADR-014 (full supersede 予定 / Phase E)
  • ADR-029 (partial supersede / Phase E)
  • ADR-015 / ADR-018: takt 移行の先行事例 (本 PR は 3 例目)
  • ADR-020: takt facets 共通化戦略 (4 facets 分離方針の根拠)
  • ADR-022: 自動化コンポーネントの責務分離原則 (L1 takt 経由は本原則に整合)

Summary by CodeRabbit

  • 新機能

    • PR マージ後に、PR解析・セッション解析・プレプッシュ解析を順に実行して統合した自動フィードバックレポートを生成する新ワークフローを追加しました。
    • CLI がこのワークフローを呼び出してレポートを保存するようになり、失敗時は復旧用のソフトフェイルマーカーを残します。
  • ドキュメント

    • 各解析手順(PR解析/セッション解析/プレプッシュ解析/集約)の手順書を追加しました。
  • その他

    • ワークフロー生成物を無視する設定を更新しました。

…DR-030 Phase B)

ADR-030 で起案した決定論的 post-merge-feedback 機構の L1 Floor を実装する。
旧 ADR-029 の pending file → Stop hook → skill 経路を、cli-merge-pipeline が
takt workflow を同期 spawn する経路に置き換えた。silent loss が起きていた
層 3-4 (session lifecycle 依存) を Rust の決定論実行で取り除く。

主な変更:
- .takt/workflows/post-merge-feedback.yaml: 4 facets 順次 chain (loop_monitors なし)
- .takt/facets/instructions/{analyze-pr,analyze-session,analyze-prepush-reports,aggregate-feedback}.md
- src/cli-merge-pipeline/src/feedback.rs (新規): transcript 時刻 range filter
  + context handoff + takt spawn + report copy + failure marker
- src/cli-merge-pipeline/src/main.rs: run_ai_step を pending file 書込から
  feedback::run に置換
- 旧 pending_file module は #![allow(dead_code)] で Phase E まで残置
- .gitignore に .claude/feedback-reports/ + .takt/post-merge-feedback-* を追加
- docs/todo.md: Phase B 完了に伴い該当セクションを削除

Phase C (UserPromptSubmit hook L2 Recovery) は別 PR で実装する。
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fc602dd0-410d-43e2-9436-d9175079877b

📥 Commits

Reviewing files that changed from the base of the PR and between 6d3adc0 and 7971062.

📒 Files selected for processing (1)
  • src/cli-merge-pipeline/src/feedback.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/cli-merge-pipeline/src/feedback.rs

📝 Walkthrough

Walkthrough

ADR-030に基づき、ペンディングファイル方式を廃止して、決定論的な同期taktワークフロー(PR解析・セッション解析・プレプッシュ解析・集約)を追加し、CLIから直接実行・タイムアウト管理・成果物の配置を行う統合実装を導入しました。

Changes

Cohort / File(s) Summary
ワークフロー構成
\.gitignore, .takt/workflows/post-merge-feedback.yaml
ADR-030成果物(.claude/feedback-reports/、ワークフロー入力ファイル)をgitignoreへ追加。新しいpost-merge-feedbackワークフローを定義。
takt手順書
.takt/facets/instructions/analyze-pr.md, .takt/facets/instructions/analyze-session.md, .takt/facets/instructions/analyze-prepush-reports.md, .takt/facets/instructions/aggregate-feedback.md
4段階の分析/集約手順を新規追加。入力読み込み、フィルタリング、Tier分類、出力フォーマットと終了マーカーを規定。
フィードバック実行エンジン
src/cli-merge-pipeline/src/feedback.rs
PR時間範囲取得、トランスクリプト時刻フィルタ、pre-pushレポート探索、.taktコンテキスト/トランスクリプト生成、takt実行(タイムアウト監視)、結果コピー・失敗マーカー処理を実装。公開定数・helper関数・単体テストを追加。
CLI統合
src/cli-merge-pipeline/src/main.rs
AIステップをペンディングファイル方式から同期takt呼び出しへ差替え。feedback::run()呼び出し追加、失敗時はソフトフェイルとして.failedマーカーを残す。関連ユニットテスト更新。
削除
src/cli-merge-pipeline/src/pending_file.rs
従来のpending_file実装(読み取り/書き込み/並行制御ロジック)とそのテスト群を完全削除。
ドキュメント
docs/todo.md
Phase B相当の項目を完了済みに更新し、以降の開始フェーズをPhase Cへ移動。

Sequence Diagram(s)

sequenceDiagram
    participant CLI as CLI (feedback.rs)
    participant GH as GitHub CLI
    participant FS as File System
    participant TAKT as Takt Workflow
    participant ANA1 as analyze-pr
    participant ANA2 as analyze-session
    participant ANA3 as analyze-prepush
    participant AGG as aggregate-feedback

    CLI->>GH: gh pr view -> first_commit_time, mergedAt
    GH-->>CLI: 時刻範囲

    CLI->>FS: transcript source dir を読み込み
    FS-->>CLI: JSONL 行

    CLI->>CLI: 範囲内の user/assistant をフィルタ
    CLI->>FS: .takt/post-merge-feedback-transcript.jsonl に書込

    CLI->>FS: 最新の *-pre-push-review/reports/ を検出
    FS-->>CLI: prepush_reports_dir

    CLI->>FS: .takt/post-merge-feedback-context.json を生成

    CLI->>TAKT: takt -w post-merge-feedback を実行
    activate TAKT

    TAKT->>ANA1: PR解析を実行
    ANA1->>FS: PR diff / コメント / メタデータ取得
    ANA1-->>TAKT: pr-analysis.md

    TAKT->>ANA2: セッション解析を実行
    ANA2->>FS: フィルタ済みトランスクリプト読み込み
    ANA2-->>TAKT: session-analysis.md

    TAKT->>ANA3: プレプッシュ解析を実行
    ANA3->>FS: pre-push レポート読み込み
    ANA3-->>TAKT: prepush-analysis.md

    TAKT->>AGG: 集約を実行
    AGG->>FS: 3レポート読み込み・マッチング・統合
    AGG-->>TAKT: feedback-report.md

    deactivate TAKT
    TAKT-->>CLI: 完了

    CLI->>FS: 最新実行の reports/feedback-report.md を .claude/feedback-reports/<pr>.md にコピー
    CLI->>FS: <pr>.md.failed を削除(成功時)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed タイトルは ADR-030 Phase B に基づく post-merge-feedback 機構の L1 Floor 実装という、PR 全体の主要な変更を明確に要約している。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/cli-merge-pipeline/src/main.rs (1)

636-640: ⚠️ Potential issue | 🟡 Minor

警告メッセージが旧経路の文言のまま残っている。

ADR-030 では post_steps の AI ステップは pending file を書かず、takt workflow を同期実行するよう切り替わっている。pending file を書き込めずスキップ という記述は実装と乖離しており、運用時のログ追跡で誤解を招く。

📝 提案する修正 diff
     let owner_repo = detect_owner_repo();
     if owner_repo.is_none() {
         log_info(
-            "警告: owner_repo を検出できませんでした (gh repo view 失敗)。post_steps の AI ステップは pending file を書き込めずスキップします。",
+            "警告: owner_repo を検出できませんでした (gh repo view 失敗)。post_steps の AI ステップ (post-merge-feedback workflow) はスキップします。",
         );
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cli-merge-pipeline/src/main.rs` around lines 636 - 640, owner_repo が None
のときに出す警告メッセージが旧仕様(pending file を書き込めずスキップ)を伝えているので、log_info 呼び出しのメッセージ文言を
ADR-030 に合わせて更新してください(参照: owner_repo 変数と log_info 関数呼び出し)—具体的には「post_steps の AI
ステップは pending file を書き込まず、takt ワークフローを同期実行する」旨に差し替え、誤解を招かない短い日本語メッセージにしてください。
🧹 Nitpick comments (1)
src/cli-merge-pipeline/src/feedback.rs (1)

383-611: #[cfg(test)] mod tests は通常ファイル末尾に置くのが慣例。

現在 mod tests (383-611) が public エントリポイント run (617-664) より前に置かれており、ファイルを開いたときに「テストの海」を越えないと本体エントリに辿り着けない。Rust の慣例どおり run の後(ファイル末尾)へ移動すると読みやすさが大きく改善する。挙動には影響しない並べ替えのみ。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cli-merge-pipeline/src/feedback.rs` around lines 383 - 611, テストモジュール
(#[cfg(test)] mod tests { ... }) が公開エントリポイント run の前に置かれているため、ファイル末尾(run
関数の後)に移動して可読性を改善してください;具体的にはファイル内の mod tests ブロック全体を切り取り、run 関数(run
の定義と終了括弧)を見つけた後ろ、ファイルの末尾に貼り付けてテストモジュールを配置し、既存のインポートやスコープに影響がないことを確認してください。
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/cli-merge-pipeline/src/feedback.rs`:
- Around line 624-639: The current use of unwrap_or(0) when calling
filter_transcripts hides I/O errors (e.g. File::create failures) — change the
match to handle the Result explicitly: call filter_transcripts(transcript_dir,
&range, &transcript_path) and on Err e, emit a clear error log including e and
transcript_path (eprintln! or the crate's logger) and propagate the error back
to the caller (return Err(...)) instead of turning it into 0; ensure the
surrounding function's signature is adjusted to return Result so main.rs can
convert the error into a concrete write_failed_marker reason; references:
filter_transcripts, transcript_path, input.transcript_source_dir.
- Around line 215-220: The current string comparison between timestamp and
range.first_commit_time / range.merged_at can misorder millisecond vs
second-only formats; instead parse all three values into chrono::DateTime (e.g.,
using chrono::DateTime::parse_from_rfc3339 or parse_from_rfc3339 then
.with_timezone(&Utc)) and perform DateTime comparisons; update the block that
reads timestamp and the final comparison (the variables timestamp,
range.first_commit_time, range.merged_at) to handle parse errors (return false
on parse failure) and compare the parsed DateTime values rather than raw
strings.

---

Outside diff comments:
In `@src/cli-merge-pipeline/src/main.rs`:
- Around line 636-640: owner_repo が None のときに出す警告メッセージが旧仕様(pending file
を書き込めずスキップ)を伝えているので、log_info 呼び出しのメッセージ文言を ADR-030 に合わせて更新してください(参照: owner_repo
変数と log_info 関数呼び出し)—具体的には「post_steps の AI ステップは pending file を書き込まず、takt
ワークフローを同期実行する」旨に差し替え、誤解を招かない短い日本語メッセージにしてください。

---

Nitpick comments:
In `@src/cli-merge-pipeline/src/feedback.rs`:
- Around line 383-611: テストモジュール (#[cfg(test)] mod tests { ... }) が公開エントリポイント run
の前に置かれているため、ファイル末尾(run 関数の後)に移動して可読性を改善してください;具体的にはファイル内の mod tests
ブロック全体を切り取り、run 関数(run
の定義と終了括弧)を見つけた後ろ、ファイルの末尾に貼り付けてテストモジュールを配置し、既存のインポートやスコープに影響がないことを確認してください。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 73c71a82-7c21-403c-a97c-a6a2efd197db

📥 Commits

Reviewing files that changed from the base of the PR and between 65008b9 and 6d3adc0.

📒 Files selected for processing (10)
  • .gitignore
  • .takt/facets/instructions/aggregate-feedback.md
  • .takt/facets/instructions/analyze-pr.md
  • .takt/facets/instructions/analyze-prepush-reports.md
  • .takt/facets/instructions/analyze-session.md
  • .takt/workflows/post-merge-feedback.yaml
  • docs/todo.md
  • src/cli-merge-pipeline/src/feedback.rs
  • src/cli-merge-pipeline/src/main.rs
  • src/cli-merge-pipeline/src/pending_file.rs
💤 Files with no reviewable changes (1)
  • src/cli-merge-pipeline/src/pending_file.rs

Comment thread src/cli-merge-pipeline/src/feedback.rs Outdated
Comment thread src/cli-merge-pipeline/src/feedback.rs
Resolved findings:
- [Minor] src/cli-merge-pipeline/src/feedback.rs:220 境界付近で精度差による取りこぼしが起き得る(minor)。
- [Major] src/cli-merge-pipeline/src/feedback.rs:639 `filter_transcripts` のエラーが握り潰されている。
@aloekun
Copy link
Copy Markdown
Owner Author

aloekun commented Apr 25, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 25, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@aloekun aloekun merged commit a1ee195 into master Apr 25, 2026
1 check passed
@aloekun aloekun deleted the feat/adr-030-phase-b branch April 25, 2026 14:07
aloekun added a commit that referenced this pull request Apr 25, 2026
* fix(post-merge-feedback): task labeling 規約導入で run dir 検索を決定論化

PR #77 の merge dogfood で発覚した `copy_feedback_report` の bug を修正する。
takt の run dir 命名は `<ts>-<sanitized-task-label>` 形式で workflow 名そのものは
含まないため、`ends_with("-<workflow>")` での suffix match が context suffix
(例: `-for-77`) 付きの dir に対して fail していた。

対策: 「task label は workflow 名を必ず prefix として含む」という命名規約を
ADR-030 に追記し、Rust 側のマッチングを `name.contains("-<workflow>")` の
1 ルールに統一。context suffix の有無に関わらず一律にマッチする。

主な変更:
- src/cli-merge-pipeline/src/feedback.rs: find_latest_run_dir を contains
  match に変更、TAKT_TASK_PREFIX を workflow 名と sanitization 後一致する形に
  修正、新規テスト 5 件追加
- src/cli-pr-monitor/src/config.rs + pr-monitor-config.toml +
  templates/pr-monitor-config.toml: post-pr-review の task を
  "analyze PR review comments" → "post-pr-review" に揃え、latent bug を予防
- docs/adr/adr-030-deterministic-post-merge-feedback.md: §task labeling
  convention セクション追加。規約・制約 (workflow 名同士の部分文字列禁止)・
  採用根拠を明記

Phase B 内の bugfix として完結し、Phase C には bug を持ち越さない。

* docs(adr-030): 制約例を実装と一致させ、partial substring の取り違えを明示

CodeRabbit (PR #78) が指摘した不整合を修正。

旧記述: "merge と post-merge-feedback は OK" は誤り。
- find_latest_run_dir は name.contains("-{workflow}") で照合
- workflow=merge の needle "-merge" は "<ts>-post-merge-feedback-..." に
  内部出現するため誤マッチが起きる
- したがって merge も post-merge と同様 NG

修正内容:
- 「部分文字列関係」の定義を実装メソッド (name.contains) と紐付けて明記
- NG 例を 2 件 (merge, post-merge) と OK 例 (build) を併記
- 実装ファイル feedback.rs へのリンクを追加
aloekun added a commit that referenced this pull request Apr 26, 2026
)

Phase B dogfood で発見されたタイムアウト経路の残存不具合と、ボトルネック分析で
判明した sequential 構造を併せて修正する。

## 主な変更

### 1. workflow の並列化 (.takt/workflows/post-merge-feedback.yaml)
3 つの analyze facet (analyze-pr / analyze-session / analyze-prepush-reports) は
独立した情報源を扱うため parallel block で並列実行する。
PR #78 計測 (sequential 12m13s) → parallel 想定 ~7m30s に短縮。

### 2. TAKT_TIMEOUT_SECS: 600s → 1200s
PR #77 (14m21s)、#78 (12m13s) 観測実績を踏まえた暫定値。並列化後の想定 7m30s
に対し 2x の安全係数。docstring に「band-aid」と明記し、本質解は workflow 構造で
時間を抑えることだと残した。

### 3. caller-side reconciliation (run() 末尾)
Windows の child.kill() が takt の descendants を殺せず、Rust が timeout で kill
した後も takt が orphan として走り続けて report を完成させるケースを観測した
(PR #78 で kill 後 2m13s で feedback-report.md 完成)。

run_takt_workflow の戻り値に関わらず copy_feedback_report を必ず試行し、report が
存在すれば success 扱いとする。既存の .failed marker は cleanup_failed_marker で
除去する。

### 4. 並行起動 guard (CONCURRENT_RUN_GUARD_SECS = 1500s)
cross-invocation context overwrite race を発生源で予防。
.takt/post-merge-feedback-context.json が 1500s 以内に書かれていれば、orphan takt
が走行中の可能性が高いとみなして新規実行を refuse する。

### 5. テスト追加 (5 件)
concurrent_run_guard / context_age_secs の振る舞いを検証。

### 6. ADR-030 更新
- レイテンシモデル (parallel 想定 = max(analyze) + aggregate)
- Reconciliation 設計の根拠
- 並行起動 guard の意図と Phase B 外切り出し方針

## 残存リスク (Phase B 外)
- Windows の job object でプロセスツリー全体を kill する根本対策
- 完全な per-invocation isolation (takt context dir 連携)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant