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
14 changes: 14 additions & 0 deletions .claude/hooks-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ enabled = true
fetch_timeout_secs = 3 # jj git fetch 全体の timeout (network 異常で session 起動を阻害しない)
fetch_cache_secs = 300 # FETCH_HEAD mtime が N 秒以内なら fetch をスキップ (network cost 抑制)
default_branch = "master" # trunk-based 前提、feature branch 運用では変更
# workspace stale 検知 nudge (ADR-045 § Known operational risks、C2)。並列 workspace の操作で
# working copy が stale になったら `jj workspace update-stale` を促す (自動実行はしない)。
# default-OFF (ADR-039 § 1)、本リポジトリは並列 workspace 運用のため有効化して dogfood。
stale_check_enabled = true

# [session_start.weekly_review_reminder]
# - ADR-031 Phase C: `/weekly-review` skill 起動の reminder (試験運用、ADR-039 experimental pattern 準拠)。
Expand Down Expand Up @@ -128,6 +132,16 @@ threshold_bytes = 51200 # 50KB (= 50 * 1024)、Claude C
paths = ["docs/**/*.md", "src/**/*.rs"] # default 対象 glob
touch_trigger = true # 触られたファイルのみ check (ratchet)

# jj operation 検証 (ADR-045 § Operation Verification Checklist の自動化、G案)。
# Bash tool で変更系 jj コマンド (new/describe/abandon/rebase/squash/bookmark 変更系) を
# 実行した直後に `jj op log --limit 1` で operation の記録を確認し、無ければ
# 「operation not recorded」警告を additionalContext で返す (non-blocking 助言層)。
# 2026-07-12/13 の並列 workspace lost-update incident の検出網。
# default-OFF (ADR-039 § 1)、本リポジトリは並列 workspace 運用のため有効化して dogfood。
# Kill-switch: enabled = false で完全停止。
[post_tool_use.jj_op_verify]
enabled = true

# ─── PostToolUse: リンター ───

[post_tool_linter]
Expand Down
10 changes: 10 additions & 0 deletions .claude/settings.local.json.template
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@
"timeout": 10
}
]
},
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"{{PROJECT_DIR}}\\.claude\\hooks-post-tool-jj-op-verify.exe\"",
"timeout": 10
}
]
}
],
"Stop": [
Expand Down
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ members = [
"src/cli-push-pipeline",
"src/cli-push-runner",
"src/hooks-post-tool-comment-lint-rust",
"src/hooks-post-tool-jj-op-verify",
"src/hooks-post-tool-linter",
"src/hooks-pre-tool-validate",
"src/hooks-session-start",
Expand Down
13 changes: 13 additions & 0 deletions docs/adr/adr-015-push-runner-takt-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ push-runner の設定は `push-runner-config.toml` (リポジトリルート)
- `.takt/` — takt ワークフロー・facets
- `takt` devDependency (package.json)

## push 戦略の 2 層管理原則 (2026-07-13 追記)

push 戦略 (どの bookmark を、どの経路で push してよいか) は **hook 層と exe 実装層の 2 層で独立に管理されており、片方だけでは守れない**。ADR-045 の並列 workspace 事故 (lost-update incident) の調査で、`pnpm push` (cli-push-runner) が内部で `jj git push --all` を無条件実行しており、hook 層のガードが自動化経路に一切効いていないことが判明した実例を原則化する。

| 層 | 担当範囲 | 実装 |
|---|---|---|
| hook 層 (hooks-pre-tool-validate `jj-push-guard`) | **対話操作のみ**: Claude が Bash tool で直接打つ `jj git push` / `jj push` を全 block し `pnpm push` へ誘導 | `src/hooks-pre-tool-validate/src/presets/jj.rs` |
| exe 実装層 (cli-push-runner push stage) | **自動化経路**: pipeline 内部の push コマンド。hook のスコープ外 (Bash tool を経由しない subprocess) のため、push 範囲の制御は exe/config 側で行う | `src/cli-push-runner/src/stages/push.rs` `build_push_command` — bookmark_check の検出名から `-b <name>` を組み立て、`--all` を廃止 (2026-07-13) |

原則: **push 戦略を変更するときは両層を確認する**。「hook で block したから安全」は対話操作にしか成立しない。逆に exe 層の制御は Claude の直接操作には効かない。片層のみの変更は保護の非対称 (asymmetric guard coverage、review-security-whole の観点) を生む。

補足 — ADR-011 との整合: ADR-011 (jj 0.37 前提) は新規 bookmark push を `remotes.origin.auto-track-bookmarks` 設定で解決する戦略だったが、その後の実装は config コメントベースで `--all` を採用し、ADR-011 と乖離していた。jj 0.42 では `jj git push -b <name>` が未 tracking の新規 bookmark を自動 track するため、auto-track 設定も `--all` も不要になり、本追記の `-b` 明示方式で両者の課題が解消される。

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

- **cli-pr-monitor の takt 化**: daemon ポーリング完了後に takt ワークフローで CodeRabbit 指摘の自動分析・修正 (Phase 2)
Expand Down
40 changes: 37 additions & 3 deletions docs/adr/adr-045-jj-workspace-parallel-sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## ステータス

試験運用 (2026-06-29) / 改訂 (2026-06-30: 初 PR 運用ケースで判明した secondary workspace の `.git` 不在 → gh ベースコマンドの `GIT_DIR` 必須、および merge-pipeline の bookmark 誤検出を「§ PR 運用時の追加設定」として追記) / 改訂 (2026-07-03: 恒久対策候補 1 = `GIT_DIR` 自動注入を実装。cli-* exe は手動 `GIT_DIR` 前置なしで動作するようになり、手動前置は直接 gh 呼び出し時の fallback に格下げ。PR #238 で `GH_REPO` による場当たり対処が部分故障を招いた実観測を受け `gh-repo-env-guard` preset も追加)
試験運用 (2026-06-29) / 改訂 (2026-06-30: 初 PR 運用ケースで判明した secondary workspace の `.git` 不在 → gh ベースコマンドの `GIT_DIR` 必須、および merge-pipeline の bookmark 誤検出を「§ PR 運用時の追加設定」として追記) / 改訂 (2026-07-03: 恒久対策候補 1 = `GIT_DIR` 自動注入を実装。cli-* exe は手動 `GIT_DIR` 前置なしで動作するようになり、手動前置は直接 gh 呼び出し時の fallback に格下げ。PR #238 で `GH_REPO` による場当たり対処が部分故障を招いた実観測を受け `gh-repo-env-guard` preset も追加) / 改訂 (2026-07-13: **再評価 trigger #3 が発火** — 並列セッションの concurrent 操作と重なる時間帯に 2 コミット分の作業が消失する incident が発生 (PR #265 セッション、手動再構築で復旧)。「並行操作は jj が安全にマージする」という調整ポイント 4 の記述を jj 公式の並行モデルに即して是正し、「§ Known operational risks」「§ 並列運用の運用ルール」「§ Operation Verification Checklist」を新設)

> ADR-039 (Experimental feature 標準パターン) に準拠: config opt-in なし (本 ADR は workflow 運用ポリシーであり実装機構ではないため該当しない) / kill-switch = 本 ADR を supersede する後続 ADR で停止可能、運用上は単一 workspace へ戻すだけで無効化 / bounded lifetime = 採用判定 3 ヶ月 (2026-09-29) を目安に dogfood 結果から本採用 / 修正 / 却下を判定。

Expand Down Expand Up @@ -92,7 +92,41 @@ src の大規模分割 (メイン) と lint/facet/docs (改善) は編集領域
1. **bookmark 名は workspace 間で共有 namespace**。タスクごとに別名 (メイン = `pr-w3-...` / `pr-w4-...`、改善 = `fix-<task>` / `lint-<rule>` 等) を付け、別 PR として独立させる。同名 bookmark を両 workspace で作らない。
2. **ローカル `master` bookmark は共有**。片方が `pnpm merge-pr` で land すると `master@origin` が進む。もう片方は `jj git fetch` + `jj rebase -d master@origin` で取り込んでから push する (`docs/file-length-enforcement-plan.md` § Cargo.lock 競合の rebase 手順と同型)。
3. **state / lock / monitor は workspace ごとに独立** (gitignore + per-checkout)。並列の post-PR monitor / CronCreate が互いの state を壊さない。
4. **op log は共有**だが、並行操作は jj が安全にマージする (concurrent operation を自動解決)。
4. **op log は共有**であり、並行操作の扱いは jj 公式の並行モデルに従う (2026-07-13 是正。当初の「並行操作は jj が安全にマージする」という記述は不正確だった)。公式モデル: jj は lock-free 設計で、並行操作は op log の分岐 (divergent operation heads) として記録され、次のコマンドが自動 3-way マージする。干渉は「stale working copy」(エラーで停止 → `jj workspace update-stale` で recovery commit が作られ変更は保全される) と「bookmark 競合」(競合状態として可視化) の 2 形態で表面化する。ただし **colocated リポジトリの同時編集は upstream が「十分にテストされていない」と明記する領域**であり (本リポジトリの default workspace は colocated)、公式保証の外側がある。「§ Known operational risks」を参照。

### Known operational risks (2026-07-13 新設)

並列 workspace 運用で実際に遭遇しうるリスクと対処。出典: jj 公式 [Concurrency 設計文書](https://docs.jj-vcs.dev/latest/technical/concurrency/) / [Working copy 文書](https://docs.jj-vcs.dev/latest/working-copy/) と本プロジェクトの実観測。

| リスク | 内容 | 対処 |
|---|---|---|
| **stale working copy** | 別 workspace がリポジトリを変更 (この workspace の wc commit の書き換え・abandon 等) すると、こちらの working copy が stale になり jj コマンドがエラーで停止する | `jj workspace update-stale` を実行する。recovery commit が作られ、working copy 上の変更は失われない (公式の設計保証)。エラーは異常ではなく、公式が想定する正常な干渉の表面化 |
| **bookmark 競合** | 同じ bookmark が並行して別方向に動くと競合状態として記録される。特に **`jj git push --all` は他 workspace の作業中 bookmark を巻き込んで push する** | push は必ず bookmark 明示 (`jj git push -b <name>`)。`--all` は並列運用中は使わない |
| **colocated repository の同時編集** | upstream が「十分にテストされていない」と明記する領域。default workspace は colocated (`.git` 併設) で、fetch は git refs を共有 store に取り込む | repo 境界操作 (fetch / push / merge) の同時多発を避ける (下記運用ルール)。挙動不審時は op log で確認 |
| **parallel terminal output corruption** | 2026-07-12/13 に実観測: 2 セッション並行稼働中、ツール出力の混線 (偽の成功表示・別セッションのテキスト混入) と同時間帯に、2 コミット分の操作が **op log に痕跡なく消失** (手動再構築で復旧)。op が記録されない事象は jj 公式モデルでは説明できず、有力仮説は「コマンドが実際には実行されず、成功表示は出力混線による偽物」(ハーネス側の問題)。ただしコマンド送信失敗 / tool 呼び出しキャンセル / terminal multiplex 不具合 / jj 未発見バグ / colocated 特有問題も排除できていない (未確定) | 下記運用ルール + Operation Verification Checklist で検出・封じ込め。混線を発見したら直ちに両セッションを停止しログを保存する |

### 並列運用の運用ルール (2026-07-13 新設)

1. **1 terminal = 1 Claude Code session**。terminal multiplex は使わない
2. workspace ごとに terminal ウィンドウを分離する
3. repo 境界操作 (`jj git fetch` / `jj git push` / `pnpm merge-pr`) は共有資源への書き込みであり、並列セッション稼働中はどちらか一方のセッションに寄せる
4. push は bookmark 明示 (`jj git push -b <name>`) のみ。`--all` 禁止
5. 変更系 jj コマンドは 1 つずつ実行し、並行投入しない (1 メッセージに複数の変更系 jj を混ぜない)
6. マージ等の repo 境界操作の前に、background task (monitor / lint 等) の完了を確認する
7. 出力混線 (重複・欠落・身に覚えのないテキスト) を発見したら、直ちに両セッションを停止し、`jj op log` と会話ログを保存してから再開する

### Operation Verification Checklist (2026-07-13 新設、暫定手順)

変更系 jj 操作 (`new` / `abandon` / `describe` / `rebase` / `squash` / `git fetch` / `git push`) の直後に、operation が記録されたことを確認する:

```sh
jj op log --limit 1 --no-graph
```

- 直前の操作に対応する op (description が操作内容と一致) が先頭にあること
- 無い場合は「operation not recorded」= 上記 output corruption リスクの兆候。作業を止めて状態を確認する
- `jj op log` は working copy を snapshot しない (副作用なし) ため、確認自体は安全
- 本手順は PostToolUse hook による自動化 (todo 順位 275-278 と同経緯の feedback 採用分) が実装されるまでの暫定。hook 実装後は自動検証に置き換わる

### マージ方法 (各 workspace で独立)

Expand Down Expand Up @@ -185,7 +219,7 @@ PR head 以外の non-trunk bookmark が `@` / `@-` / `@--` の近接 3 世代

1. タスク領域分割が機能せず、master での論理衝突 (同一箇所の二重編集) が複数回観測される
2. 新 workspace 作成頻度が高く `pnpm build:all` の初回コストが運用ボトルネック化する (事前ビルド共有 / deploy 機構の検討トリガー)
3. jj workspace 間の op log 競合や bookmark 衝突が dogfood で顕在化する
3. jj workspace 間の op log 競合や bookmark 衝突が dogfood で顕在化する — **発火 (2026-07-12/13)**: 並列セッションの concurrent 操作 (`jj git fetch` / `jj new` / `jj abandon` / `jj git push --all`) と重なる時間帯に 2 コミット分の操作が op log に痕跡なく消失。対応 = 本改訂 (§ Known operational risks / § 運用ルール / § Operation Verification Checklist) + push の bookmark 明示必須化 + stale 検知 nudge + operation 検証 hook (同一 PR で実装)。ADR 自体は却下せず運用ルール + 決定論ガードで継続 (公式・コミュニティとも workspace 並列は標準的な使い方であり、workspace 誤用の証拠はないため)
4. 採用判定期限 (2026-09-29) で本採用 / 修正 / 却下を判定

## 関連 ADR
Expand Down
2 changes: 0 additions & 2 deletions docs/todo-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@
| 275 | 🔧 Tier 2 | **層別テストテンプレート (StubOllama パターン・integration 独立性) の共有化 (PR #265 post-merge-feedback T2-1 採用)** | todo13.md | M | なし (WP-11/ADR-054 の多層防御実装で「空 StubOllama による LLM 未呼び出し証明」「tempdir+jj init+CwdRestore の integration 独立性」を都度設計。WP-17 の classifier/scope guard 拡張で同種判断が再発見込み。shared crate 化の境界は ADR-044 で判定、WP-17 着手前の実施が効果的) |
| 276 | 💎 Tier 3 | **ADR-007 に「コメント配置の意思決定フロー」を追加 (PR #265 post-merge-feedback T3-2 採用)** | todo13.md | S | なし (PR #265 で非 doc コメントの Bundle Z block が 2 回発生 = doc コメント/識別子名/マーカー付き Why の配置判断が未文書化。linter 自動化は NLP 必要で却下済み、既存 Q1-Q3 形式で人間/AI の判断補助を doc 化。バッチ PR で消化可) |
| 277 | 💎 Tier 3 | **PR body 配置タイミング規約を dev-conventions に明記 (PR #265 post-merge-feedback T3-3 採用)** | todo13.md | XS | なし (push パイプライン実行中の working copy に `__pr-body.md` を作成し snapshot 混入をかろうじて回避したヒヤリハット実発生。「push 完了後に scratchpad で準備し --body-file に絶対パス」を規約化。バッチ PR 消化可、並列安全化 PR docs への相乗りも可) |
| 278 | 💎 Tier 3 | **ADR-015 に「push 戦略は hook ブロックと exe 実装の両層で管理する」原則を追記 (PR #265 post-merge-feedback T3-4 採用)** | todo13.md | XS | なし (pnpm push が `jj git push --all` を無条件実行と判明 = hook block は対話操作にしか効かず自動化経路は exe/config 側管理が必要という 2 層原則が未記録。並列 lost-update incident の背景記録。並列安全化 PR (push の -b 明示化) と同一 PR での消化を推奨) |
| 279 | 💎 Tier 3 | **ADR-045 に「Known operational risks」「運用ルール」「Operation Verification Checklist」の 3 セクションを追加 (PR #265 post-merge-feedback T3-1 採用)** | todo13.md | S | なし (ADR-045:95「並行操作は jj が安全にマージする」という記述が、本セッションで実際に発生した workspace 間 concurrent 操作による 2 コミット lost update (手動再構築で復旧) と矛盾することが判明。ADR-045 § 再評価 trigger #3 に該当する実観測。Severity High、Effort S で Supervisor が最優先 2 件の一つと指摘) |

**戦略**: 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
Loading
Loading