雲端要拿得到票、主線與通知:白名單住 ISEP、主線檔隨 repo 走、leo21c 讀放寫擋(inkstone/ISEP#130)

- docs/permissions-allow.json + scripts/settings-allow-sync:四個 Gitea 正門工具的權限白名單一份,
  setup script 裝完 plugin 寫一次、SessionStart 每次再對一次(只加不減、冪等)
- hooks/lib/mainline.py/scripts/mainline:家目錄沒主線就讀 InkStoneCo/system-dev/mainline.json;
  set/adopt/clear 兩份一起寫,refresh 只寫家目錄
- hooks/leo21c-write-guard.sh:唯讀 -d(tr/cut/sort…)先剪掉再判、notify_leo trigger 放行
  (與 prod-write-guard 同一份白名單)、改法段改印 09-02 起的 youlin 子網域;補第一支測試(26 條)
- prod-write-guard/main-and-prod-push-guard/kbdb-live-exam:認得 youlin 新子網域 arcrun-yuga3bse
- scripts/ticket:收件 repo 寫 inkstone/ISEP 不再 404(org 寫錯當場講)
- scripts/isep-notify:有 TELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_ID 先走 Bot API 直送(雲端唯一通的路)
- 測試:A31–A35 共 79 條;README/plugin.json/hooks-inventory 數字實數(61 支、85 條、53 支腳本)

假設(記在這裡等 review):權限規則的形狀沿用 leo 09-07 親手加、實測有效的那四條;
「分類器真的不擋」要雲端一趟 run 的 permission_denials 才驗得到,本 PR 驗不了。
版本:待總管定版(plugin.json 仍 0.22.0)。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DTZ9QtvjY7MNxjfQbexAm7
This commit is contained in:
isep-hand
2026-09-07 01:17:15 +00:00
parent 605f1fe5a6
commit 65120a1c65
27 changed files with 1141 additions and 34 deletions
+120
View File
@@ -678,6 +678,109 @@ B 段拿這台機器真正的 `.env` 對帳——**`.env` 不在的機器(雲
> ```
> ⇒ 第二條正是黑名單會放過去的形狀。
### A31 — leo21c 讀可以、寫不行,而且改法指到活著的 youlin:26 條
```
bash hooks/tests/leo21c-write-guard.test.sh
```
**該看到**`通過 26 條,失敗 0 條`。全程離線,這支閘不寫檔,直接跑真跡。
**它在守什麼**inkstone/ISEP#1302026-09-04 雲端 run log):`leo21c-write-guard.sh`
**連讀都擋**——Routine 讀 `notify_leo` 定義那一條被攔下,雲端於是什麼都拿不到。
實查:舊判準 `-d[[:space:]]``| tr -d '\r'``cut -d=` 這種唯讀的 `-d` 當成 curl 的 body
`prod-write-guard.sh` 在 08-12 就修過同一個洞,這支漏了。另外它把 `notify_leo` 的 trigger
一律當寫入擋,而 `prod-write-guard.sh` 從 ISEP#63 起就放行它——**兩支閘對同一條指令說不同的話**。
這支之前**沒有任何測試**,「讀會不會被誤攔」從來沒被驗過。
測資是 Routine 文件(`cloud-worker.md``progress-guard.md`)裡**真的會下的那幾條**。
**失敗**
- A 群任一紅 ⇒ **誤攔**,雲端又回到「連讀都讀不到」;③④⑤ 紅就是 09-04 那個形狀復發
- ⑫ 紅 ⇒ 撞人閘時發 Telegram 叫 leo 又會被擋(inkstone/InkStoneCo#110 的病)
- B 群任一紅 ⇒ 寫得進 leo 的真庫(2026-08-20 那 8 張測試卡的病)。⑬ 特別看:
Routine 的心跳 POST **就是寫入**,它該被擋——那條指令要改,不是閘要放
- ㉔㉕ 紅 ⇒ 閘印的「改法」教人打 09-02 起 DNS 已不存在的舊子網域,照著做只會拿到 000
**修之前用同一份測試跑舊閘(`git show main:hooks/leo21c-write-guard.sh`**:③⑤⑫㉔㉕ 五條紅
——證明這五格是真的改到了,不是測試順著新閘寫的。
### A32 — 主線那個檔隨 repo 走:17 條
```
bash hooks/tests/mainline-repo-mirror.test.sh
```
**該看到**`通過 17 條,失敗 0 條`。全程離線:家目錄那份走 `ISEP_COUNTDOWN_STATE_DIR`
repo 那份走 TMP 底下的假 `InkStoneCo/system-dev/`
**它在守什麼**inkstone/ISEP#130leo 09-05「routine 每天早上開啟後抓不到任務」):
主線只住在家目錄,雲端是另一台機器 ⇒ 不知道主線是哪條。PR inkstone/InkStoneCo#118
把它放進 `system-dev/mainline.json`,這裡驗 ISEP 這一半:**家目錄沒有就讀 repo 那份;
兩份都在 `set_at` 較新的算數;`set``adopt``clear` 兩份一起動;`refresh` 只寫家目錄。**
**失敗**
- ①②③ 紅 ⇒ 雲端(`$CLAUDE_PROJECT_DIR` 是薄殼根、真身在 `InkStoneCo/`)仍然讀不到主線
- ⑤⑥ 紅 ⇒ 誰後標的誰算數這條壞了:本機會把雲端剛標的蓋回去,或反過來
- ⑧ 紅 ⇒ **每開一個 session InkStoneCo 的工作樹就髒一次**,而髒的 diff 沒有人會去 commit
- ⑫ 紅 ⇒ `clear` 之後下一次讀又從 repo 那份長回來
- ⑮ 紅 ⇒ ISEP#82 第 4 條(沒有主線不能整組壞掉)被本票弄壞
雲端實跑(2026-09-07,本 session):`CLAUDE_PROJECT_DIR=/home/user/inkstoneco
ISEP_COUNTDOWN_STATE_DIR=$(mktemp -d) python3 scripts/mainline` → 印出
`🎯 現在的主線:inkstone/Arcrun#48「AI 問一次就看得到全部…」`——家目錄空的,只靠 repo 那份。
### A33 — 權限白名單住 ISEP 一份、兩台各自寫進家目錄:19 條
```
bash scripts/test-settings-allow-sync.sh
```
**該看到**`19/19 通過`。全程在 TMP 底下的假 `settings.json` 上跑,不碰真的 `~/.claude/settings.json`
**它在守什麼**inkstone/ISEP#130 → comment 61206121):leo 09-07 親手加進本機
`InkStoneCo/.claude/settings.json` 的四條(`ticket``mainline``gate-ok``gitea-pr-merge`
雲端沒有 ⇒ 同樣動作被分類器擋(09-04 `permission_denials=6`)。雲端真正讀的薄殼 repo
要 D20 開閘才推得動 ⇒ 清單住 ISEP `docs/permissions-allow.json``scripts/settings-allow-sync`
在那台機器上寫進 `~/.claude/settings.json`:雲端由 `docs/cloud-setup-script.sh` 裝完 plugin 跑一次、
之後每個 SessionStart 再對一次;本機同一支。
**失敗**
- A1 紅 ⇒ 清單裡混進了整類放行(`Bash(python3 *)`)或少了正門工具
- B3B4 紅 ⇒ `~` 沒換成那台的家目錄——雲端是 `/root` 不是 `/Users/youlinhsieh`,規則會對不上
- B7 紅 ⇒ 不冪等,每個 session 都改一次 settings.json
- **C1 紅 ⇒ 動到了別人手加的規則**。這支只准加不准減
- E1 紅 ⇒ 目標壞掉時炸了——它掛在 SessionStart,炸了 session 就沒閘
- F1/F2 紅 ⇒ 沒接線:清單對了但沒人會去跑它
⚠️ **這支驗不了「分類器真的不擋」**——那要在雲端一趟 run 裡看 `permission_denials`
規則的形狀(`Bash(python3 …/isep/*/scripts/ticket *)`)沿用 leo 09-07 親手加、實測有效的那四條。
### A34 — 收件 repo 寫 `owner/repo` 不該是 4047 條
```
bash scripts/test-ticket-repo-arg.sh
```
**該看到**`通過 7 條,失敗 0 條`。把 `scripts/ticket` 當模組載進來、`api()` 換成只記路徑的假貨——
不打 Gitea、不開票、不留戳記。
**它在守什麼**inkstone/ISEP#130 → comment 6120 第 2 件):09-07 `ticket new inkstone/ISEP`
回 404。不是 ISEP 不存在,是 `inkstone/ISEP` 被原樣塞進 `/repos/inkstone/{repo}/issues`
⇒ 打到 `/repos/inkstone/inkstone/ISEP/issues`。**正門壞了人就走側門**——那天四張票是直接打 API 開的。
**失敗**:② 紅 ⇒ 那個 404 復發;③ 紅 ⇒ 寫錯 org 又變成一個要人猜的 404;⑦ 紅 ⇒ 路徑裡出現 `inkstone/inkstone`
### A35 — 雲端唯一通的通知路(Bot API 直送):10 條
```
bash scripts/test-isep-notify-botapi.sh
```
**該看到**`10/10 通過`。Bot API 指到本機一個假伺服器、實例那條也指到它——不打真 Telegram、不打實例。
**它在守什麼**inkstone/ISEP#1302026-09-07 從雲端實測):
```
notify_leo @ leo21c → HTTP 404「找不到 workflow」(08-28 起就斷;修它是 leo 的人閘)
notify_leo @ youlin → 雲端 egress proxy 回 403policy denial;要 leo 在 Cloud environment 放行主機)
api.telegram.org → 302,通
```
⇒ 雲端唯一走得通的是 Bot API 直送,只缺 `TELEGRAM_BOT_TOKEN``TELEGRAM_CHAT_ID` 兩個環境變數。
有就先走它(不碰實例,閘管不到也不必管);沒有要**點名缺哪兩個**,不能靜默。
**失敗**:A1 紅 ⇒ 沒憑證時不講缺什麼,leo 不知道要在 Cloud environment 加哪兩個;
B3 紅 ⇒ 送到了還去打實例;C1 紅 ⇒ 401 被講成送到;D1 紅 ⇒ 舊版閘 block 時直送也被連坐。
### A5 — 開票前的搜尋是跨 repo 的
```
python3 scripts/ticket where 標籤 模組化
@@ -954,6 +1057,11 @@ B2(信標那行)/B3(setup 輸出)/B4(閘的訊息)三個畫面
| **A18 信標會報雲端接線缺陷** | 總管 | ✅ 14/142026-08-28inkstone/ISEP#90 |
| **A19 下游做完頂層跟著關** | 總管 | ✅ 49/492026-08-28inkstone/ISEP#92 |
| **A20 舊票有固定管道被撈** | 總管 | ✅ 47/472026-08-28inkstone/ISEP#83)+真實 229 張唯讀實跑 |
| **A31 leo21c 讀放寫擋+改法指活的 youlin** | isep-hand | ✅ 26/262026-09-07inkstone/ISEP#130)+舊閘實跑 5 條紅 |
| **A32 主線檔隨 repo 走** | isep-hand | ✅ 17/172026-09-07inkstone/ISEP#130)+雲端 session 實跑讀到主線 |
| **A33 權限白名單住 ISEP 一份** | isep-hand | ✅ 19/192026-09-07inkstone/ISEP#130);「分類器真的不擋」要雲端 run 的 `permission_denials` 才驗得到 |
| **A34 收件 repo 寫 owner/repo 不 404** | isep-hand | ✅ 7/72026-09-07inkstone/ISEP#130 |
| **A35 Bot API 直送** | isep-hand | ✅ 10/102026-09-07);**真的到 leo 手機**要 Cloud environment 先有 `TELEGRAM_BOT_TOKEN``TELEGRAM_CHAT_ID`leo |
| A7 plugin 裝得起來 | 總管 | ✅ |
| **A8 新 session 閘會觸發** | 總管 | 見本版 release note |
| **B1B5 雲端** | **leo** | 還沒跑(機器碰不到 Cloud environment |
@@ -998,3 +1106,15 @@ arcrun_search_workflows(通知 leo Telegram) → 只回 ship_refresh_cdn 一
`#issuecomment-5182``#issuecomment-5184`),並把原文印在眼前。
**發不出去而靜默,等於沒做;發不出去但講出來並留下退路,就是這支的規格。**
通道修好之後不必改任何程式碼,重跑 `python3 scripts/isep-nag --notify` 即可補驗這一格。
### 2026-09-07 從雲端 session 再量一次(inkstone/ISEP#130
| 路 | 結果 | 誰能修 |
|---|---|---|
| `notify_leo` @ leo21c`…/webhooks/named/leo/notify_leo` | **HTTP 404**,跟 08-28 一樣 | leoleo21c 寫入是人閘) |
| `notify_leo` @ youlin`*.arcrun-yuga3bse.workers.dev` | **連不到:egress proxy 對 CONNECT 回 403**`/__agentproxy/status` 記為 policy denial)。不是 DNS、不是 000 | leoCloud environment 的 allowed network hosts |
| `api.telegram.org` | **302,通** | — |
⇒ 雲端能走的只有 Bot API 直送(`scripts/isep-notify` 現在會先試它),缺的只是兩個環境變數
`TELEGRAM_BOT_TOKEN``TELEGRAM_CHAT_ID`——Routine 文件 `cloud-worker.md` 檔頭本來就列著它們,
只是這個 environment 沒有。**這一格仍然是 leo 的:加變數,然後回一個詞。**