閘教的那條出路要真的走得通(inkstone/ISEP#112) #114
Reference in New Issue
Block a user
Delete Branch "fix/gate-teaches-a-command-that-runs"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
【身份】isep-hand/inkstone/ISEP/fix/gate-teaches-a-command-that-runs
修
inkstone/ISEP#112。病在哪(兩個獨立的原因,各自都足以害死那一行)
① 相對路徑。 閘印的是
scripts/ticket subtask …,而相對路徑是對貼上去那個人的 cwd解析的。總管的 cwd 是
InkStoneCo/,那裡的scripts/ticket是正本停在 2026-08-27之前的舊複本。實測(cwd=
/home/user/inkstoneco/InkStoneCo):⇒ 票上寫的「噴出四個動詞的說明然後什麼都沒發生」就是這個。
(ISEP 正本
grep -c subtask= 10;hooks/lib/beacon_report.py② 已經會在 SessionStart報這個舊複本,但報告不會改掉閘印出來的那一行。)
② 用法各寫一份,而且已經漂了。 閘那份寫
--assign <誰做>卻沒有--next。就算路徑對了,跑在正本上照樣:
修法:拿掉可以漂的那一格,不是把兩份對齊一次
scripts/ticket的self_path()=os.path.realpath(__file__)。印指令的人與跑指令的人是同一個檔案,沒有第二種可能USAGE/usage_text()一份。閘去ticket usage subtask --example現要,不自己抄body_template()由REQUIRED_SECTIONS現生。模板與檢查同源 ⇒ 不可能生出「照著貼卻過不了自己那道閘」的票新增動詞:
ticket usage <verb> [--example] [--parent <owner/repo#N>] [--draft <路徑>]。閘的訊息改成一整塊可貼可跑:腳本絕對路徑、母票已填、內文草稿附在同一塊 heredoc 裡,
只剩標題/目標/驗收條件三格是機器不可能知道的。
正本叫不動時 fail-open 的只有「訊息內容」(只指路、不補一份手抄用法),擋不擋不受影響。
順手把同一份檔案裡另外三處印給終端機的相對路徑改掉(
cmd_loose兩行、journey 提示一行)。⚠️ 貼進 Gitea 留言的那幾行刻意維持相對寫法——留言會被別台機器讀到,
寫死本機絕對路徑等於寫死一個他們沒有的檔案。分界寫在
_writeback那段註解裡。驗收條件逐條
① 照閘印出來的那行原樣貼上就能跑完,產出母子相依成立的子票 ✅
把閘 stderr 那塊原樣複製、只填三格,實跑:
② 子票沒關時母票關不掉(Gitea 原生相依,實測) ✅
③ 閘訊息與能跑的指令不再有第二種可能漂掉的關係 ✅
保證方式是結構,不是紀律:閘的訊息裡沒有任何一段用法是它自己寫的,
整塊都是
python3 "$TICKET" usage subtask --example的 stdout。而
$TICKET=${CLAUDE_PLUGIN_ROOT}/scripts/ticket,它印的路徑是自己的__file__。驗這件事的是
scripts/test-comment-carries-task-guard.sh新增的 ⑮–㉑(22 → 29 條):⑱ 是核心:它把閘 stderr 裡那塊指令原樣抽出來、只填三格、真的執行一次,
離開碼必須是 1(
TICKET_HOST指到連不上的位址,走到網路才停)。是 2 就代表又被某道閘擋下 = 這個病復發。全程離線,不開任何測試票。
變異測試(證明這幾條真的有鑑別力)
--assign(沒--next)body_template寫死、少一段(第一輪還抓到我自己寫的 ⑮ 是空過的——用相對路徑的變異沒讓它紅,
因為它比對的是「訊息裡出現過的所有路徑」,別的行還有絕對路徑,
all()照樣真。已改成只看「要執行的那一行」,再跑一次變異才紅。)
其他驗過的
scripts/test-ticket-handoff-writeback.sh49/49、test-ticket-where-seen-guard.sh17/17、test-baton-handback-guard.sh10/10、hooks/tests/diagnosis-evidence-guard.test.sh26/26、reply-identity.test.sh11/11、isep-presence-beacon.test.sh14/14 全綠claude plugin validate .→√ Validation passedscripts/check-version-consistency.sh→✅ 版本一致——這次沒有增減,README 與
plugin.json不用動⚠️ 沒驗的 / 要總管處理的
plugin.json仍是0.17.0。plugin update比的是版本號不是內容 ⇒ 不升版這個修正到不了任何人手上。CLAUDE_PLUGIN_ROOT指到 worktree 跑過,fallback(指到不存在的 root)也跑過。
main跑過對照):test-ticket-api-bypass-guard.sh23/24、dispatch-format-guard.test.sh40/52、gitea-arm-check.test.sh、main-and-prod-push-guard.test.sh、main-and-prod-push-guard-cross-repo.test.sh、prod-write-guard.test.sh18/19 紅、stage-before-prod-guard.test.sh9/7。baton-handback-guard.sh、dispatch-format-guard.sh、factory-idle-guard.sh)——同一個病、不在這張票的範圍內,已長成子票inkstone/ISEP#113。ticket subtask貼回母票的那則留言預設簽【身份】總管/…(
_identity()),有名字的工人跑它時要自己帶ISEP_IDENTITY才會簽對名字。這次我帶了。要不要讓它自動抓工人名字,是另一件事。
comment-carries-task-guard 擋下留言時教人跑 `scripts/ticket subtask …`, 而那一行跑不動。兩個獨立的原因,各自都足以害死它: ① 相對路徑對「貼上去那個人的 cwd」解析。總管的 cwd 是 InkStoneCo/, 那裡的 scripts/ticket 是停在 08-27 之前的舊複本(grep -c subtask → 0), 照著貼只印出它「四個動詞」的說明然後 exit 0。 ② 用法是手抄的第二份,而它已經漂了:寫了 --assign 卻沒有 --next, 正本會因為「指派了人卻沒寫 --next」直接擋下(exit 2,在打 API 之前)。 修法是拿掉可以漂的那一格,不是把兩份對齊一次: - 路徑 scripts/ticket 的 self_path()(__file__ 的絕對路徑) ⇒ 印指令的人與跑指令的人是同一個檔案 - 用法 USAGE / usage_text() 一份,閘去 `ticket usage subtask --example` 現要 - 內文模板 body_template() 由 REQUIRED_SECTIONS 現生,跟檢查同源 新增動詞 `ticket usage <verb> [--example] [--parent] [--draft]`。 閘的訊息改成整塊可貼可跑:腳本絕對路徑、母票已填、內文草稿附在同一塊裡, 只剩標題/目標/驗收條件三格是機器不可能知道的。 正本叫不動時 fail-open 的只有「訊息內容」(只指路,不補一份手抄用法), 擋不擋不受影響。 測試 scripts/test-comment-carries-task-guard.sh 22 → 29 條。 新增的 ⑮–㉑ 驗的是「出路走不走得通」,不是「有沒有擋」—— ⑱ 把閘 stderr 裡那塊指令原樣抽出來、只填三格、真的執行一次, 離開碼必須是 1(走到網路才停);是 2 就代表這個病復發。 六個變異全部驗過會紅(相對路徑/閘自己抄用法/--assign 沒配 --next/ 模板寫死少一段/fallback 補回手抄用法)。 版本:待總管定版(plugin update 比的是版本號不是內容)。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP7DiGMfSkWjZ15CHMbPFE