Files
ISEP/hooks/leo21c-write-guard.sh
Leo 1dc97f0bd6 fix(hooks): 補上 leo21c-write-guard.sh 第二、三次誤攔的修法(InkStoneCo 反向移植)
InkStoneCo/.claude/hooks/leo21c-write-guard.sh 2026-08-20 當天已修過兩次
誤攔(bc8a529/5e62d28),但沒人把修法帶回 ISEP——ISEP 那份還是上線當天
的舊版,會誤擋「git commit 訊息提到 leo21c」「Gitea PATCH 內文提到
leo21c」這類完全碰不到 CF 帳號的動作。

發現於 inkstone/InkStoneCo#57/inkstone/ISEP#32「同一件事只留一份」:
要把 InkStoneCo 本機的閘收斂成只剩 ISEP 這份之前,先確認 ISEP 沒有落後
——結果這支剛好是唯一反向的(其餘 4 支已修過的閘 ISEP 都領先)。

判準改成只認「這個指令會不會真的寫到那台」:
① 寫入請求打到 *.leo21c.workers.dev(POST/PUT/PATCH/DELETE/--data/-d/trigger)
② 用它的 CF 帳號 id 跑 wrangler/acr
其餘一律放行,不管文字裡提到什麼。

實測 6/6(4 該放行/2 該擋,含這次要修的兩個誤攔案例):見 PR 說明。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 19:46:24 +08:00

99 lines
5.0 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# leo21c-write-guard.sh — 不准寫 leo 的個人帳號(leo 2026-08-20 立)
#
# leo 原話:
# 「youlin = stagegeek6688 = 測試 prod 出貨機,uncle6 = 中心服務,
# 這三個都可以拿來當 default,但你要實驗當然是放在 youlin。」
# 「**leo21c 就是我這個普通用戶,不應該讓你去操控,我只用公開的更新。**」
#
# 🔴 為什麼要機器守(2026-08-20 實錯,本閘的來由):
# 總管派 subagent 驗碎形目錄索引,它用了本機 `~/.arcrun/config.yaml` 的預設
# `cypher_executor_url: …leo21c…``api_key: bfezv28v`),
# 把 8 張測試卡寫進 leo 的真庫。
# 而當時 `system-dev/wiki/agent-memory.md` §2 白紙黑字寫著
# 「底層帳號=leo21c,**任何自動化只准落在它上面**」——那是 dogfood 時代的舊分工。
# ⇒ **文件教錯 + 機器預設也錯 ⇒ 沒指定的一律流進他的帳號。**
# ⇒ 規則改對了還不夠:`~/.arcrun/config.yaml` 至今仍指著 leo21c
# (它的 KV id 與 encryption_key 是該實例專屬,換不過去),
# 所以**真正擋得住的是這道閘**,不是那張表。
#
# 判準(封動作,不封措辭 —— 同 empty-handed-stop-guard 的哲學):
# 命中 leo21c 的座標 + 這是一個寫入動作 ⇒ 擋
# 只是讀(GET/查詢/grep 到那個字串) ⇒ 放行
set -uo pipefail
payload=$(cat)
cmd=$(printf '%s' "$payload" | python3 -c "
import json,sys
try: print((json.load(sys.stdin).get('tool_input') or {}).get('command',''))
except Exception: print('')
" 2>/dev/null)
[ -z "$cmd" ] && exit 0
# 🔴 這些工具碰不到 CF 帳號 ⇒ 整個放行(2026-08-20 上線當天就誤攔兩次,本段是修正)
# ① `git commit -m "…leo21c… acr update…"` 同時命中座標與寫入動詞而被擋
# ② 連「修這道閘本身」的指令都被擋(測試案例裡自然含觸發字)
# 但 git 與文字編輯根本寫不到那台實例,**訊息裡寫到什麼都不會造成寫入**。
# leo 2026-08-17:「紅線寫得越細,命中關鍵字的機率越高 ⇒ 那些閘在懲罰謹慎。」
# ⇒ 閘要問「這個指令能不能真的寫到那台」,不是「這段文字提到什麼」。
case "$cmd" in
git\ *|jj\ *|" git "*) exit 0 ;;
esac
if printf '%s' "$cmd" | grep -qE '^[[:space:]]*(git|jj)[[:space:]]'; then
exit 0
fi
# 修這道閘自己:命中的是本檔路徑就放行(否則永遠改不動它)
if printf '%s' "$cmd" | grep -q 'leo21c-write-guard'; then
exit 0
fi
# ── 判準:這個指令會不會真的把東西寫到那台?────────────────────────────────
# 🔴 2026-08-20 第三次誤攔後收斂(前兩次:git commit 訊息、修閘自己)。
# 舊判準是「文字裡有沒有出現座標」+「有沒有寫入動詞」,於是
# `curl -X PATCH .../api/v1/repos/inkstone/Arcrun/issues/145 -d '{"state":"closed"}'`
# **只因為票的內文提到那個帳號就被擋**——而那是打 Gitea,跟 CF 一點關係都沒有。
# ⇒ 只認**兩種真的會寫到那台的形狀**,其餘一律不管文字寫了什麼:
# ① 寫入請求打到 `*.leo21c.workers.dev`
# ② 用它的 CF 帳號 id 去跑 wrangleracr
# leo 2026-08-17:「紅線寫得越細,命中關鍵字的機率越高 ⇒ 那些閘在懲罰謹慎。」
hit=0
# ① 寫入請求打到那台 worker
if printf '%s' "$cmd" | grep -qiE 'https?://[^[:space:]"'"'"']*leo21c\.workers\.dev'; then
if printf '%s' "$cmd" | grep -qE -- '-X *(POST|PUT|PATCH|DELETE)|--data|--data-raw|-d[[:space:]]|/trigger'; then
hit=1
fi
fi
# ② 拿它的 CF 帳號去部署
if printf '%s' "$cmd" | grep -qE 'CLOUDFLARE_ACCOUNT_ID=51a01bfa2665bd7bc3fd080dc40cf3e1'; then
if printf '%s' "$cmd" | grep -qE 'wrangler|acr |node .*index\.js'; then
hit=1
fi
fi
[ "$hit" = "1" ] || exit 0
cat >&2 <<'MSG'
🚫 不准寫 leo 的個人帳號 leo21cleo 2026-08-20 立)
leo 原話:「**leo21c 就是我這個普通用戶,不應該讓你去操控,我只用公開的更新。**」
youlin ← 🟢 你的 stage:做實驗、跑驗證,**沒指定就用這個**
geek6688 ← 測試 prod 出貨機
uncle6 ← 中心服務(安裝器/文件站/bundle),出貨線的目的地
leo21c ← 🔴 leo 本人在用的知識庫。**讀可以,寫不行。**
改法:把目標明寫成 youlin,不要吃 `~/.arcrun/config.yaml` 的預設——
那個檔至今仍指著 leo21cKV id 與 encryption_key 是該實例專屬,換不過去)。
cypher : https://arcrun-cypher-executor.youlin-hsieh-dev.workers.dev
ns : yuga3bse
CF : 1129efd7df2e8899d537e9c8fbabb6cb
token : 頂層 .env 的 CLOUDFLARE_API_TOKEN_YOULIN_CC_USE
📌 2026-08-20 實錯:subagent 吃了那個預設,把 8 張測試卡寫進 leo 的真庫
library=demo-real-verify)。當時 wiki 還教「任何自動化只准落在 leo21c」。
MSG
exit 2