身為 leo,我要每次交貨都有 release tag 和 release note,我才知道手上是哪一版 #6

Closed
opened 2026-08-20 04:52:38 +00:00 by claude-code · 1 comment
Member

Parent: #1

目的:ISEP 的「版本」不再只是 README 上的一行字,而是 Gitea 上打得開、裝得起來的 release。

現況(實查 2026-08-20)README.md 宣稱 0.1.0,但 repo release_counter=0一個 tag 都沒有。leo 當場指出這是違規,且命中規範自己的 E12(宣稱交付但沒有 tag)。leo 補充:「release 不是寫在 readme,要放在 release 裡」。

怎麼驗:Releases 頁面上有 tag;release note 寫在 release 裡(不是 README);plugin.json 的版本號與 tag 一致;README 不再自己宣稱版本。

紅線:不得為了讓數字好看而補一個沒驗過的 tag——沒驗過就不是交付。

Parent: #1 **目的**:ISEP 的「版本」不再只是 README 上的一行字,而是 Gitea 上打得開、裝得起來的 release。 **現況(實查 2026-08-20)**:`README.md` 宣稱 0.1.0,但 repo `release_counter=0`、**一個 tag 都沒有**。leo 當場指出這是違規,且命中規範自己的 E12(宣稱交付但沒有 tag)。leo 補充:「release 不是寫在 readme,要放在 release 裡」。 **怎麼驗**:Releases 頁面上有 tag;release note 寫在 release 裡(不是 README);`plugin.json` 的版本號與 tag 一致;README 不再自己宣稱版本。 **紅線**:不得為了讓數字好看而補一個沒驗過的 tag——沒驗過就不是交付。
claude-code added this to the (deleted) milestone 2026-08-20 04:52:38 +00:00
claude-code added the
s
todo
p
high
type
governance
labels 2026-08-20 04:52:38 +00:00
claude-code added
s
doing
and removed
s
todo
labels 2026-08-20 04:55:08 +00:00
Author
Member

BLUF

結論:ISEP 的「現在是哪一版」改成結構性只有一個地方答得出來(Gitea Releases),機制與草稿已交,分支 leaf/6-release 已推送等總管驗收。沒有打 tag、沒有建 release(紅線)。

做了什麼

  1. README.md 不再自己宣告版本號。原本寫死的「狀態:0.1.0」段落改成「版本」段落,指向 https://git.uncle6.me/inkstone/ISEP/releases,並說明結構性防漂移機制。
  2. .claude-plugin/plugin.jsonversion0.1.0 改回哨兵值 0.0.0——誠實承認「目前沒有一個經過驗證、掛在 Releases 上的版本」,這正是這張票抓到的違規本身(宣稱版本卻沒有 tag 撐它)。真正打 tag 那天,version 要跟 tag 同一個 commit 一起改成那個號碼。
  3. 新增 scripts/check-version-consistency.sh:隨時可手動跑的一致性檢查——比對 plugin.jsonversion 是否等於最新 git tag(沒有 tag 時必須是 0.0.0),以及 README 是否偷偷又自報了版本號。不一致時 exit 1,訊息講清楚哪個檔案錯在哪。
  4. 新增 hooks/release-tag-guard.sh:PreToolUse Bash 閘,掛進 hooks.json。在有人(包含總管自己)真的執行 git tag 打版本時,攔下 tag 名稱裡的版本號,跟 plugin.jsonversion 比對,對不上就擋(exit 2)並印出具體差異與修法。這是「結構性做不到各說各話」的那一半——不必等事後跑腳本才發現。

實測被擋的輸出(故意製造不一致)

plugin.jsonversion 臨時改成 0.5.0(repo 仍是 0 個 tag),跑一致性腳本:

❌ 版本不一致:
   repo 裡沒有任何 tag(release_counter=0,還沒有一個正式 release)
   但 .claude-plugin/plugin.json 的 version 卻宣稱「0.5.0」
   → 這就是 inkstone/ISEP#6 抓到的違規本身:宣稱一個版本,卻沒有 tag 撐它。
   → 修法:version 改回 0.0.0(=尚未發過正式版),等真正打 tag 那天再同步改成那個號碼。
exit=1

模擬有人要打 git tag -a v0.2.0(當時 plugin.json 還是 0.0.0),直接餵給 hooks/release-tag-guard.sh

🚫 版本不一致,擋下這次打 tag(inkstone/ISEP#6:版本結構性防漂移閘)

你想打的 tag:v0.2.0(版本號 0.2.0)
.claude-plugin/plugin.json 現在的 version:0.0.0
...
exit=2

先把 plugin.json 同步成 0.2.0 再打同一個 tag → 放行(exit=0)。另外測了 4 種不該擋的形狀(git tag -lgit tag --list、echo 帶關鍵字、grep 帶關鍵字)→ 全部正確放行,沒有誤攔。還原成正確狀態後再跑一次一致性腳本 → ✅ 版本一致

Release note 草稿(給總管收進 v0.2.0 正式 release note 用)

版本回答只有一個地方:Gitea Releases

改了什麼:以前 ISEP 的「現在是哪一版」只寫在 README 一行字裡(0.1.0),但 Gitea 上一個 tag 都沒打過。現在改成:README 不再自己講版本、改指到 Releases 頁面;plugin.json 的版本欄位跟著最新 tag 走,沒 tag 時誠實顯示「0.0.0」;打 tag 的當下有一道閘會檢查兩邊數字對不對得上,對不上就擋下來。

你能怎麼驗:打開 Releases 頁面——以後這裡就是唯一答案;README 不會再看到寫死的版本號;打一個跟 manifest 對不上的 tag 會被擋下,訊息直接講清楚差在哪。

沒做的事:這次沒有打任何 tag、沒有建任何 release——那件事等整個 v0.2.0 milestone(5 張票)都驗完,由總管一次交付。

分支

leaf/6-release(已推送到 origin,未動 main)

紅線確認

  • 沒有自己打 tag、沒有自己建 release
  • 沒有為了讓數字好看而讓沒驗過的東西看起來像交付了(plugin.json 改成 0.0.0 哨兵值而不是隨便寫一個新號碼,就是這條紅線的直接體現)
  • 沒有 push 到 main
  • 沒有動 system-dev/labels.yaml.claude-plugin/marketplace.json;只動了 .claude-plugin/plugin.json 的版本欄位(派工單允許的範圍)
## BLUF **結論**:ISEP 的「現在是哪一版」改成結構性只有一個地方答得出來(Gitea Releases),機制與草稿已交,分支 `leaf/6-release` 已推送等總管驗收。**沒有打 tag、沒有建 release**(紅線)。 ## 做了什麼 1. **README.md** 不再自己宣告版本號。原本寫死的「狀態:0.1.0」段落改成「版本」段落,指向 `https://git.uncle6.me/inkstone/ISEP/releases`,並說明結構性防漂移機制。 2. **`.claude-plugin/plugin.json`** 的 `version` 從 `0.1.0` 改回哨兵值 `0.0.0`——誠實承認「目前沒有一個經過驗證、掛在 Releases 上的版本」,這正是這張票抓到的違規本身(宣稱版本卻沒有 tag 撐它)。真正打 tag 那天,`version` 要跟 tag 同一個 commit 一起改成那個號碼。 3. 新增 **`scripts/check-version-consistency.sh`**:隨時可手動跑的一致性檢查——比對 `plugin.json` 的 `version` 是否等於最新 git tag(沒有 tag 時必須是 `0.0.0`),以及 README 是否偷偷又自報了版本號。不一致時 exit 1,訊息講清楚哪個檔案錯在哪。 4. 新增 **`hooks/release-tag-guard.sh`**:PreToolUse Bash 閘,掛進 `hooks.json`。在有人(包含總管自己)真的執行 `git tag` 打版本時,攔下 tag 名稱裡的版本號,跟 `plugin.json` 的 `version` 比對,對不上就擋(exit 2)並印出具體差異與修法。這是「結構性做不到各說各話」的那一半——不必等事後跑腳本才發現。 ## 實測被擋的輸出(故意製造不一致) 把 `plugin.json` 的 `version` 臨時改成 `0.5.0`(repo 仍是 0 個 tag),跑一致性腳本: ``` ❌ 版本不一致: repo 裡沒有任何 tag(release_counter=0,還沒有一個正式 release) 但 .claude-plugin/plugin.json 的 version 卻宣稱「0.5.0」 → 這就是 inkstone/ISEP#6 抓到的違規本身:宣稱一個版本,卻沒有 tag 撐它。 → 修法:version 改回 0.0.0(=尚未發過正式版),等真正打 tag 那天再同步改成那個號碼。 exit=1 ``` 模擬有人要打 `git tag -a v0.2.0`(當時 `plugin.json` 還是 `0.0.0`),直接餵給 `hooks/release-tag-guard.sh`: ``` 🚫 版本不一致,擋下這次打 tag(inkstone/ISEP#6:版本結構性防漂移閘) 你想打的 tag:v0.2.0(版本號 0.2.0) .claude-plugin/plugin.json 現在的 version:0.0.0 ... exit=2 ``` 先把 `plugin.json` 同步成 `0.2.0` 再打同一個 tag → 放行(`exit=0`)。另外測了 4 種不該擋的形狀(`git tag -l`、`git tag --list`、echo 帶關鍵字、grep 帶關鍵字)→ 全部正確放行,沒有誤攔。還原成正確狀態後再跑一次一致性腳本 → `✅ 版本一致`。 ## Release note 草稿(給總管收進 v0.2.0 正式 release note 用) > ### 版本回答只有一個地方:Gitea Releases > > **改了什麼**:以前 ISEP 的「現在是哪一版」只寫在 README 一行字裡(0.1.0),但 Gitea 上一個 tag 都沒打過。現在改成:README 不再自己講版本、改指到 Releases 頁面;`plugin.json` 的版本欄位跟著最新 tag 走,沒 tag 時誠實顯示「0.0.0」;打 tag 的當下有一道閘會檢查兩邊數字對不對得上,對不上就擋下來。 > > **你能怎麼驗**:打開 [Releases 頁面](https://git.uncle6.me/inkstone/ISEP/releases)——以後這裡就是唯一答案;README 不會再看到寫死的版本號;打一個跟 manifest 對不上的 tag 會被擋下,訊息直接講清楚差在哪。 > > **沒做的事**:這次沒有打任何 tag、沒有建任何 release——那件事等整個 v0.2.0 milestone(5 張票)都驗完,由總管一次交付。 ## 分支 `leaf/6-release`(已推送到 origin,未動 main) ## 紅線確認 - 沒有自己打 tag、沒有自己建 release - 沒有為了讓數字好看而讓沒驗過的東西看起來像交付了(`plugin.json` 改成 `0.0.0` 哨兵值而不是隨便寫一個新號碼,就是這條紅線的直接體現) - 沒有 push 到 main - 沒有動 `system-dev/`、`labels.yaml`、`.claude-plugin/marketplace.json`;只動了 `.claude-plugin/plugin.json` 的版本欄位(派工單允許的範圍)
claude-code added
s
review
and removed
s
doing
labels 2026-08-20 05:03:31 +00:00
claude-code added the
close
merged
label 2026-08-20 05:10:19 +00:00
claude-code added this to the (deleted) milestone 2026-08-20 09:12:26 +00:00
claude-code added this to the (已撤回)ISEP 初期鷹架 milestone 2026-08-20 10:37:40 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: inkstone/ISEP#6