Files
ISEP/README.md
T
Leo d19bf88503 雲端對 stage 的寫入有正門:scripts/stage(secret/api)只寫 youlin,白名單放固定形狀(inkstone/ISEP#137)
09-07 三種寫入在雲端全被 auto mode 分類器擋:npx wrangler secret put、
stage-deploy-artifacts.py --confirm、curl POST 到 arcrun-yuga3bse——
白名單是逐條比前綴,複合指令與任意 curl 永遠對不上;放整類又是紅線。

- scripts/stage secret put|list|delete:直接打 CF API(不經 npx);先 GET /accounts
  看這把 token 打得到誰,stage 的 ID 不在裡面就拒絕並印出它打得到誰;URL 永遠只帶
  1129efd7…;值只從 --from-env 讀,--value 拒收。
- scripts/stage api <METHOD> <worker>/<path>:curl 打實例,主機只會是
  *.arcrun-yuga3bse.workers.dev,別的主機拒絕;標頭與 body 走 stdin 設定檔+管線,
  不走 argv;--bearer-env/--header-env/--data-env 從環境變數讀。
- docs/permissions-allow.json:stage 四種形狀+Arcrun 自己那支 stage-deploy-artifacts.py
  的相對形狀(它已寫死只認 youlin 帳號 ID、不收 --account/--token,不重造)。
- scripts/test-stage.sh 45 條(假 CF 對 PUT 回 201——第一次實跑 CF 回 201 被講成失敗,
  就是這格抓的);test-settings-allow-sync 仍 19/19。
- 真跑:探針種進 youlin arcrun-cypher-executor、CF API 獨立列到、刪掉恢復原狀;
  api GET health 200、無 Bearer POST 401、leo21c 主機拒絕零請求。
  「帶 Bearer 真寫 KBDB」缺 KBDB_INTERNAL_TOKEN 沒跑(TESTING A36 標明)。

盤點在本樹實數:hooks 61、註冊 85(都沒動)、scripts 56(+stage、+test-stage.sh)。
版本待總管定版。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DTZ9QtvjY7MNxjfQbexAm7
2026-09-07 02:31:18 +00:00

100 lines
5.6 KiB
Markdown
Raw 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.
# 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/` | 61 支 `hooks.json` | 全部機械閘(PreToolUseStopSubagentStopSessionStartPostToolUseUserPromptSubmit 共 85 條註冊)。**一支一行的白話盤點在 `docs/hooks-inventory.md`,那裡才是這兩個數字的家** |
| `agents/` | 7 位 | **工人名單**`inkstone/ISEP#86`)——派工時指名派給誰,規約見 `docs/governance/worker-roster.md` |
| `commands/` | 7 支 | `/wiki-recall` `/wiki-capture` `/cp-write` `/issue-handle` … |
| `skills/` | 2 支 | `ship-check`(東西要出去之前)/`deep-recall`(把散落的枝葉還原成一棵樹)。🔴 **這兩支的內容不一定是在這裡寫的**——誰是真相源查 `docs/file-ownership.tsv` |
| `scripts/` | 56 支 | `ticket``roster``isep-nag``wiki-compress``github-arm.sh` …(頂層檔案,不含 `lib/` 等子目錄) |
> 🔴 這五個數字**每次都要在自己的樹上實數**,不准沿用上一版、也不准用加減推
> `system-dev/wiki/mistakes.md`:那是 leo 的驗收介面,多報就是假綠):
>
> ```sh
> ls hooks/*.sh | wc -l # hooks
> grep -c '"command":' hooks/hooks.json # 註冊條數(冒號不能省,省了會數到 "type": "command"
> ls agents/*.md | wc -l
> ls commands/*.md | wc -l ; ls -d skills/*/ | wc -l
> ls -p scripts | grep -v / | wc -l # scripts(只數檔案,不含子目錄)
> ```
>
> 🔴 **光看數字對不對還不夠**——`hooks.json` 合錯的時候「語法合法、閘卻不見了」,
> **不會有任何東西喊一聲**。合併過 `hooks.json` 之後一律再跑這一支,逐支點名:
>
> ```sh
> python3 -c "
> import json,collections
> d=json.load(open('hooks/hooks.json'))
> c=collections.Counter(h['command'].split('/')[-1] for ev in d['hooks'].values() for g in ev for h in g.get('hooks',[]))
> print('總註冊', sum(c.values()))
> for k in sorted(c): print(' ', k, c[k])
> "
> ```
>
> **這是 leo 的驗收介面**——多報就是假綠(`docs/hooks-inventory.md` 開頭記著同一個病)。
**不放**`.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/`——那個目錄退場中。
🔴 **但有些檔案的內容不是在這裡寫的**`inkstone/ISEP#122`):
`skills/``commands/``agents/` 底下有幾個檔案在 InkStoneCo 也有一份,
**誰是真相源、往哪個方向修,一律查 `docs/file-ownership.tsv`**,不要憑「ISEP 一定比較新」動手
——2026-09-02 實查,兩個方向都真的發生過(`ship-check` 是那邊新,`sdd-check` 是這邊新)。
改完那類檔案要把 commit/sha256 兩欄一起更新;沒更新的話,
`isep-presence-beacon.sh` 會在下一個 session 開場當著大家的面說它對不上。
## 這些閘各自在管什麼
**不用點開任何 `.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——
細節與判準都寫在那兩支腳本開頭的註解。