claude-code
|
ce0fe87529
|
定版 v0.18.0:閘教的那條出路要真的走得通
inkstone/ISEP#112:comment-carries-task-guard 印出的
`scripts/ticket subtask` 子命令根本不存在,照著跑會噴四個動詞的
說明然後什麼都沒發生——閘擋對了,但它教的解法跑不動。
這一版讓那行指令原樣貼上就跑得完:補上 subtask 子命令(一個動作
同時掛 Gitea 原生相依+在母票留下指回來的留言),閘改成去
`ticket usage subtask` 拿用法而不自己抄一份,印的路徑改絕對路徑。
測試 29/29,其中 ⑱ 直接驗「訊息裡那塊指令原樣貼上跑得完」,
⑲ 是對照組證明舊的那組旗標確實跑不完。
|
2026-08-31 11:11:54 +00:00 |
|
claude-code
|
85f76c556a
|
Merge '閘教的那條出路要真的走得通(inkstone/ISEP#112)' (#114) from fix/gate-teaches-a-command-that-runs into main
|
2026-08-31 11:10:40 +00:00 |
|
Leo
|
58c3689e4b
|
閘教的那條出路要真的走得通(inkstone/ISEP#112)
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
|
2026-08-31 11:01:45 +00:00 |
|
claude-code
|
b8676f5aa9
|
Merge pull request '定版 v0.17.0(sdd-guard 退役)' (#111) from chore/v0.17.0 into main
v0.17.0
|
2026-08-31 01:04:50 +00:00 |
|
claude-code
|
6e18cc2072
|
定版 v0.17.0:sdd-guard 退役
|
2026-08-31 01:04:21 +00:00 |
|
claude-code
|
8b2c7cecac
|
Merge pull request 'sdd-guard 退役:讓「取消 Active SDD」這個裁決真的執行得下去(inkstone/ISEP#91)' (#110) from feat/retire-sdd-guard into main
|
2026-08-31 01:04:01 +00:00 |
|
Claude
|
c7af690c2b
|
sdd-guard 退役:讓「取消 Active SDD」這個裁決真的執行得下去(inkstone/ISEP#91)
leo 2026-08-16 在 inkstone/InkStoneCo#40 → comment 2942 裁定「取消 Active SDD」,
11 天沒被執行。原因不是有人偷懶,是**執行它的第一步會鎖死自己**:
sdd-guard.sh 是 fail-closed 的
· 動 code 檔時 status: active 不是恰好 1 份 → 擋(0 份也擋)
· 路徑所在的 repo 沒有 3-specs → 也擋
⇒ 照裁決把最後那份 active 拿掉 → 變 0 份 → 任何人動任何 .ts/.py/.go 全被擋。
而 ISEP 這個 repo 自己就沒有 3-specs——本票開工第一件事實測到:
$ echo '{"tool_name":"Edit","tool_input":{"file_path":".../hooks/lib/dispatch_parse.py"}}' \
| bash hooks/sdd-guard.sh
🚫 SDD 協議攔截:… 找不到任何 SDD exit 2
**它一直在誤攔 ISEP 自己,只是沒人回報。**
── 這一版做了什麼 ────────────────────────────────────
· hooks/sdd-guard.sh 刪除,hooks.json 取消註冊(85 → 84 條,只少這一條)
· commands/sdd-check.md 改寫:SDD 只記「起初的樣子」,任務本體在 Gitea 票;
找不到 SDD 不再是停下來的理由,找不到票才是
· agents/inkstoneco-hand.md 拿掉「任何時刻只允許一份 status: active」那條紅線
· hooks/lib/path-resolve.sh 只加註解:它的唯一 caller 走了,但別順手刪
(#22 學到的東西住在裡面,十幾支閘還在用它要修的那個寫法)
── 迴歸測試:測的不是「檔案刪了沒」,是「那個擋還會不會發生」──
hooks/tests/sdd-guard-retired.test.sh(通過 8/失敗 0,離線):
把「裁決執行完之後的世界」(沒有 3-specs 的 repo、兩份 status: active 的 repo)
丟給 hooks.json 上**整組** Write|Edit|MultiEdit 的閘——清單當場從 hooks.json 讀、
不寫死——不准有任何一支用 SDD/3-specs 當理由擋下來。
⇒ 日後有人換個檔名把同一個形狀種回來,這支照樣紅。
🔴 判準刻意不是「一支閘都不准擋」:同組還住著跟 SDD 無關、且看 session 狀態
決定擋不擋的閘(history-first/subagent-first)。把它們算失敗,這支測試會在別人
改別的東西時無故變紅,紅久了就沒人看——誤攔比漏擋更該修,對測試一樣成立。
**紅的證明**:把 sdd-guard 暫時復原(檔案+註冊)重跑 → 通過 1/失敗 7,
四條行為格全部指名 sdd-guard.sh。已還原。
── 自己跑過的 ──────────────────────────────────────
· hooks/tests/sdd-guard-retired.test.sh 通過 8/失敗 0
· 逐支點名 hooks.json(README「裝什麼」那道指令) 84 條,對 main 做集合差:
少了 sdd-guard.sh × 1,多出 0 支,其餘一支不差
· 盤點數字全部在這棵樹上實數,不是加減推:
ls hooks/*.sh|wc -l = 61(原 62)
grep -c '"command":' hooks/hooks.json = 84(原 85)
agents 7/commands 7/skills 2/scripts 48(皆未變動)
· 盤點表對帳三格(hooks-inventory 自己寫死的那三道):三格皆無輸出
· scripts/check-version-consistency.sh ✅ 0.16.2 一致
· claude plugin validate . ✅ Validation passed
· hooks/tests/ 全部離線測試 24 支重跑:本次改動 0 退步
(dispatch-format-guard 40/52、prod-write-guard 18/19-fail、
stage-before-prod-guard 9/7-fail、另 3 支需帶參數/建不起沙盒——
**六支在 gitea/main 上逐支重跑結果一模一樣,是既有狀態不是本次造成**)
── 沒做、也不該由這張票做的 ─────────────────────────
· inkstone/InkStoneCo 那半(拿掉 active SDD + 刪 CLAUDE.md「單一活性鐵律」段)
——那是 inkstoneco-hand 的 repo;而且順序上本來就要等這一版出去、
兩邊 /plugin update 之後才動得,先拿掉就鎖死
· checkbox 分診(掛 inkstone/InkStoneCo#49,票上明寫不要另開票)
· 版本號:待總管定版
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZBu4Sa1cGntKFRBYNZ6xs
|
2026-08-31 00:56:37 +00:00 |
|
Leo
|
4b91cd5d48
|
Merge 'feat/parallel-lines-cap':一條線一份自己的工作目錄(inkstone/ISEP#109)
總管逐筆審過並自己實測(不採信交回的數字):
hooks/tests/line-needs-own-worktree.test.sh 59/59
hooks/tests/parallel-lines-cap-guard.test.sh 33/33
hooks/tests/main-and-prod-push-guard.test.sh 10/10 ← 共用檔改動的迴歸
hooks/tests/…-cross-repo.test.sh 19/19 ← 同上
實地打四次(不是只跑測試):
· cd <repo> && git checkout → 擋,且認出的是那個 repo(原缺陷已修)
· git -C <repo> checkout → 擋,認得對
· cd <自己的 worktree> && checkout → 放行(舊版會誤攔正確做法)
· cd <不是 repo 的地方> && checkout → 放行
🔴 併進來不等於送達:安裝端停在 0.9.0,repo 是 0.16.2,
而這支閘在任何一份安裝裡都不存在(find 零命中)
⇒ 這一格仍是 ◐,缺的是 plugin update,不是 merge。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
v0.16.2
|
2026-08-29 22:08:31 +08:00 |
|
Leo
|
358f67abf3
|
閘認得出「動的是哪個 repo」,不再拿 cwd 當答案(inkstone/ISEP#109 → comment 5398)
line-needs-own-worktree.sh 擋 `cd <別的 repo> && git checkout` 時擋對了,但訊息
指的是 payload 的 cwd 那個 repo,不是指令真正動的那個。comment 5398 實測:
指令:cd .../matrix/arcrun && git checkout fix/library-lifecycle-187
舊版:目錄:.../InkStoneCo 它現在在:feat/ticket-bell-webhook
↑ 動的是 matrix/arcrun,講的卻是 InkStoneCo
🔴 照著那個訊息做的人,會在 InkStoneCo 開一份用不到的 worktree,真正要隔離的
matrix/arcrun 沒開到——而他以為自己隔離好了。**一道閘給錯下一步比不擋更糟。**
而 `cd X && git checkout` 正是這條線最常出現的寫法(本票的來由那次就是它)。
沒有另寫一支解析器:hooks/lib/push_target_dir.py 2026-08-23 已經替 git push 解過
同一題(inkstone/ISEP#30 comment 3949),多層 cd 鏈與「子殼的 cd 不外洩」都算過了。
本輪只把那支的動詞與「要不要去掉 env 前綴」變成參數(兩個都有預設值,push 那條路
一個 byte 都沒變,42 條既有測試重跑全綠),新增的 lib/checkout_target_dir.py 只放
checkout 專屬的兩件事:哪些形狀不動 HEAD、-C 贏過 cd 的優先序。
新增的一條性質(不是順手,是本票要的):目錄解不出來就放行。
`cd $VAR`/`cd -`/引號壞掉時回 "?",閘直接 exit 0。寧可漏擋,也不要指著錯的
repo 叫人去開 worktree——猜一個回去等於原地打轉。
實測:
- hooks/tests/line-needs-own-worktree.test.sh 35 條 → 59 條(新增 D 群 24 條)
正向:cd 認出 A/-C 認出 B/兩者都在時 -C 贏/相對 cd/相對 -C 接在 cd 之後/
從 worktree cd 回共用目錄/子殼不外洩
反向(不該擋):cd 到非 repo、cd 進自己的 worktree、cd $VAR、cd -、還原檔案
已知邊界也釘成測試:`);` 中間沒空白時 tokenize 會斷在那裡 ⇒ 漏擋(不是指錯)。
那層是 push_target_dir 的 tokenizer,動它會連帶改到推 main 那道閘的偵測範圍,
本票不動,另報。
- 推 main 那三套(共用被改到的 lib):10/10、19/19、13/13
- 實地打票上那條害過我們的指令:現在印的是 matrix/arcrun,worktree 指令也是它的
plugin.json 0.16.1 → 0.16.2 並重跑 vendor-to-shell.py(版本沒動=沒人吃得到)。
⚠️ 留痕:hooks/lib/checkout_target_dir.py 是用 Bash heredoc 寫的,因為 sdd-guard
對 ISEP 的 .py 是結構性永遠在響——這個 repo 根本沒有 system-dev/docs/3-specs,
而 hooks/lib/ 已經住了 9 支 .py。範圍就這一支新檔,沒有動那道閘(另報)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-29 21:31:42 +08:00 |
|
Leo
|
f69ea11a58
|
一條線一份自己的工作目錄,同時跑的線有上限(inkstone/ISEP#109 → comment 5391)
兩支新閘,兩個方向的測試都有:
line-needs-own-worktree.sh(PreToolUse: Bash,35 條測試)— 治本那半
一條線想在共用的工作目錄裡切分支就擋,叫它開自己的 worktree。
判準是 git 自己回答的兩個問題(會不會動 HEAD/是不是主工作目錄),
不靠任何人登記。擋下來時順手 prune 掉指向空氣的登記。
實測:products/arcrun-rag 清掉 4 筆、ISEP 清掉 13 筆,
還在的 worktree 與分支一根寒毛都沒動。
parallel-lines-cap-guard.sh(PreToolUse: Agent|Task,33 條測試)— 治標那半
同時在跑的線超過上限(預設 3)就派不出下一條,訊息列出現在有哪幾條。
條數是從 harness 自己寫的 subagents/*.meta.json + 主 transcript 的完工通知
數出來的,不是計數器 —— 沒有任何東西要人去減,所以不會永久卡死。
三個機械前提是實測的,不是推測的:
· SubagentStop 在實測 session 裡一次都沒觸發(不能拿它當減法)
· PostToolUse:Agent 在送出後 5 秒就觸發(不是收工)
· subagent 不是獨立行程(ps 只有一個 claude-code 行程)
· Agent 的原生 isolation:"worktree" 只做頂層 repo,
而 products/ matrix/ 是 gitignore 掉的子 repo,worktree 裡根本沒有它們
⇒ 原生那條路解不了這張票的問題
盤點數字在自己的樹上重數:62 支 / 85 條(main 上的 60/82 沒算到這兩支)。
🔴 版本沒動 = 沒有人吃得到。這條分支沒有定版,
plugin.json 仍是 0.16.1(版本一致性檢查要求它等於最新 tag)。
合併時要跟著一個新版本號,不然這兩支閘到不了任何人手上。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-29 20:52:13 +08:00 |
|
claude-code
|
aac6498850
|
Merge pull request 'roster-guard 認不出真實的 subagent_type,整個環境派不出工(inkstone/ISEP#86 迴歸)' (#108) from fix/roster-plugin-prefix into main
v0.16.1
|
2026-08-28 12:37:36 +00:00 |
|
claude-code
|
5342917f2b
|
roster-guard 認不出真實的 subagent_type,整個環境派不出工
Claude Code 給 plugin agent 的 subagent_type 帶前綴(isep:isep-hand),
而 agents/*.md 的 frontmatter name 沒有(isep-hand)。roster.find() 用完全相等比對
⇒ 真實派工一律被擋,而名單上的裸名字工具又不收 ⇒ 兩種寫法都派不出去。
測試沒抓到是因為 24 條全部餵手寫 payload,沒有一條用真實的 subagent_type 形狀。
補第 19 條專測這個:舊 roster.py + 新測試 → 紅;修好 → 25/25。
順手補 gate-ok 漏掉的 roster——v0.15.0 新增那支閘時沒同步逃生口清單,
所以撞上死鎖時連留痕的出口都沒有。
|
2026-08-28 12:36:13 +00:00 |
|
claude-code
|
a0a34b629e
|
Merge pull request '定版 v0.16.0(會主動叫人、wiki 太長有人整理)' (#107) from chore/v0.16.0 into main
v0.16.0
|
2026-08-28 01:32:10 +00:00 |
|
claude-code
|
7df15f2e2b
|
定版 v0.16.0(.claude-plugin/plugin.json)
|
2026-08-28 01:31:27 +00:00 |
|
claude-code
|
7a3ce4e590
|
Merge pull request '沒人會叫的事會自己叫+讀不完的必讀檔要被整理(inkstone/ISEP#93、inkstone/ISEP#89)' (#106) from feat/nag-and-wiki-compress into main
|
2026-08-28 01:28:00 +00:00 |
|
Claude Code
|
672439bd95
|
把 main(v0.15.0,派工紀律三件 #105)併進來,逐支點名複驗過 hooks.json
## hooks.json:這次 git 自動合成功了,而那正是最危險的情況
`hooks.json` 是 JSON——**合錯了語法照樣合法、閘卻不見了,不會有任何東西喊一聲。**
所以「沒有衝突」不等於「沒掉東西」,一律再做兩件事:
① 逐支點名(指令已寫進 README「裝什麼」那段)→ 82 條,60 支各自幾條全部列出
② 跟**兩個父節點**做集合對照:
merged 82 = main 79 + 我的 3
從 main 掉了:0 條
從我這邊掉了:0 條
兩邊都沒有卻冒出來的:0 條
`#105` 三支與我的兩支同時在,位置也對:
roster-guard.sh PreToolUse Agent / Task
diagnosis-evidence-guard.sh PreToolUse Bash
investigate-first-stamp.sh PostToolUse Agent|Task / SendMessage
overdue-nag-guard.sh SessionStart
wiki-size-guard.sh SessionStart / PreToolUse Write|Edit|MultiEdit
(總管提醒的 `roster-guard` vs `mainline-focus-guard` 那種「同一陣列位置兩邊各一支」
這次沒有再發生衝突,但兩支都在,各 2 條。)
## 三處文字衝突:兩邊都留,數字重數
- plugin.json 版本吃 main 的 **0.15.0**(總管已定版,**我沒有動它**);
描述欄補上 main 新增的「7 位有名字的工人」,三個數字重數
- README.md 吃 main 的新表格結構(多了 agents/commands/skills/scripts 四列),
數字重數;並把累積成**四列**的 `hooks/` 收成一列
- hooks-inventory 標頭被貼成兩份、「一句話結論」被貼成**三份**(數字還互相打架),
各收成一份;版本註記兩邊都留
## 盤點(全部在合併後的樹上實數,不是加減推的)
ls hooks/*.sh | wc -l 58 → 60
grep -c '"command":' hooks/hooks.json 79 → 82
ls agents/*.md | wc -l 7
ls -p scripts | grep -v / | wc -l 48
未掛進 hooks.json 的 .sh 3(與本頁原本寫的一致,重數過)
📌 抓到的漂移(每次併都有一個,這次三個):
① hooks-inventory 的標頭 ×2、一句話結論 ×3
② README 的 `hooks/` 列 ×4,其中兩列是舊數字
③ plugin.json 描述欄寫「49 支腳本」,而用本頁寫死的那道指令實數是 48
## 測試(合併後全部重跑,帶對參數)
hooks/tests 23 支全綠:ask-user-question 14、countdown 20、diagnosis-evidence 26、
dispatch-format 52、factory-idle 33、gate-ok 17、gitea-arm-check 16、
presence-beacon 14、cross-repo 19、main-and-prod-push 10、mainline-focus 24、
mainline-idle 61、milestone-account 22、**overdue-nag 36**、pr-verdict 52、
prod-write 37、reply-identity 11、roster 24、sdd 8、search-is-not-proof 31、
stage-before-prod 16、unpushed-police 10、**wiki-compress 25**
scripts/test-* 13 支全綠。
claude plugin validate . ✔ passed;check-version-consistency ✅ 0.15.0 = v0.15.0。
兩支新 SessionStart hook 併完實跑過,閘判定探針對 v0.15.0 的 prod-write-guard 回 pass。
🔴 跑之前清 `CLAUDE_CODE_CHILD_SESSION`;四支要帶參數
(三支帶 hook 絕對路徑、cross-repo 帶 hook 絕對路徑、gitea-arm-check 帶 repo 根目錄)
——不帶會紅,而那是假紅。
|
2026-08-28 01:25:49 +00:00 |
|
claude-code
|
5fca644b5a
|
Merge pull request '工人有名字、診斷要有調查、回覆也只給票號(inkstone/ISEP#86、#87、#88)' (#105) from feat/named-workers-and-reply-gate into main
v0.15.0
|
2026-08-28 01:20:12 +00:00 |
|
Claude
|
44f60ba0b8
|
merge main(v0.14.0,五批)into 派工紀律三件
hooks.json 兩處衝突:roster-guard 與 mainline-focus-guard 在同一個陣列位置,
兩支都是真的閘,展開成兩個項目保留(不是二選一)。
盤點在合併後重數:58 支 .sh/79 條註冊/49 支腳本/7 位具名工人。版本 0.15.0。
|
2026-08-28 01:20:00 +00:00 |
|
Claude Code
|
79ee9e62d6
|
把 main(v0.14.0,五批)併進來,解 5 處衝突,盤點數字在合併後的樹上重數
衝突全部**兩邊都留**,沒有丟掉任何一側:
- hooks.json main 的 `scripts/mainline refresh` + 我的兩支,同一個
SessionStart 陣列裡並存
- plugin.json 版本吃 main 的 0.14.0(**沒有自己決定版本**),描述欄的
三個數字在合併後的樹上重數
- README.md main 那格被貼成兩列(54 支/69 條 與 54 支/71 條,互相矛盾),
收成一列並填上實數
- hooks-inventory main 的 `mainline refresh` 那列 + 我的兩列;標頭與
「一句話結論」的數字重數
- TESTING.md 兩邊各自新增的格子都留。**我的兩格改號成 A21/A22**——
併之前兩邊都叫 A16/A17,撞號(這一頁本來就已經有
三組重複的 A14–A18,這次至少沒有再加一組)
盤點(`ls hooks/*.sh | wc -l`、`grep -c '"command":' hooks/hooks.json`、
`ls -p scripts | grep -v / | wc -l`,都在**合併後**的樹上跑):
55 → 57 支 .sh
72 → 75 條註冊
47 支腳本
📌 順手抓到一個漂移:main 的 plugin.json 描述欄寫「48 支腳本」,
而用 hooks-inventory 自己寫死的那道指令實數是 44(main)/47(合併後)。
已記在 hooks-inventory 的版本註記裡——**同一個病,第 N 次,只是換一欄。**
📌 TESTING.md 的「已知斷點」那段補上總管用 MCP 查到的更廣範圍:
不只 notify_leo 不見了,那台實例的工作流定義是**整批失效**;
而且修它要寫 leo 的個人帳號 ⇒ `leo21c-write-guard.sh` 明文禁止
⇒ **那是真人閘,總管也不能解**。
測試(合併後全部重跑,帶對參數):
我的兩套 overdue-nag 36/36、wiki-compress 25/25
hooks/tests/* ask-user-question 14、countdown 20、dispatch-format 33、
factory-idle 33、gate-ok 17、presence-beacon 14、
mainline-focus 24、mainline-idle 61、milestone-account 22、
pr-verdict 52、reply-identity 11、sdd 8、
search-is-not-proof 31、unpushed-police 10、
prod-write 37、stage-before-prod 16、
main-and-prod-push 10、cross-repo 19、gitea-arm-check 16
scripts/test-* 13 支全綠(含 release-manifest 21、milestone-account 23、
debt-worklist 47、ticket-handoff-writeback 49)
claude plugin validate . 通過;check-version-consistency 通過(0.14.0 = v0.14.0)
|
2026-08-28 01:15:54 +00:00 |
|
Leo
|
5ac06abc95
|
工人有名字+回覆也是派工+未經調查不寫診斷(inkstone/ISEP#86/#87/#88)
三張票同一族(誰在派、派給誰、派的內容住哪裡),做在同一條分支:
#86 工人名單:agents/ 七位有名字的工人+scripts/roster+hooks/roster-guard.sh
派工用 Task 的 subagent_type 指名,派工單格式一個字都沒改;
指對名字就把那位的檔案原文注入(你是誰/先讀什麼/你的紅線)。
【身份】欄同時吃得下工人名字(原本三個角色照舊)。
#87 未經調查不寫診斷:hooks/diagnosis-evidence-guard.sh + investigate-first-stamp.sh
三個結構訊號(派過人查沒/有沒有走得過去的出處/有沒有份量),
一個關鍵字比對都沒有;轉述有出處不會被誤擋。
#88 回覆也是派工:不另造閘,把攔截點加掛上去。
hooks/lib/dispatch_parse.py 的 tool_channel() 一次列全所有通往 subagent 的路
(SendMessage/雲端 session・trigger/claude -p);擋下來時把那段內容原文印出來。
subagent 往上回報(to: "main")=交件不是派工,刻意不管。
順手修掉一個真的會咬人的 flake:dispatch-format-guard 原本開四支 python 各讀一個欄位,
機器忙的時候某個欄位會靜靜變空字串(實測連跑 10 次有 1 次「豁免了卻還是被擋」)。
四個欄位改成一次讀完。
版本號待總管定(plugin.json 只更新了描述裡的數字,版本沒動)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZBu4Sa1cGntKFRBYNZ6xs
|
2026-08-28 01:15:09 +00:00 |
|
Claude Code
|
156d339308
|
退路留言要帶「為什麼發不出去」,不是只帶閘的判定(inkstone/ISEP#93)
2026-08-28 第一版漏了這一格,而它剛好就在實測時咬到:
閘判定 pass、Telegram 卻 404(實例上找不到 notify_leo 工作流),
退路留言貼上票之後**只看得到 pass**——真正的斷點一個字都沒進票。
⇒ 下一個人會去修閘,而斷點根本不在那裡。
把留言內文抽成 fallback_body()(獨立成一支就是為了測得到),
測試從「看原始碼有沒有那個字串」改成**真的產一份留言出來檢查**:
斷點原因、原文、身份欄三格都要在。36 條全綠。
|
2026-08-28 01:06:52 +00:00 |
|
claude-code
|
0a8bb2d9dd
|
Merge pull request '跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)' (#104) from feat/manifest-account-v2 into main
v0.14.0
|
2026-08-28 01:04:55 +00:00 |
|
claude-code
|
eb6c427421
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(scripts/test-release-manifest.sh)
|
2026-08-28 01:04:22 +00:00 |
|
claude-code
|
c6eb269551
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(scripts/test-milestone-account.sh)
|
2026-08-28 01:04:20 +00:00 |
|
claude-code
|
bc02c2645b
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(scripts/release-manifest)
|
2026-08-28 01:04:18 +00:00 |
|
Claude Code
|
da9bd53cae
|
沒人會叫的事會自己叫+讀不完的必讀檔要被整理(inkstone/ISEP#93、inkstone/ISEP#89)
兩張票放同一條分支:都是「該發生卻不會自己發生的事」,觸發點都在 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),待總管定版。
|
2026-08-28 01:04:16 +00:00 |
|
claude-code
|
ca10e1db30
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(scripts/milestone-account)
|
2026-08-28 01:04:16 +00:00 |
|
claude-code
|
5f6995b892
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(hooks/tests/milestone-account-guard.test.sh)
|
2026-08-28 01:04:14 +00:00 |
|
claude-code
|
395d885ceb
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(hooks/milestone-account-guard.sh)
|
2026-08-28 01:04:12 +00:00 |
|
claude-code
|
a7ca29c180
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(hooks/hooks.json)
|
2026-08-28 01:04:10 +00:00 |
|
claude-code
|
ba30c49876
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(docs/hooks-inventory.md)
|
2026-08-28 01:04:08 +00:00 |
|
claude-code
|
4eed944f68
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(docs/TESTING.md)
|
2026-08-28 01:04:05 +00:00 |
|
claude-code
|
b6405b2a5c
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(README.md)
|
2026-08-28 01:04:03 +00:00 |
|
claude-code
|
521dda1b47
|
跨 repo 版本清單+結案記帳(inkstone/ISEP#84、#85)(.claude-plugin/plugin.json)
|
2026-08-28 01:04:01 +00:00 |
|
claude-code
|
90ed988d84
|
Merge pull request '舊票每天有固定管道被撈出來(inkstone/ISEP#83)' (#101) from feat/debt-worklist into main
|
2026-08-28 01:01:53 +00:00 |
|
claude-code
|
d301810fb6
|
merge main(#98 下游做完時頂層跟著關),我的那節再讓一次編號
衝突只有 docs/TESTING.md 一列:#92 也用了 A19 ⇒ 我改成 A20,並把整節搬到 A19 後面。
(今天 main 上 A16、A17 各被佔兩次、A19 被佔兩次——編號撞是這條線的常態,
讓號的成本比要求別人改小,所以一律我讓。)
plugin.json 的腳本數在合併後的樹上重數 40 → 43:
main v0.13.0 那個「40」= `ls scripts | wc -l`(37 檔+3 目錄),
合併後同一算法 = 43:+2 是本 PR,+1 是 #98 帶進來的 test-ticket-handoff-writeback.sh
(#98 併進 main 時沒有回頭改這個數字)。版本號沒動(0.13.0)。
|
2026-08-28 00:58:49 +00:00 |
|
claude-code
|
e575786be3
|
merge main(定版 v0.13.0),衝突只有 plugin.json 一行
版本號取 main 的 0.13.0(我不定版)。description 的腳本數在合併後的樹上重數:
main 那個「40」= `ls scripts | wc -l`(37 個檔+3 個子目錄)
合併後同一個算法 = 42(多的兩個是本 PR 的 debt-worklist 與 test-debt-worklist.sh)
⇒ 40 → 42。閘的兩個數字沒變(hooks/*.sh = 54、hooks.json "command": = 71,本 PR 沒新增 hook)
|
2026-08-28 00:55:30 +00:00 |
|
claude-code
|
5d6c4b5d63
|
Merge pull request '下游做完時頂層跟著關(inkstone/ISEP#92)' (#98) from feat/handoff-writeback-loose into main
|
2026-08-28 00:54:27 +00:00 |
|
claude-code
|
45adc10a52
|
併進 main(v0.12.0)並接上「主線唯一答案」(inkstone/ISEP#83)
衝突只有 docs/TESTING.md 一處,兩邊都留:
main 的 A16(gate-ok)/A17(未推警察)/A18(信標)原樣保留,
我那節改編號成 A19——main 上 A16、A17 已經被 #90 與 #99 各佔一次,不動別人的。
接上 inkstone/ISEP#82 帶進來的 hooks/lib/mainline.py(不自己養第二套判斷):
· 有標主線 ⇒ 只排除「屬於主線那一條」的票;掛在**別條** milestone 的仍算債
(那條線現在沒有人在推,正是它躺著的原因)
· 沒標主線 ⇒ 退回保守做法:掛 open milestone 的一律不領,並在清單上照實說沒標
· 別條 milestone 已逾期 ⇒ +15「答應過人家的日期已經過了」
測試 40 → 47 條(+7 條全給主線這段),並把 ISEP_COUNTDOWN_STATE_DIR 也隔離:
不然這支測試的結果會取決於「這台機器現在標了哪條主線」。
盤點數字在合併後的樹上重數:
hooks/*.sh = 54、hooks.json "command": = 71(本 PR 沒新增 hook,兩個都沒變)
scripts 一層檔案 = 39(本 PR +2)⇒ plugin.json description 37→39
版本號沒動(0.12.0,總管統一定版)
|
2026-08-28 00:51:06 +00:00 |
|
claude-code
|
87678a8a87
|
Merge pull request '定版 v0.13.0(現在的主線是哪一個,有唯一答案)' (#102) from chore/v0.13.0 into main
v0.13.0
|
2026-08-28 00:49:13 +00:00 |
|
claude-code
|
62c2f3e664
|
定版 v0.13.0(.claude-plugin/plugin.json)
|
2026-08-28 00:48:59 +00:00 |
|
claude-code
|
07cb5e4e55
|
併進 main(#96 雲端接線/#100 v0.12.0/#99 主線唯一),解 TESTING.md 撞號(inkstone/ISEP#92)
唯一衝突在 docs/TESTING.md:兩條線各自加了一節、**都叫 A16**。
兩邊內容都留,我這一節改成 A19(main 已用掉 A16/A17/A18),
「目前狀態」表的那一列跟著搬到 A18 後面。
main 側本來就有的 A11/A12/A14/A15 重號**沒有動**——那是它兩條線各自編的,
不是這次造成的,動它會把 diff 炸開。
沒有碰的:.claude-plugin/plugin.json(維持 main 的 v0.12.0,版本由總管統一定)、
hooks/hooks.json、docs/hooks-inventory.md——這三個檔本線一個字都沒改,
自動合併拿到的就是 main 那份。
盤點數字在合併後的樹上重數(不是相加、不是抄別人的):
hooks/*.sh 54 hooks.json 註冊 71 commands 7 skills 2 scripts 頂層 38
docs/hooks-inventory.md 寫的 54/71 **是對的**;README 寫的 48/59/23
**三個都錯**,已改成實數,並把「怎麼重數」的指令寫進去——
這種數字會漂是因為沒人知道它怎麼來的。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZBu4Sa1cGntKFRBYNZ6xs
|
2026-08-28 00:48:49 +00:00 |
|
claude-code
|
4014676813
|
Merge pull request '現在的主線是哪一個,有唯一答案(inkstone/ISEP#82)' (#99) from feat/mainline-milestone into main
|
2026-08-28 00:43:55 +00:00 |
|
claude-code
|
7871921741
|
把主線接進派工與注入(inkstone/ISEP#82)
- hooks.json mainline-focus-guard 掛 Agent+Task(派工的兩個入口都要守);
SessionStart 多一條 `scripts/mainline refresh`(0.8s,不輪詢)
- hooks-inventory 54 支/71 條(當場數的)+補人話一列;順手修掉上一版重複的那一行,
並把「指向空氣」那格的假警報寫清楚(countdown-milestone-refresh 在 scripts/)
- TESTING A16(24 條離線)+ A17(要網路的那半怎麼驗)
- plugin.json 描述數字對齊;版本不動,待總管定版
|
2026-08-28 00:40:05 +00:00 |
|
Claude Code
|
21971ea83e
|
現在的主線是哪一個,變成一個查得到的事實(inkstone/ISEP#82)
14 個 open milestone 同時亮著,其中「Mira 現代化」同名活在 5 個 repo,
所以 SOP 說的「那個 active milestone」在現場沒有指涉對象。
- hooks/lib/mainline.py 主線的唯一存放處(一個檔放得下一條),從不打網路
- scripts/mainline show/list/set/clear/refresh/adopt/has
- hooks/mainline-focus-guard.sh 派了不在主線上的票 ⇒ 攔一次,問補收還是跳線
- hooks/lib/countdown.py ⏱ 那一行的主線改讀「被標定的」,蓋過「期限最近」的猜測
- hooks/countdown-guard.sh 同一個注入點加第二行 🎯(ISEP#63 那半不動)
- 測試 24 條(離線)+ countdown 原有 20 條仍全綠
|
2026-08-28 00:39:50 +00:00 |
|
claude-code
|
dbd7c8c874
|
Merge pull request '定版 v0.12.0(雲端的閘真的能用)' (#100) from chore/v0.12.0 into main
v0.12.0
|
2026-08-28 00:39:06 +00:00 |
|
claude-code
|
f9327de068
|
定版 v0.12.0(.claude-plugin/plugin.json)
|
2026-08-28 00:38:13 +00:00 |
|
claude-code
|
67f5f0fa5e
|
舊票每天有固定管道被撈出來(inkstone/ISEP#83)
leo 2026-08-27:「現在每天都在追新的,所以要用 Routine 去消化舊的,可以有多個條件」
兩條線各用各的判準(他當場訂正的那件事):
緊急線=掛 open milestone 的,用「距離目標的遠近」排
還債線=沒掛的那 188 張,用多條件排(事故/擋人/承諾/票齡/估工)← 本次做的
新增 scripts/debt-worklist(list/claim/forget):
· 撈全 org 15 個 repo 的 open issue + open PR,逐一列出當作「我查了哪些」的證明
· 扣掉掛 open milestone 的(緊急線在管)、等 leo 的(Human/human-exec/s/stage,
那些要催不是要領,催辦是 inkstone/ISEP#93)、已領走的
· 每張票旁邊印出「為什麼排這裡」的分項,排錯可以指著某一項說它給太多
· 成包只認強訊號:互相指著、或 Gitea 原生相依(母子票)。
第一版用單向引用成包,190 張裡 121 張黏成一坨——一包沒有人領得動
· 空清單會明講「查詢跑過了,結果是零」,不默默結束
· claim 之後那些票不再出現在清單上,並在隔天的清單頂端交代它們關了沒
hooks/session-start-recall.sh 加一段(不打網路,只看狀態檔日期):
今天還沒撈過就說一句,並給出要跑的那一行。開 session 自動去撈=輪詢,紅線擋著。
測試 scripts/test-debt-worklist.sh:40 條全離線,票上四條驗收條件各一組。
真實資料唯讀實跑過:229 張 → 可領 188 張/185 包,領走兩張後隔天清單少掉它們。
|
2026-08-28 00:38:02 +00:00 |
|
claude-code
|
9b0afec0b2
|
Merge pull request '雲端的閘:修好三個穩定重現的接線缺陷,並診斷第四個(inkstone/ISEP#90)' (#96) from fix/cloud-wiring-isep90 into main
|
2026-08-28 00:37:30 +00:00 |
|
claude-code
|
f3a41fba0e
|
下游做完時頂層跟著關(inkstone/ISEP#92)
票上的病:「開在頂層的票,下游做完了卻沒人回來關⋯⋯頂層票會永遠掛著,
而 leo 是看頂層的。」缺的三格是 journey 標籤、雙向連結的強制、完工回寫。
不重造既有的(票上明列):`ticket where` 戳記+側門閘(查票防重複)、
`comment-carries-task-guard`(留言藏任務)、Gitea 原生 issue dependency
(跨 repo 關聯的載體)——這一版全部長在它們上面。
四格,判準全部是機械事實(相依邊在不在、state 是什麼),沒有一格在猜文字:
① 雙向連結(驗收 1):`subtask`/新別名 `handoff` 一個動作同時掛原生相依
+ 在頂層票的時間軸貼一則指回下游的留言。相依邊只長在側欄,
時間軸上什麼都沒有,跨 repo 時尤其看不出來。
② 完工回寫(驗收 2,最痛的那格):`ticket close` 關完子票立刻問 `/blocks`
(誰在等我),對每張還開著的頂層票貼回寫留言;下游全關的那一張再
指派回總管+改 s/review。**不自動關母票**——關票要有交付物、要有人看過,
默默關掉跟默默留著是同一個病的兩面。
③ journey 標籤:`--journey <名>` 把 `j/<名>` 同時貼在母子兩端(只貼一端就
聚不起來)。標籤不存在就擋下並指回 labels.yaml——要求標籤在場,
不是猜哪些名字合法。labels.yaml 的 `j/` 段刻意留空:旅程怎麼切、叫什麼
名字是方向題,不由工具代決。
④ 撈得出來(驗收 3、4):新動詞 `ticket loose` 掃 org 的 open 票,撈
「有下游相依、下游全關、自己還開著」的頂層票。這是 ② 的補網——
關票的側門(直接 PATCH state=closed)是刻意放行的,漏掉的由這張網撈回來。
不是輪詢,掛在開場/收工對帳跑一次。
實跑(2026-08-28,唯讀,沒動任何票):245 張 open 票裡 17 張有下游相依,
其中 2 張是「下游都關了、自己還開著」——inkstone/arcrun-rag#136(已 s/review
且指派給 claude-code,正在被處理)與 inkstone/Arcrun#100(沒標籤、沒指派,
就是票上講的那種「永遠掛著」)。
測試:scripts/test-ticket-handoff-writeback.sh,49 條全綠,全程離線
(會打 API 的兩段把 api() 換成錄音機,不開票不關票不留測試票)。
回歸:A13 17/17、A4 24/24、A12 11/11 皆綠。
文件:docs/TESTING.md 新增 A16。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZBu4Sa1cGntKFRBYNZ6xs
|
2026-08-28 00:31:35 +00:00 |
|