Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
9 changes: 0 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,6 @@
- [ADR-027: Push-time review を simplicity に限定し architectural review は post-PR に委ねる](docs/adr/adr-027-push-review-simplicity-focus.md)
- [ADR-028: 外部可視成果物の生成コマンド (PR 作成/マージ) の実行ゲート](docs/adr/adr-028-pnpm-create-pr-gate.md)

## Automated actor boundary (ADR-022)

takt / claude -p / cli-* の副作用は**コード修正とレポート生成**に限定する。以下は人間の責務であり、automated actor は触らない:

- commit message / commit description
- bookmark / branch 名
- tag
- PR title / PR body (作成時の user-supplied text をそのまま使う)

## Build

```sh
Expand Down
190 changes: 157 additions & 33 deletions docs/adr/adr-022-automation-responsibility-separation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## ステータス

承認済み (2026-04-17)
承認済み (2026-04-17) / 改訂 (2026-04-20: 分離型 fix commit 追記 → 2026-04-21: 原則 1 を「生成 vs 確定」軸に再構築 → 2026-04-21: 原則 5「PR 包含 changeset の不変性」追加)

## コンテキスト

Expand Down Expand Up @@ -43,16 +43,112 @@ let (ok, output) = run_cmd_direct(

## 決定

### 原則 1: automated actor の副作用範囲
### 原則 1: automated actor の副作用範囲 (改訂 2026-04-21)

自動化コンポーネント (takt / claude -p / cli-*) の副作用は以下に限定する:
本 ADR の当初版 (2026-04-17) は「automated actor は意図表現の生成そのものを禁止」とする書き方をしていた。しかし運用の結果、以下の 2 点で窮屈さが顕在化した:

- **許可**: コード修正 (ファイル書き換え、新規ファイル作成)、レポート生成 (`.takt/runs/*`, stdout log)
- **禁止**:
- commit message / commit description の生成・書き換え
- bookmark / branch 名の生成・書き換え
- tag の作成・書き換え
- PR title / PR body の書き換え (作成時の user-supplied text をそのまま使う)
1. interactive Claude Code に commit description / bookmark 名の draft 生成まで禁じると、ユーザーが手動工程で埋まり Claude Code 利用の意義が失われる
2. takt fix 分離型 child commit (2026-04-20 追記) のように「新規 artifact への自己記述」は実害がないにも関わらず、例外追記が必要になる

原則 1 を **「生成 vs 確定」軸** で再構築し、「草案生成」と「新規 artifact への自己記述」は許可、「**意図表現** を含む既存 artifact の無断上書き」および「未承認での確定」を禁止とする。

#### 用語

**意図表現** = 人間の意思が込められた外部可視の成果物:

- commit description
- bookmark / branch 名
- tag
- PR title / PR body

**automated actor** = takt / claude -p / cli-* の自律ループ **および** interactive Claude Code session。自律ループと interactive の違いは承認ゲートの形態のみ (後述)。

#### 許可される副作用

- **コード修正** (ファイル書き換え、新規ファイル作成)
- **レポート生成** (`.takt/runs/*`, stdout log)
- **草案生成**: commit description / bookmark 名 / PR title / PR body / VCS コマンドの提案、および最終的に人間が採用する (統合) commit message の草案
- **新規 artifact への自己記述の適用**: 新規 child commit の description、新規 bookmark の命名、新規 tag の生成 (既存の意図表現を侵食しないため)

#### 禁止される副作用

- **意図表現を含む既存 artifact の無断上書き**
- 例: 既存 commit への `jj describe` による description 書き換え、作成済み bookmark のリネーム、作成済み PR の title/body 改変
- **未承認での確定**: 承認ゲートを経ずに外部観測可能な状態を変更すること (GitHub 上の PR 作成、remote push 等)

#### 緩和条項: 既存 artifact の内容更新

既存 artifact への内容更新は、以下の 4 条件をすべて満たす場合に限り自律ループでも許可する:

1. **可逆**: `jj op log` / `git reflog` 等で完全に巻き戻せる
2. **事前ポリシー許可**: `.claude/settings.json` や ADR 等で運用ポリシーとして明示されている
3. **意図表現を破壊しない**: commit description / bookmark 名 / PR title/body / tag を変更しない
4. **changeset が remote open PR に含まれていない**: 原則 5 と整合 (2026-04-21 追加)

適用例:

- takt fix の file edit → `@` amend: 内容更新・可逆・意図不変・PR 外 → 許可 (原則 3 と整合。PR 内では原則 5 により child commit 分離が必須)
- (将来候補) auto-rebase / auto-squash / auto-format commit history: parent 付け替えや空白調整・可逆・意図不変 → 別 ADR で運用ポリシーを明示した後に PR 外限定で許可

#### 承認ゲート (actor 別)

同じ副作用でも、actor の種類により適用される承認ゲートが異なる:

| actor | 承認ゲート | 既存 artifact 改変 (上記緩和条項外) |
|---|---|---|
| autonomous loop (takt fix / cli-pr-monitor の自律ポーリング / claude -p) | なし | 常に禁止 |
| interactive Claude Code (ユーザー明示依頼) | permission prompt / AskUserQuestion / ユーザー黙認 (重要度に応じて使い分け) | 承認ゲート経由で許可 |
| 人間の直接操作 | 不要 (本人の意思) | 許可 |

interactive Claude Code が使う承認ゲートの対象別対応:

| 対象 | 草案生成 | 承認ゲート |
|---|---|---|
| commit description | Claude が提案 | ユーザーが黙認で OK、明示 NG で修正 |
| bookmark 名 | Claude が自動採番 | 不要 (pnpm push 時に名前が見える) |
| `pnpm push` 実行 | Claude が foreground で起動 | harness の permission prompt |
| PR title / body | Claude が `prepare-pr` skill 経由で draft | AskUserQuestion で明示承認 |
| `pnpm create-pr` 実行 | Claude が foreground で起動 | permission prompt + AskUserQuestion (ADR-028 二層) |

#### 想定 UX (interactive Claude Code)

PR 作成フローの典型:

```
[Claude]
Proposed commit description:

feat(cli-pr-monitor): avoid overwriting commit description

- remove automatic jj describe
- ensure automated actor boundary (ADR-022)

Proposed bookmark: fix/avoid-overwrite-desc

Run:
jj describe -m "<above>"
Comment thread
aloekun marked this conversation as resolved.
Resolved
jj bookmark create fix/avoid-overwrite-desc
pnpm push

Proceed? (y/n)

[User]
y

[Claude]
(permission prompt 越しに pnpm push を実行)

...

[Claude] (push 完了後)
PR draft:
title: ...
body: ...

AskUserQuestion で明示承認を取得 → pnpm create-pr
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

この「草案生成 → 承認 → 実行」の 3 段階が interactive session の標準パターン。`prepare-pr` skill はこれを標準化する実装。

### 原則 2: fix 実行事実の記録先

Expand All @@ -68,38 +164,62 @@ takt fix は `@` を amend する (jj auto-snapshot が file edit を `@` に sq

描写が空の初回 commit で fix ラベルを付けたい場合、それは「人間による明示的な describe」で対応する。automated actor は入らない。

**原則 1 との関係 (改訂解釈 2026-04-21)**: 原則 3 は原則 1 の緩和条項の具体例として位置付け直す。`jj amend` は「意図表現を破壊しない内容更新」であり緩和条項の 4 条件 (可逆・事前ポリシー許可・意図不変・PR 外) を満たすため許可。`jj describe` は「意図表現の上書き」に該当し、既存 commit 対象の場合は禁止。PR 内 changeset への amend は原則 5 により禁止。

### 原則 4: PR 作成時の user-supplied body

`pnpm create-pr -- --title ... --body ...` で渡された title/body は automated actor が書き換えない。CodeRabbit が「PR description をもっと詳しく書け」と指摘したとしても、takt は該当する書き換えを行わない (fix step の `edit: true` はあくまで**リポジトリ内ファイル**への edit を意味する)。

### 例外: 分離型 fix commit の自己記述 (2026-04-20 追記)
### 原則 5: PR 包含 changeset の不変性 (2026-04-21 追加)

ADR task 4 (takt fix のレビュー修正コミット分離) の実装に伴い、以下を例外として許可する:
#### 高レベル原則

**対象**: 自動生成された修正を、既存 commit を改変せずに新規 child commit として分離する場合のみ
external reviewer が参照する対象 (PR 上の commit 履歴) は不変であるべき。amend 等の履歴書き換えは GitHub レビュー thread の outdated 化・orphan 化を招き、指摘の追跡可能性とレビュアーの信頼を損なう。

**許可される内容**:
#### ルール

- **changeset が remote open PR に含まれている場合**: 原則 1 の緩和条項 (可逆・事前ポリシー・意図不変) を満たしていても amend を禁止
- **修正は必ず新規 child commit として分離**: `jj new -m "fix(review): ..."` または `jj new` + 自動 description 生成
- **changeset が PR に含まれていない場合**: 原則 1 緩和条項に従った amend は許可

#### 適用対象

| actor | 扱い |
|---|---|
| takt fix (autonomous) | task 4 (PR #63) で child commit 分離を既に実装済み。本原則は当該実装を設計原則として事後的に昇格させるもの |
| interactive Claude Code | 本 ADR の 2026-04-21 改訂で automated actor の範囲に含めた。同じルールに従う |
| 人間の直接操作 | 自分の意思で判断可能だが、同じ線引きを推奨 (レビュー破壊のリスクは actor を問わず同じ) |

#### 判定方法

- `gh pr list --head <bookmark-name> --state open --json number` で bookmark が open PR に紐付いているか確認
- cli-pr-monitor は stage 間 state で PR 番号を保持済み (`src/cli-pr-monitor/src/stages/push.rs` 参照)
- interactive Claude Code は `jj describe` / ファイル edit 連続実行の前に上記チェックを入れる運用に切り替える (実装タスクは docs/todo.md 参照)

#### 本原則の適用開始

本 ADR の改訂版 (原則 5 追加) 自体が原則 5 の自己適用例。PR #64 で原則 5 を追加する際、ADR-022 v3 基礎改訂 (`ccda6198`) への amend ではなく、新規 child commit として分離した。

### 原則 1 の適用例: 分離型 fix commit の自己記述 (2026-04-20 追記 / 2026-04-21 位置付け変更)

task 4 (takt fix のレビュー修正コミット分離) の実装により、takt fix は修正を独立した child commit として分離する。この child commit への description 付与は、原則 1 改訂版の「**新規 artifact への自己記述の適用**」に該当し正面から許可される (当初は 2026-04-20 の例外条項として扱っていたが、2026-04-21 の原則 1 再構築で本流に吸収)。

**description に含める内容** (automated actor が生成してよい):

- commit 種別を示すラベル (例: `fix(review): apply CodeRabbit fixes for #<PR>`)
- 何を問題と捉えて修正したかの文脈 (CodeRabbit finding の severity / file / summary など)
- 対応した指摘の列挙 (ファイル/行/issue 要約)

**依然として禁止される内容**:

- 既存 commit (= 人間が意図を込めた元 PR commit) の description 書き換え
- PR title / PR body の書き換え
- bookmark / tag への介入

**根拠**:
**依然として禁止**:

- 独立した child commit の description は「その commit 自身の自己記述」であり、原則 1 が守るべき「人間の意図表現」を侵食しない
- automated actor の修正判断を残すことは、後のレビュー・post-merge-feedback (ADR-014) 等へのフィードバックループの情報資源になる
- 「最初の commit の意味は保ったまま、追加 commit に自動化の痕跡を残す」という形で、人間の意思と自動化の記録を両立させる
- 既存 commit (= 人間が意図を込めた元 PR commit) の description 書き換え (原則 1 の「意図表現の既存 artifact 無断上書き」)
- PR title / PR body の書き換え (原則 4)
- bookmark / tag への介入 (原則 1)

**実装上の拘束**:

- description は automated actor が生成してよいが、**常に新規 commit に対してのみ**適用する (`jj new -m ...`)
- 既存 commit への `jj describe` は引き続き禁止 (原則 3 は不変)
- description は **常に新規 commit に対してのみ**適用する (`jj new -m ...`)
- 既存 commit への `jj describe` は引き続き禁止 (原則 3 / 原則 1 の禁止条項)
- fix commit が空になる (takt no-op) 場合は abandon する — 空 description の commit を残さない

## 影響
Expand All @@ -112,18 +232,22 @@ ADR task 4 (takt fix のレビュー修正コミット分離) の実装に伴い

### 避けるべきアンチパターン

- **automated actor による commit message 自動付与**: `jj describe -m "fix(*): ..."` の自動実行 (PR #43 で実害発生)
- **PR 作成時の user-supplied body を AI が書き換える**: CodeRabbit 指摘の「PR description 強化」を takt fix で自動適用する等
- **takt fix 後の commit を rename する**: 元 description が失われる
- **bookmark 名を自動生成する**: 人間が意図を込めて命名すべきもの
- **autonomous loop による既存 commit の `jj describe` 実行**: 既存 description を上書きする (PR #43 で実害発生)
- **承認済み PR title / body の事後改変**: CodeRabbit 指摘の「PR description 強化」を takt fix で自動適用する等 (原則 4)
- **既存 bookmark のリネーム**: 人間が意図を込めた命名を automated actor が勝手に書き換える
- **interactive Claude Code が AskUserQuestion を省いて `pnpm create-pr` を実行**: ADR-028 二層ゲートの一層目が抜け落ちる
- **autonomous loop が緩和条項の 4 条件 (可逆 / 事前ポリシー / 意図不変 / PR 外) を満たさないまま既存 artifact を改変する**: 例えば auto-rebase を ADR なしで実装する
- **PR 内 changeset への amend**: open PR に紐付く commit を `jj describe` や jj auto-snapshot amend で書き換える。GitHub レビュー thread の outdated 化を招く (原則 5)

### CLAUDE.md への反映 (本 PR で反映済み)
### CLAUDE.md への反映方針 (改訂 2026-04-21)

グローバル原則として以下を `CLAUDE.md` に追記済み (`Automated actor boundary` セクション):
ハーネスエンジニアリングの基本方針 (CLAUDE.md はリンクに留め、詳細は ADR 等のリンク先ドキュメントに置く) に従い、本 ADR の内容を CLAUDE.md に転載しない。CLAUDE.md の `Architecture Decisions` 一覧に本 ADR へのリンクを記載するのみ (既に存在)。

> **Automated actor boundary**: takt / claude -p / cli-* の副作用はコード修正とレポート生成に限る。commit message / bookmark / tag / PR title/body は人間の責務であり、automated actor は書き換えない。
当初版 (2026-04-17) で `CLAUDE.md` に `Automated actor boundary` セクションを直接記載していたが、2026-04-21 の本改訂と同時に削除。参照先は本 ADR 原則 1 (改訂版) に一本化する。

## 次ステップ (スコープ外)

- **post-merge-feedback (ADR-014) 実装時の参照**: merge 後の AI ステップで commit にタッチしないよう、本 ADR を設計原則として参照する
- **post-merge-feedback (ADR-014) 実装時の参照**: merge 後の AI ステップで既存 commit の description にタッチしないよう、本 ADR を設計原則として参照する
- **ADR-015 の push-runner 見直し**: 同原則で軽くレビューし、副作用の過剰な箇所がないか確認 (必要なら別 ADR)
- **takt fix による最終 commit message 草案生成機能の実装**: child commit の description が「機械ログ化」する問題を緩和するため、takt fix の report phase で「最終的に人間が採用する統合 commit message の草案」を `.takt/runs/*/reports/final-commit-message-draft.md` 等に書き出す。`prepare-pr` skill が起動時にこれを読み込み draft 初稿の元ネタとする。原則 1 改訂版の「草案生成」で許可されており、別 PR で実装
- **auto-rebase / auto-squash / auto-format commit history の検討**: 原則 1 改訂版の緩和条項 (可逆・事前ポリシー・意図不変) を満たす範囲で将来実装可能。必要になった時点で別 ADR を作成し運用ポリシーを明示してから実装
Loading