[Bug] SessionStart hook 对 startup source 正常派发,/compact 后不派发(compact source 从未触发,0.16.5 实测)
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 22
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
提交前确认 · Pre-submission checklist
- 我已搜索过现有 issue,确认这不是重复提议 / I searched existing issues and confirmed this isn't a duplicate.
- 我已阅读 CONTRIBUTING.md / I've read CONTRIBUTING.md.
与 #167 的关系:#167 家族的共同根因是「hooks 注册成功、UI 显示已加载,但运行时从不触发」。本案例不同——同一注册条目对
startupsource 正常派发,只有/compact时不派发(source 级、事件级更精确),无法归入「从不触发」的根因描述,故单独开帖供研发定位;如判断应合并回 #167 请直接处理。
问题类别 · Category
对话 / Agent 交互 · Agent chat(compact 与 SessionStart hook 派发)
涉及的 Agent 框架 · Agent framework
ZCode Agent(自研)
严重程度 · Severity
影响体验 · Major(依赖 SessionStart(compact) 注入接续材料的方案完全不可用)
复现频率 · Reproducibility
必现 · Always
问题描述 · Description
官方 hooks 文档宣称「SessionStart 匹配 source,常见值为 startup / clear / compact」。实测(macOS,user-level ~/.zcode/cli/config.json 注册 process hook):
startupsource 有派发:新开对话时 hook 被真实调用,stdin JSON 中source: "startup";/compact后零派发:同一对话真实执行/compact,hook 完全没有被调用(诊断日志零新行),压缩后 context 也没有任何注入;- matcher 对 SessionStart 的 source 匹配疑似不生效:带
matcher: "compact"注册时,五天内 startup / compact 均零调用(startup 本应被 matcher 过滤掉,这符合预期;但 compact 也从未命中)。为排除 matcher 变因,复现实验全部改用无 matcher 注册(脚本内自行按sourcegate)。
证据链(三步排除法)· Evidence chain
hook 脚本入口第一行把 stdin 原文写入日志文件(先落档、再做任何 source 判断),任何调用都会留痕:
- 带
matcher: "compact":日志五天零调用 → 无法区分「事件不派发」与「matcher 不匹配」; - 移除 matcher(脚本内 source gate):新开对话 → 日志出现
source=startup行(首次非手动调用的真实派发实证,SessionStart 事件本身是活的); - 同一对话真实
/compact(input_history表可证该 prompt 确实执行、压缩确实发生)→ 日志无任何新行、压缩后 context 无注入块 → compact 时机 SessionStart 零派发。
复现步骤 · Steps to reproduce
- user-level config 注册 SessionStart hook(无 matcher),脚本把 stdin 写日志:
"SessionStart": [
{ "hooks": [ { "type": "process", "command": "python3", "args": ["/abs/path/hook.py"], "timeoutMs": 10000 } ] }
]
- 新开对话 → 日志出现
source=startup行 ✅ - 同一对话执行
/compact→ 日志无新行 ❌(按文档预期应出现source=compact)
期望行为 · Expected behavior
/compact 完成后 SessionStart hook 以 source=compact 派发(文档宣称的行为)。顺带请求确认:SessionStart 的 matcher 对 source 的匹配在当前版本是否生效(本实验以无 matcher 绕过,未单独验证 matcher 语义)。
使用场景 · Use case
compact 后自动注入接续材料(压缩前对话尾部原文 + 项目 STATE),缓解长会话压缩后 verbatim 交付物丢失、摘要细节失真的问题——与 #348 的 keep-anchors 诉求同源,是其在 hook 层的实现路径。
你使用的 ZCode 版本 / 环境 · ZCode version / environment
ZCode Desktop,macOS(darwin arm64),engine 0.16.5(#167 留言中 0.16.3 的 subagent hookRunner 根因分析之后的版本;本案例发生在主 session,非 subagent)。
English summary
Official docs claim SessionStart matcher matches source values startup / clear / compact. Measured on engine 0.16.5 (user-level config hook, no matcher, stdin-logging script): SessionStart does dispatch with source=startup on new conversations, but a real /compact results in zero hook invocations (no log line, no injected context). With matcher: "compact" registered, no source ever fired within 5 days. Distinct from #167's "registered but never fire" family — here the same registration fires for startup and only misses compact. Repro: register matcher-less SessionStart hook that logs stdin → new chat logs source=startup → run /compact → no new log line.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce with the user-level ~/.zcode/cli/config.json SessionStart process hook and the stdin-logging hook.py on engine 0.16.5. Compare logs after startup and a real /compact, then verify that compact dispatches source=compact and that matcher behavior is understood.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, python
- Domain
- developer-experience, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100