da9bd53cae
兩張票放同一條分支:都是「該發生卻不會自己發生的事」,觸發點都在 session 邊界。 ## inkstone/ISEP#93 —— 逾期和掛著沒人接的事會主動叫 - scripts/isep-nag 撈三種沒人會叫的事(逾期 milestone/等 leo 的票/掉在地上的棒子) - scripts/isep-notify 發 Telegram,而且**發不出去的時候不會安靜** - hooks/overdue-nag-guard.sh SessionStart 跑一次(不輪詢、不 fan-out、不掛 Actions) - hooks/tests/overdue-nag.test.sh 35 條,全程離線 實跑撈得出票上點名的那五個逾期 milestone(08-24 三個、08-26 兩個)。 沒東西可報時會說「查過了,沒有」——安靜跟壞掉長得一模一樣。 🔴 工單補的那個限制(今天實測出來的)已經處理: 「能不能發得出去」取決於這個 session 載到的 ISEP 是哪一版 (prod-write-guard v0.10.0 才認得出 notify_leo 不是部署,而 hook 註冊路徑 在 session 啟動當下就寫死了)。所以 isep-notify 會**先拿真的要送的那一則 去問這個 session 註冊的那支閘**,把判定寫成檔(誰都查得到),然後: · 放行 ⇒ 送,並驗內層 data.data.ok(外層 200 不算送到) · 會擋 ⇒ **不繞路**,改貼回票上並把原文印在眼前 用 git 歷史裡的真跡(c263866 那一版閘)測過「會擋」那條路。 ⛔ 實測發現通道本身現在是斷的:實例上找不到 notify_leo 工作流(404)。 不是閘、不是網路、不是金鑰。詳情與修法寫在 docs/TESTING.md 最後一段。 退路兩次都走通了(inkstone/ISEP#93 comment 5182、5184)。 ## inkstone/ISEP#89 —— wiki 太長時有人整理 - scripts/wiki-compress audit/plan/apply/verify/bench 五個動詞 - hooks/wiki-size-guard.sh SessionStart 點名太長的檔;寫檔時擋「沒走流程的壓縮」 - hooks/tests/wiki-compress.test.sh 25 條,全程離線、不碰真的 wiki 設計上最重要的一條:**只搬不改**,正文一個字都不動。 「合併同類、濃縮成一行」要重寫正文,而重寫的當下沒有人會發現弄丟了什麼。 所以機器只做「搬 + 目錄 + 標 ×N/↻」,合併留給人。 拿現在的 mistakes.md 複本實壓過(不動真的 wiki): 7,681 行 → 1,199 行 260 條一條都沒少(verify 用內文雜湊逐條對帳) 80 個查詢命中率 80/80,定位成本 2,956 → 131 行,**快 22.5 倍**(bench) verify 反向測過:真的弄丟一條時它抓得到(抓不到的對帳表比沒有更糟)。 ## 盤點數字 在這棵樹上當場數的,不是拿上一版加減推的: ls hooks/*.sh | wc -l → 55(was 53) grep -c '"command":' hooks.json → 71(was 68) plugin.json/README/hooks-inventory 三處同步改。 **版本號沒動**(0.11.0),待總管定版。
66 lines
3.5 KiB
Markdown
66 lines
3.5 KiB
Markdown
# ISEP — InkStone Environment Plugin
|
||
|
||
> leo 2026-08-20:「你把全部環境設定放在一個 claude code plugin,**同一個 plugin 你用,薄殼也用,保證兩邊同步**⋯⋯
|
||
> 以後有任何變化,增加 command, hook⋯⋯都增加在這裡,再去跟它同步。」
|
||
> 「我要你幫雲端做薄殼,永遠都有問題,**你要做的就是這組設定你自己可以 dogfooding**。」
|
||
|
||
## 這個 repo 解什麼
|
||
|
||
在此之前,同一套環境有**兩份**:
|
||
|
||
```
|
||
真身 InkStoneCo/.claude/ ← 本機在跑的
|
||
薄殼 由 generate-shell-payload.py 產生一份,塞進 GitHub 私 repo ← 雲端在跑的
|
||
```
|
||
|
||
兩份必然漂移。`inkstone/InkStoneCo#57` 記著實測結果:**薄殼比真身少 7 支閘**,
|
||
其中兩支是前一天才立的。`#14` 更早:雲端 33 支 guard **一支都沒生效**。
|
||
|
||
⇒ 現在只有一份:**本 repo 就是唯一真相源**,本機與雲端裝同一個 plugin。
|
||
⇒ 而且**總管自己也用它**——壞掉的時候是我先踩到,不是雲端替我踩。
|
||
|
||
## 裝什麼
|
||
|
||
| | 數量 | 是什麼 |
|
||
|---|---|---|
|
||
| `hooks/` | 55 支 + `hooks.json` | 全部機械閘(PreToolUse/Stop/SubagentStop/SessionStart/PostToolUse/UserPromptSubmit 共 71 條註冊)。**數字一律當場數**:`ls hooks/*.sh \| wc -l` 與 `grep -c '"command":' hooks/hooks.json`(冒號不能省),白話盤點見 `docs/hooks-inventory.md` |
|
||
| `commands/` | 7 支 | `/wiki-recall` `/ship-check` `/cp-write` … |
|
||
| `skills/` | 2 支 | |
|
||
| `scripts/` | 23 支 | `ticket`/`github-arm.sh`/`gitea-bootstrap.sh` … |
|
||
|
||
**不放**:`.env`(金鑰,違 D36「金鑰只有一個家」)、`wiki/`、`docs/`、`_archive/`
|
||
——那些是**知識**不是**環境**。
|
||
|
||
## 路徑規約(薄殼一直壞掉的根)
|
||
|
||
hook 一律用官方的 `${CLAUDE_PLUGIN_ROOT}`,**不准寫死絕對路徑、也不用 `$CLAUDE_PROJECT_DIR`
|
||
去指 hook 自己**:雲端的 cwd 不是真身,寫死就斷。
|
||
腳本**內部**要指專案檔案(wiki、docs)時才用 `$CLAUDE_PROJECT_DIR`——那是對的,
|
||
因為那些東西本來就住在被操作的那個 repo 裡。
|
||
|
||
## 改東西的規矩
|
||
|
||
🔴 **只改這裡,然後兩邊 `/plugin update`。**
|
||
不要再改 `InkStoneCo/.claude/hooks/`——那個目錄退場中。
|
||
|
||
## 這些閘各自在管什麼
|
||
|
||
**不用點開任何 `.sh`**——`docs/hooks-inventory.md` 一支一行白話,按「你會在什麼時候撞到它」分組。
|
||
測試手冊在 `docs/TESTING.md`,治理規範在 `docs/governance/`。
|
||
|
||
🔴 **派工前先讀 `docs/governance/dispatch-and-reply-format.md`**——
|
||
派工單只給票號(其餘全部寫進票或共通規定),票上的每一則留言第一行要表明身份。
|
||
兩件事都有機械閘(`dispatch-format-guard.sh`/`reply-identity-guard.sh`)。
|
||
|
||
## 版本
|
||
|
||
**「ISEP 現在是哪一版」只有一個地方答得出來:[Gitea Releases](https://git.uncle6.me/inkstone/ISEP/releases)。**
|
||
每一版的內容、改了什麼、驗過什麼都寫在那裡的 release note,不寫在這份 README。
|
||
|
||
這份 README 本來寫死過「狀態:0.1.0」,但 repo 一個 tag 都沒打(`release_counter=0`)——
|
||
leo 當場指出這是違規:宣稱交付卻沒有 tag 撐它(`inkstone/ISEP#6`)。
|
||
現在改成結構性防漂移:`.claude-plugin/plugin.json` 的 `version` 欄位永遠跟最新 tag 一致,
|
||
`scripts/check-version-consistency.sh` 會擋下兩者對不上的狀態,
|
||
`hooks/release-tag-guard.sh` 則在打 tag 的當下直接擋住不一致的 tag——
|
||
細節與判準都寫在那兩支腳本開頭的註解。
|