Summary: chat-Claude corrigendum #1 Point 3 「hook ファイル を 一時ファイル に 書いてから mv で 置き換えれば、 置き換え は 原子的、 他 tab は 常に 旧版 or 新版 のどちらか を 読む = 中途半端 state 不可能」 の script + permanent memory rule land。 fm-hook-edit-via-edit-tool-transient-syntax-error 対応 (STEP 2206 initial commit の 「syntax error near unexpected token (」 実 emerge)。
Implementation
scripts/edit-hook-safely.sh (~85 line)
- mktemp in same directory (same-filesystem 保証 = POSIX atomic rename)
- Read new content (stdin or
--filter transform)
- Empty check: 空 content → exit 2 refuse (accidental blank hook 予防)
- +x bit preserve (target が executable なら)
- Atomic mv: tempfile → target
- trap EXIT cleanup for error paths
Usage
# Case A: 全内容 差替
cat new-content > | scripts/edit-hook-safely.sh .githooks/pre-commit
# or
scripts/edit-hook-safely.sh .githooks/pre-commit < path/to/new.sh
# Case B: transform 適用
scripts/edit-hook-safely.sh .githooks/pre-commit --filter sed 's/foo/bar/g'
Self-test
$ echo -n "" | scripts/edit-hook-safely.sh scripts/edit-hook-safely.sh
ERROR: new content is empty — refusing to overwrite scripts/edit-hook-safely.sh
exit=2 ✓
file preserved (3621 bytes, still executable) ✓
memory/feedback_hook_file_edit_use_tempfile_mv_atomic_2026-09-23.md
Permanent feedback memory rule:
- Root fm: fm-hook-edit-via-edit-tool-transient-syntax-error (STEP 2206 initial commit 実 emerge)
- Why: chat-Claude 明示 + POSIX rename(2) atomic guarantee
- Scope:
.githooks/* + scripts/git-atomic-commit.sh + tsx/node が 直接 import する .ts/.sh
- Anti-pattern:
Edit(.githooks/pre-commit, ...) and Write(.githooks/pre-commit, ...) = NG
- How to apply: Case A (全内容 差替) / Case B (transform) / Case C (small patch)
Effect
未来 .githooks/* を 編集する 時 (Item #6 optimization 追加調整、 attribution check rule 追加、 Section 8 拡張 等)、 concurrent commit の transient syntax error 事故 回避。 STEP 2206 initial commit の incident 再発予防。
Honest scope
- Enforcement は 自主遵守 依存: lint 自動 detect なし、 私 が 「.githooks/* 触る = edit-hook-safely.sh 使用」 rule を 内在化 する 必要 (memory feedback file が discipline load 経路)
- chmod --reference 未使用: cross-platform Git Bash 対応で
chmod +x 単純化、 best-effort
- Concurrent 前提 multi-tab 環境: single-tab では transient state read 起きない、 rei-aios standard multi-tab で 常に concurrent 前提
- Tempfile 命名:
.<basename>.tmp.XXXXXX short-lived、 git status で 見えるかも (mv 直後 消滅)
- STEP 2210 自身 の initial creation: script 自作 initial 例外 明示 (initial creation、 未 executable、 concurrent reader なし)、 以後 の 変更 は 本 rule 適用
Next candidates (defer marker)
- Pre-commit hook で staged .githooks/** の atomic edit path 経由 verify (mtime / inode diff から heuristic、 自動 enforcement)
- Session hook rule (自動 rewrite: Edit(.githooks/*) → SendMessage 「edit-hook-safely.sh 使用」)
- CLAUDE.md 直接 embed (session-start protocol level rule)