feat/lang-guard-traditional-chinese-encoding #28

Merged
admin merged 6 commits from feat/lang-guard-traditional-chinese-encoding into develop 2026-08-27 01:58:38 +00:00
Member

feat/lang-guard-traditional-chinese-encoding

摘要

  • 需求描述:新增第七支 hook lang-guard.sh,強制「所有非程式碼輸出必須是繁體中文、UTF-8、無亂碼、無簡體字」。範圍涵蓋程式碼註解、commit 訊息、PR 描述、wiki 頁、對使用者的回報、README 與各種文件。規則正文的真實來源仍是 jsc-meta 的 references/ste100.md,本存取庫只放判定實作與機檢字表。
  • 計畫名稱:無
  • 計畫頁:無
  • 分析頁:無

變更內容

檔案 為什麼改
hooks/lang-guard.sh 新增。三種模式(prompt、無參數單檔、sweep [dir]),偵測簡體字、亂碼、非 UTF-8 編碼。命中走 stderr 並 exit 2,資料不足一律安靜 exit 0,逃生門 JSC_LANG_GUARD=off
hooks/simplified.txt 新增。機檢用的簡體字表,一行一字共 102 字,內容照抄 jsc-meta tools/ste100-lint.sh 的 SIMPLIFIED 變數,不增不刪。這是本存取庫的單一真實來源
hooks/hooks.json claude 接線:UserPromptSubmit 加 lang-guard.sh prompt,PostToolUse 的 Write|Edit|MultiEdit 加無參數模式
hooks/ste100-guard.sh 注入文字補上「適用範圍是所有非程式碼輸出」與「UTF-8 無亂碼、無簡體字,不加 BOM」
tools/wire-cli.sh codex 的 notify 與 kiro 的 userPromptSubmit 串上 lang-guard.sh sweep;rules_text() 加上 lang-guard.sh prompt 的輸出;smoke 三種模式各跑一輪並沿用既有的 exit 2 例外;status 補盤點項;寫入後驗證新增 has_lang_guard()
tools/jsc-wrap.sh copilot 與 antigravity 的收尾再跑一次 lang-guard.sh sweep,以 || true 接住 exit 2,不蓋掉 CLI 自己的結束碼
README.md hook 一覽表新增一列;所有「六支 hook」改七支;環境變數表補 JSC_LANG_GUARD;tools/jsc-wrap.sh 那列補收尾 sweep
skills/hooks-install/SKILL.md 六支改七支,覆蓋範圍表與備註補這支;description 括號清單加上 language guard,維持英文 4 句並保留觸發時機
AGENTS.md domain 說明與規則清單同步,新增第 6 條繁中無亂碼規則
plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json 三份 manifest 版本 0.2.0 升到 0.2.1

設計重點

  • 簡體字與亂碼檢查掃整個檔案,不只掃註解行。 程式碼的任何位置都不該出現簡體字——字串常值、識別字、資料內容一樣算輸出。這跟既有的 comment-scope.sh 不同,那支只掃註解行,因為它抓的是註解夾帶文件編號,那件事只發生在註解裡。
  • markdown 與純文字檔要掃。 它們正是「非程式碼輸出」的主場:README、wiki 頁、PR 描述、commit 訊息都是這類檔案。comment-scope.sh 刻意跳過 .md,因為那裡沒有程式碼註解,這支的判斷剛好相反。
  • 字表放本存取庫,當機檢的單一真實來源。 jsc-meta 的 ste100-lint.sh 優先讀這份、讀不到才用它自己的內建備援。本存取庫不放第二份字表,腳本裡也不留字元清單副本。
  • 各 CLI 的掃描時機不同,不得寫成五支一樣。 claude 逐檔即時(PostToolUse)、codex 每輪結束(notify)、kiro 每輪提示送出時(userPromptSubmit,掃到的是上一輪寫的檔)、copilot 與 antigravity 只有工作階段結束時由 tools/jsc-wrap.sh 收尾掃一次。sweep 看的是 git diff HEAD,涵蓋範圍與 claude 一樣,差的只有回饋速度。
  • 誤報防線做在字表與跳過清單裡。 字表刻意排除繁體也在用的字(后、台、干、只、里、面、制、志);掃描跳過 simplified.txt、ste100-guard.sh、lang-guard.sh 三份以簡體字與亂碼為討論對象的檔案,不然這支 hook 每次都會先抓到自己,訊號全被自己的噪音蓋掉。
  • 亂碼用位元組比對,不靠語系字元範圍。 grep -E 的字元範圍在不同語系下行為不一致,位元組範圍到哪都一樣。雙重編碼的前導字收整個 Latin-1 字母段而不只收 Ã:中文的 UTF-8 前導位元組落在 E4–E9,被當成 Latin-1 讀一次後會變成 測試 這種 ä–é 開頭的長相,只收 à 會漏掉最常見的中文亂碼。
  • 安靜降級的邊界一致。 字表讀不到就跳過簡體字這一項、沒有 iconv 就跳過編碼那一項,都不中斷整支腳本;少抓一項好過整支 hook 死掉。

測試結果

  1. sh -n 語法檢查,三支皆 exit 0:
hooks/lang-guard.sh -> exit 0
tools/wire-cli.sh -> exit 0
tools/jsc-wrap.sh -> exit 0
  1. hooks/hooks.json 通過 JSON 解析:
JSON ok, events: ['SessionStart', 'UserPromptSubmit', 'Stop', 'SessionEnd', 'PreToolUse', 'PostToolUse']
UserPromptSubmit cmds: 5
PostToolUse write block cmds: ['comment-scope.sh', 'lang-guard.sh']
  1. 暫存測試檔(全部放 /tmp,未進存取庫)單檔掃描:
測試檔 內容 結束碼 預期
simp.txt 含簡體字 2 2
fffd.txt 含 U+FFFD 替代字元 2 2
trad.txt 純正體中文 0 0
code.c 純英文程式碼 0 0
falsepos.txt 后、台、干、只、里、面、制、志 0 0(誤報防線)
latin1.txt Latin-1 編碼 2 2
dbl.txt 雙重編碼 測試 2 2
dbl2.txt 雙重編碼引號 2 2
accent.txt câmara、crème、naïve 0 0(誤報防線)

誤報防線那一列的實際輸出:

falsepos.txt -> exit 0
accent.txt -> exit 0
  1. 暫存 git 庫實測 sweep:
== 4a. 乾淨工作區 sweep ==            exit 0
== 4b. 違規工作區 sweep(庫根)==     exit 2
    [jsc] 工作區有簡體字、亂碼或編碼問題,請就地修正:
      /tmp/.../gtest/doc.md
        簡體字,改成繁體
          1:新增一行:这里有简体字,应该被抓到。
      修法:簡體字換成對應繁體字;亂碼那段重打,不要留著半壞的字元;檔案存成 UTF-8。
      規則正文見 jsc-meta 的 references/ste100.md,字表在 hooks/simplified.txt。誤判時用 JSC_LANG_GUARD=off 關閉。
== 4c. 從子目錄找得到庫根 ==          exit 2
== 4d. 非 git 目錄 ==                 exit 0
== 4e. 修好後回復乾淨 ==              exit 0
  1. sh tools/wire-cli.sh smoke claude 完整輸出:
status=ok reason=七支 hook 的每個接線模式都跑得完,沒有執行期錯誤
[jsc] session-timer.sh mark:exit 0,正常。
[jsc] sdlc-gate.sh check:exit 0,正常。
[jsc] version-guard.sh:exit 0,正常。
[jsc] skill-usage.sh:exit 0,正常。
[jsc] ste100-guard.sh:exit 0,正常。
[jsc] sdlc-gate.sh wp-check prompt:exit 0,正常。
[jsc] sdlc-gate.sh wp-check skill:exit 0,正常。
[jsc] comment-scope.sh prompt:exit 0,正常。
[jsc] comment-scope.sh:exit 0,正常。
[jsc] comment-scope.sh sweep:exit 0,正常。
[jsc] lang-guard.sh prompt:exit 0,正常。
[jsc] lang-guard.sh:exit 0,正常。
[jsc] lang-guard.sh sweep:exit 0,正常。
smoke exit 0
  1. 結束碼保護實測。假 CLI exit 42 搭配必定命中的工作區(先確認 lang-guard.sh sweep 對該工作區回 2):
== 先確認工作區必定命中 ==
lang-guard sweep exit 2
== 6. jsc-wrap.sh 結束碼保護 ==
    fake copilot ran, args: --hello
    [jsc] 工作區有簡體字、亂碼或編碼問題,請就地修正:
      /tmp/.../gtest/doc.md
        簡體字,改成繁體
          1:新增一行:这里有简体字,应该被抓到。
jsc-wrap.sh exit 42  (expect 42)
  1. 誤判回歸。對 /root/plugins 底下所有 *.sh、*.md、*.json、*.txt 逐檔整檔掃描(複製到非 git 暫存目錄以強制整檔掃,不是只掃 diff):
整檔掃描:scanned=437 hits=2
HIT: /root/plugins/meta/tools/ste100-lint.sh
HIT: /root/plugins/sdlc/references/cpm-chart.md
jsc-hooks 原地掃描:scanned=28 hits=0

兩筆命中逐一說明:sdlc/references/cpm-chart.md 是已知的真實簡體字(「只會出现在這一步」),不在本存取庫;meta/tools/ste100-lint.sh 命中的是它自己的 SIMPLIFIED_FALLBACK 備援字表那一行,屬於「被討論的對象」而非被使用,與本存取庫跳過 simplified.txt 是同一個道理,同樣不在本存取庫。本存取庫 28 個檔案 0 命中。

補充驗證(非必做七項,一併附上):以假執行檔加暫存 HOME 實跑 codex 與 kiro 接線,兩份設定寫入後 status 全部 present:

== kiro status ==
item	jsc-hooks-session-start	./.kiro/hooks/jsc-hooks-session-start.json	present
item	jsc-hooks	./.kiro/hooks/jsc-hooks.json	present
item	comment-scope	./.kiro/hooks/jsc-hooks.json	present
item	comment-scope-sweep	./.kiro/hooks/jsc-hooks.json	present
item	lang-guard	./.kiro/hooks/jsc-hooks.json	present
item	lang-guard-sweep	./.kiro/hooks/jsc-hooks.json	present

== codex status ==
item	notify	.../config.toml	present
item	notify-root	.../config.toml	present
item	notify-sweep	.../config.toml	present
item	notify-lang-sweep	.../config.toml	present
item	alias	.../.bashrc	present
item	ste100	.../AGENTS.md	present
item	comment-scope	.../AGENTS.md	present
item	lang-guard	.../AGENTS.md	present

本存取庫自我檢查:comment-scope.sh sweep . 與 lang-guard.sh sweep . 皆 exit 0。

前置 Push Request

  • 無
# feat/lang-guard-traditional-chinese-encoding ## 摘要 - 需求描述:新增第七支 hook `lang-guard.sh`,強制「所有非程式碼輸出必須是繁體中文、UTF-8、無亂碼、無簡體字」。範圍涵蓋程式碼註解、commit 訊息、PR 描述、wiki 頁、對使用者的回報、README 與各種文件。規則正文的真實來源仍是 jsc-meta 的 `references/ste100.md`,本存取庫只放判定實作與機檢字表。 - 計畫名稱:無 - 計畫頁:無 - 分析頁:無 ## 變更內容 | 檔案 | 為什麼改 | | --- | --- | | `hooks/lang-guard.sh` | 新增。三種模式(`prompt`、無參數單檔、`sweep [dir]`),偵測簡體字、亂碼、非 UTF-8 編碼。命中走 stderr 並 exit 2,資料不足一律安靜 exit 0,逃生門 `JSC_LANG_GUARD=off` | | `hooks/simplified.txt` | 新增。機檢用的簡體字表,一行一字共 102 字,內容照抄 jsc-meta `tools/ste100-lint.sh` 的 `SIMPLIFIED` 變數,不增不刪。這是本存取庫的單一真實來源 | | `hooks/hooks.json` | claude 接線:`UserPromptSubmit` 加 `lang-guard.sh prompt`,`PostToolUse` 的 `Write\|Edit\|MultiEdit` 加無參數模式 | | `hooks/ste100-guard.sh` | 注入文字補上「適用範圍是所有非程式碼輸出」與「UTF-8 無亂碼、無簡體字,不加 BOM」 | | `tools/wire-cli.sh` | codex 的 `notify` 與 kiro 的 `userPromptSubmit` 串上 `lang-guard.sh sweep`;`rules_text()` 加上 `lang-guard.sh prompt` 的輸出;`smoke` 三種模式各跑一輪並沿用既有的 exit 2 例外;`status` 補盤點項;寫入後驗證新增 `has_lang_guard()` | | `tools/jsc-wrap.sh` | copilot 與 antigravity 的收尾再跑一次 `lang-guard.sh sweep`,以 `\|\| true` 接住 exit 2,不蓋掉 CLI 自己的結束碼 | | `README.md` | hook 一覽表新增一列;所有「六支 hook」改七支;環境變數表補 `JSC_LANG_GUARD`;`tools/jsc-wrap.sh` 那列補收尾 sweep | | `skills/hooks-install/SKILL.md` | 六支改七支,覆蓋範圍表與備註補這支;`description` 括號清單加上 language guard,維持英文 4 句並保留觸發時機 | | `AGENTS.md` | domain 說明與規則清單同步,新增第 6 條繁中無亂碼規則 | | `plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` | 三份 manifest 版本 0.2.0 升到 0.2.1 | ## 設計重點 - **簡體字與亂碼檢查掃整個檔案,不只掃註解行。** 程式碼的任何位置都不該出現簡體字——字串常值、識別字、資料內容一樣算輸出。這跟既有的 `comment-scope.sh` 不同,那支只掃註解行,因為它抓的是註解夾帶文件編號,那件事只發生在註解裡。 - **markdown 與純文字檔要掃。** 它們正是「非程式碼輸出」的主場:README、wiki 頁、PR 描述、commit 訊息都是這類檔案。`comment-scope.sh` 刻意跳過 `.md`,因為那裡沒有程式碼註解,這支的判斷剛好相反。 - **字表放本存取庫,當機檢的單一真實來源。** jsc-meta 的 `ste100-lint.sh` 優先讀這份、讀不到才用它自己的內建備援。本存取庫不放第二份字表,腳本裡也不留字元清單副本。 - **各 CLI 的掃描時機不同,不得寫成五支一樣。** claude 逐檔即時(`PostToolUse`)、codex 每輪結束(`notify`)、kiro 每輪提示送出時(`userPromptSubmit`,掃到的是上一輪寫的檔)、copilot 與 antigravity 只有工作階段結束時由 `tools/jsc-wrap.sh` 收尾掃一次。`sweep` 看的是 `git diff HEAD`,涵蓋範圍與 claude 一樣,差的只有回饋速度。 - **誤報防線做在字表與跳過清單裡。** 字表刻意排除繁體也在用的字(后、台、干、只、里、面、制、志);掃描跳過 `simplified.txt`、`ste100-guard.sh`、`lang-guard.sh` 三份以簡體字與亂碼為討論對象的檔案,不然這支 hook 每次都會先抓到自己,訊號全被自己的噪音蓋掉。 - **亂碼用位元組比對,不靠語系字元範圍。** `grep -E` 的字元範圍在不同語系下行為不一致,位元組範圍到哪都一樣。雙重編碼的前導字收整個 Latin-1 字母段而不只收 `Ã`:中文的 UTF-8 前導位元組落在 E4–E9,被當成 Latin-1 讀一次後會變成 `測試` 這種 `ä`–`é` 開頭的長相,只收 `Ã` 會漏掉最常見的中文亂碼。 - **安靜降級的邊界一致。** 字表讀不到就跳過簡體字這一項、沒有 `iconv` 就跳過編碼那一項,都不中斷整支腳本;少抓一項好過整支 hook 死掉。 ## 測試結果 1. `sh -n` 語法檢查,三支皆 exit 0: ``` hooks/lang-guard.sh -> exit 0 tools/wire-cli.sh -> exit 0 tools/jsc-wrap.sh -> exit 0 ``` 2. `hooks/hooks.json` 通過 JSON 解析: ``` JSON ok, events: ['SessionStart', 'UserPromptSubmit', 'Stop', 'SessionEnd', 'PreToolUse', 'PostToolUse'] UserPromptSubmit cmds: 5 PostToolUse write block cmds: ['comment-scope.sh', 'lang-guard.sh'] ``` 3. 暫存測試檔(全部放 /tmp,未進存取庫)單檔掃描: | 測試檔 | 內容 | 結束碼 | 預期 | | --- | --- | --- | --- | | `simp.txt` | 含簡體字 | 2 | 2 | | `fffd.txt` | 含 U+FFFD 替代字元 | 2 | 2 | | `trad.txt` | 純正體中文 | 0 | 0 | | `code.c` | 純英文程式碼 | 0 | 0 | | `falsepos.txt` | 后、台、干、只、里、面、制、志 | 0 | 0(誤報防線) | | `latin1.txt` | Latin-1 編碼 | 2 | 2 | | `dbl.txt` | 雙重編碼 `測試` | 2 | 2 | | `dbl2.txt` | 雙重編碼引號 | 2 | 2 | | `accent.txt` | `câmara`、`crème`、`naïve` | 0 | 0(誤報防線) | 誤報防線那一列的實際輸出: ``` falsepos.txt -> exit 0 accent.txt -> exit 0 ``` 4. 暫存 git 庫實測 `sweep`: ``` == 4a. 乾淨工作區 sweep == exit 0 == 4b. 違規工作區 sweep(庫根)== exit 2 [jsc] 工作區有簡體字、亂碼或編碼問題,請就地修正: /tmp/.../gtest/doc.md 簡體字,改成繁體 1:新增一行:这里有简体字,应该被抓到。 修法:簡體字換成對應繁體字;亂碼那段重打,不要留著半壞的字元;檔案存成 UTF-8。 規則正文見 jsc-meta 的 references/ste100.md,字表在 hooks/simplified.txt。誤判時用 JSC_LANG_GUARD=off 關閉。 == 4c. 從子目錄找得到庫根 == exit 2 == 4d. 非 git 目錄 == exit 0 == 4e. 修好後回復乾淨 == exit 0 ``` 5. `sh tools/wire-cli.sh smoke claude` 完整輸出: ``` status=ok reason=七支 hook 的每個接線模式都跑得完,沒有執行期錯誤 [jsc] session-timer.sh mark:exit 0,正常。 [jsc] sdlc-gate.sh check:exit 0,正常。 [jsc] version-guard.sh:exit 0,正常。 [jsc] skill-usage.sh:exit 0,正常。 [jsc] ste100-guard.sh:exit 0,正常。 [jsc] sdlc-gate.sh wp-check prompt:exit 0,正常。 [jsc] sdlc-gate.sh wp-check skill:exit 0,正常。 [jsc] comment-scope.sh prompt:exit 0,正常。 [jsc] comment-scope.sh:exit 0,正常。 [jsc] comment-scope.sh sweep:exit 0,正常。 [jsc] lang-guard.sh prompt:exit 0,正常。 [jsc] lang-guard.sh:exit 0,正常。 [jsc] lang-guard.sh sweep:exit 0,正常。 smoke exit 0 ``` 6. 結束碼保護實測。假 CLI `exit 42` 搭配必定命中的工作區(先確認 `lang-guard.sh sweep` 對該工作區回 2): ``` == 先確認工作區必定命中 == lang-guard sweep exit 2 == 6. jsc-wrap.sh 結束碼保護 == fake copilot ran, args: --hello [jsc] 工作區有簡體字、亂碼或編碼問題,請就地修正: /tmp/.../gtest/doc.md 簡體字,改成繁體 1:新增一行:这里有简体字,应该被抓到。 jsc-wrap.sh exit 42 (expect 42) ``` 7. 誤判回歸。對 `/root/plugins` 底下所有 `*.sh`、`*.md`、`*.json`、`*.txt` 逐檔整檔掃描(複製到非 git 暫存目錄以強制整檔掃,不是只掃 diff): ``` 整檔掃描:scanned=437 hits=2 HIT: /root/plugins/meta/tools/ste100-lint.sh HIT: /root/plugins/sdlc/references/cpm-chart.md jsc-hooks 原地掃描:scanned=28 hits=0 ``` 兩筆命中逐一說明:`sdlc/references/cpm-chart.md` 是已知的真實簡體字(「只會出现在這一步」),不在本存取庫;`meta/tools/ste100-lint.sh` 命中的是它自己的 `SIMPLIFIED_FALLBACK` 備援字表那一行,屬於「被討論的對象」而非被使用,與本存取庫跳過 `simplified.txt` 是同一個道理,同樣不在本存取庫。本存取庫 28 個檔案 0 命中。 補充驗證(非必做七項,一併附上):以假執行檔加暫存 `HOME` 實跑 codex 與 kiro 接線,兩份設定寫入後 `status` 全部 `present`: ``` == kiro status == item jsc-hooks-session-start ./.kiro/hooks/jsc-hooks-session-start.json present item jsc-hooks ./.kiro/hooks/jsc-hooks.json present item comment-scope ./.kiro/hooks/jsc-hooks.json present item comment-scope-sweep ./.kiro/hooks/jsc-hooks.json present item lang-guard ./.kiro/hooks/jsc-hooks.json present item lang-guard-sweep ./.kiro/hooks/jsc-hooks.json present == codex status == item notify .../config.toml present item notify-root .../config.toml present item notify-sweep .../config.toml present item notify-lang-sweep .../config.toml present item alias .../.bashrc present item ste100 .../AGENTS.md present item comment-scope .../AGENTS.md present item lang-guard .../AGENTS.md present ``` 本存取庫自我檢查:`comment-scope.sh sweep .` 與 `lang-guard.sh sweep .` 皆 exit 0。 ## 前置 Push Request - 無
jiantw83 added 4 commits 2026-08-27 01:51:17 +00:00
What:新增 `hooks/lang-guard.sh` 與機檢字表 `hooks/simplified.txt`。腳本比照 `comment-scope.sh` 的結構,一樣三種模式:`prompt` 注入規則摘要、無參數掃剛寫入的單一檔案、`sweep [dir]` 掃整個 git 工作區這次改過的檔案。偵測三項:簡體字、亂碼(U+FFFD 與雙重編碼殘骸)、非 UTF-8 編碼。命中走 stderr 並 exit 2,資料不足或找不到 git 一律安靜 exit 0,逃生門 `JSC_LANG_GUARD=off`。

Why:使用者新增的規則是「非程式碼的輸出一律套用繁中無亂碼」,範圍涵蓋程式碼註解、commit 訊息、PR 描述、wiki 頁、對使用者的回報與各種文件。這條規則原本只有 `ste100-guard.sh` 的提示層,模型看得到卻沒有人檢查,寫出簡體字或亂碼不會有任何回饋。提示層擋不住的事,就要有機檢層。

How:簡體字樣式由字表組出,字表是單一真實來源,腳本裡不留第二份;字表讀不到就安靜跳過這一項,不中斷整支腳本。亂碼一律用位元組比對(`LC_ALL=C`),不靠語系的字元範圍,因為 `grep -E` 的字元範圍在不同語系下行為不一致。掃描深度沿用 `comment-scope.sh`:檔案已追蹤就只掃 `git diff HEAD` 的新增行,不翻舊帳。二進位檔只認 NUL 位元組判定,不拿「非可列印字元」當判準,那會把所有含中文的檔案誤判成二進位。字表刻意排除繁體也在用的字(后、台、干、只、里、面、制、志),並跳過 `simplified.txt`、`ste100-guard.sh`、`lang-guard.sh` 三份以簡體字與亂碼為討論對象的檔案,避免整支 hook 每次先抓到自己。

Who:`jsc-hooks` 的 hook 實作層,供 `hooks/hooks.json` 與 `tools/wire-cli.sh` 接線給五個 CLI 使用。
What:`hooks/hooks.json` 的 `UserPromptSubmit` 加 `lang-guard.sh prompt`、`PostToolUse` 的 `Write|Edit|MultiEdit` 加無參數模式;`tools/wire-cli.sh` 把 codex 的 `notify`、kiro 的 `userPromptSubmit` 串上 sweep,規則檔文字加上 `lang-guard.sh prompt` 的輸出,`smoke` 三種模式各跑一輪,`status` 補盤點項,寫入後驗證一併涵蓋;`tools/jsc-wrap.sh` 收尾再跑一次 sweep;`hooks/ste100-guard.sh` 的注入文字補上適用範圍與 UTF-8 無亂碼。

Why:hook 寫好了不接線等於沒寫。接的位置與 `comment-scope.sh` 完全一樣,因為兩支要解的是同一個問題——只有 claude 有 post-tool hook,其餘四個 CLI 拿不到「剛剛寫了哪個檔」,只能改掃整個工作區。各 CLI 的掃描時機本來就不同:claude 逐檔即時、codex 每輪結束、kiro 每輪提示送出時、copilot 與 antigravity 只有工作階段結束,回報時不能寫成五支一樣。

How:規則檔文字取 `lang-guard.sh prompt` 的實際輸出,不在接線腳本裡抄一份規則,抄了兩邊就會各自漂移。寫入後以 `has_lang_guard()` 比對腳本第一行實際輸出,確認規則檔真的收到那一段。`smoke` 沿用既有的 exit 2 例外:掃描模式掃到違規回 2 是設計行為,不是執行期錯誤。`jsc-wrap.sh` 的 sweep 一律加 `|| true`,包裝器原樣回傳 CLI 自己的結束碼——包裝器改掉結束碼,呼叫端的 `cmd && next` 就會誤判。

Who:`jsc-hooks` 的接線層,由 `hooks-install` 技能對 claude、codex、copilot、antigravity、kiro 五個 CLI 執行。
What:`README.md` 的 hook 一覽表新增 `lang-guard.sh` 一列(事件、三種模式、逃生門),所有「六支 hook」改七支,環境變數表補 `JSC_LANG_GUARD`,`tools/jsc-wrap.sh` 那列補收尾 sweep;`skills/hooks-install/SKILL.md` 六支改七支並補覆蓋範圍與備註,`description` 的括號清單加上這支;`AGENTS.md` 清單同步,並新增一條繁中無亂碼規則。

Why:文件寫六支、實際跑七支,使用者與 sub agent 都會照文件辦事,少接的那一支永遠沒有人發現。`AGENTS.md` 是各 CLI 讀得到的規則檔,新規則不寫進去就只剩 hook 在擋,模型自己不會知道。

How:README 維持 STE100 繁中;SKILL.md 維持整份英文,`description` 保持 4 句、保留觸發時機。規則正文一律不在本存取庫留副本,只指向 `jsc-meta` 的 `references/ste100.md`,字表位置指向 `hooks/simplified.txt`。

Who:`jsc-hooks` 的文件層,讀者是使用者與執行 `hooks-install` 的 sub agent。
What:把 `plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` 三份 manifest 的版本由 0.2.0 升到 0.2.1。

Why:0.2.0 已隨前一支 PR 發佈出去,本次新增的第七支 hook 與五個 CLI 的接線沒有跟著升版,`version-guard.sh` 就看不出本機落後,使用者不會收到更新提示。

How:以 jsc-meta 的 `sync-skill-manifest.sh` 統一 bump,patch 進位,三份同步成同一個值。

Who:繁中與編碼檢查 hook 的跨 CLI 支援。
jiantw83 added 2 commits 2026-08-27 01:53:57 +00:00
What:簡體字表由 102 字擴充到 1006 字;lang-guard.sh 的跳過清單補上
jsc-meta 的 references/ste100.md 與 tools/ste100-lint.sh。

Why:102 字的舊表覆蓋率太低——拿 21 個常見簡體詞實測只抓到 4 個,「简体字」
「举办」「觉得」「战争」「医药」這類全部漏掉,規則等於形同虛設。跳過清單則是
對稱性問題:規則文件與機檢工具本身會列舉簡體字當範例,不跳過就每次先抓到自己。

How:字表逐字檢查「簡化後才出現的字形」,剔除正體也在用的字(后、台、干、只、
里、面、制、志、出、斗、丑、了、卷、咸、云、留、言、短、困、陷、游、封、吞),
再拿 jsc 全部 11 個存取庫共 221 個檔案的既有正體中文語料回歸驗證,誤報為零。
檔頭寫明排除原則與「改完必須拿語料重驗」的要求。跳過清單比照 ste100-lint.sh 的做法。

Who:非程式碼輸出的繁中無亂碼檢查。
What:三份 manifest 由 0.2.1 升到 0.2.2。

Why:字表擴充後偵測能力大幅改變,本機沒跟著升版,version-guard.sh 就判不出落後,
使用者不會收到更新提示,繼續用覆蓋率只有兩成的舊字表。

How:以 jsc-meta 的 sync-skill-manifest.sh 統一 bump,三份同步成同一個值。

Who:非程式碼輸出的繁中無亂碼檢查。
admin merged commit 9875f917bf into develop 2026-08-27 01:58:38 +00:00
admin deleted branch feat/lang-guard-traditional-chinese-encoding 2026-08-27 01:58:38 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: plugins/hooks#28