Skip to content

docs: 勘破引擎的 command 与事件面 —— #840 必须连安装路径一起做;permission.ask 声明了却永不触发 - #846

Merged
jinjunnn merged 1 commit into
alphafrom
docs/command-event-surface
Aug 4, 2026
Merged

jinjunnn merged 1 commit into
alphafrom
docs/command-event-surface

Conversation

@jinjunnn

@jinjunnn jinjunnn commented Aug 4, 2026

Copy link
Copy Markdown
Owner

大白话

ADR-040 里挂着一条硬前置:hooks 的支持前置不是安全裁决,是一次事件面勘破,在它落地之前任何 hooks 实现票不得升 Ready。ac#840(给签名 package 加 command)的票面也写了「不许按票面动笔」——因为我当时只证明了 command 这个词在引擎配置和账本里存在,那不等于有活路径。

这份文档把两件事都跑出来了。 每条断言实读或实跑,未验证的一律标「未验证」。

三条会改变排期的结论

一、#840 不能只补 profile,必须把安装路径一起做。

有一条活路径能让 command 对用户可用——项目级 alpha_register,十跳全链已逐跳给出证据。但签名 package / 旧 catalog / 本地导入三条路,一条都没有 command 的路由、builder、账本、生效与卸载腿(逐入口给了断点)。我当初拿来当证据的 RECEIPT_TYPES 含 "command" 和 record.kind === "command" 两条,确认是弱证据,不构成安装路径 —— 和 plugin 当年一样。

二、permission.ask 声明了但永远不会被触发。

上游接口 packages/plugin/src/index.ts:261 声明了它,而全仓另一条轴上没有任何 trigger 调用点。⇒ 一个插件可以实现它、类型检查通过、而它一次都不会被调用。这是本仓「我留了个绊线 ≠ 那个绊线会绊到人」在上游的实例。任何依赖它做权限决策的设计当场作废。

三、variant 在 schema 里但运行时不生效。 Command 服务转配置时只复制 agent/model/description/template/subtask,没复制 variant。⇒ 不要把它写进 profile 合同,否则我们对外承诺一个上游不兑现的字段。

Claude hooks:真实语料实测,修正了 ADR-040 两个数

夹具里 hooks 的内容是占位字节,仓内也没有 Claude 的实现源码 —— 所以这一节全部读 ~/.claude/plugins/marketplaces/ 的真实文件。

  • 有 hooks/ 目录的 12/62,真正声明了 hook 的只有 7/62。另外 5 个(financial-services 那批)目录里有文件但没有任何声明。⇒ 谈影响面用 7,不是 12。
  • 实际用到 7 个事件名,ADR-040 列的六个漏了 UserPromptSubmit —— 而它(2 个插件)比 UserPromptExpansion(1 个)还常用。凭记忆列别人的事件名就会漏掉这种。

三条会让替身实现当场翻车的文法事实:

实测
if 用的是 Claude 的权限规则文法,不是布尔表达式:Bash(git commit:*) / Bash(git push:*) / Bash(gt create:*) …
asyncRewake / rewakeMessage / rewakeSummary 各 6 次真实在用。照「基础文档」写的实现会静默忽略它们
timeout 跨度 180 倍:5 / 10 / 180 / 900(codex 插件的 Stop)。钉一个固定超时会直接打死真实插件

运行时契约已验证:stdin JSON、stdout JSON、${CLAUDE_PLUGIN_ROOT} 既展开进命令串也作环境变量传入、type 恒为 command、matcher 是正则(能匹配带命名空间的工具名)、入口脚本 755 而辅助模块 644。未验证:退出码是否另有「exit 2 = 拦截」语义、stdin 的完整字段表 —— 两处都如实标了,写实现票前需补。

诚实映射:不为了凑齐而勉强配对

Stop 和 SessionEnd 引擎里没有(session.idle 是事后观察、不能阻止停止;session.deleted 是显式删除、不是会话结束)。PreToolUse 有强近似但没有结构化 allow/deny,只能靠抛错否决。PostToolUse 只在成功路径调用。SessionStart 只有窄观察类比。

门

零代码变更,两个 Markdown(新增一份 + 索引一行)。

  • north-star:命中 UPSTREAM_PATHS 的条目为空 ✅
  • docs 门:枚举到 2 个 Markdown → ✓ 15 relative link(s) resolve across 2 file(s),rc=0 ✅(bash -c 跑,枚举数与 across N file(s) 相等)

--no-verify:pre-push 钩子在共享主树上跑全量门,且 ac#815 未闭合。

文档影响

architecture(新增一份勘破)+ docs/README.md 索引一行。

ADR-040 明写 hooks 的支持前置是一次事件面勘破(不是安全裁决),在它落地前任何 hooks 实现票
不得升 Ready;#840 的票面也写了不许按票面动笔。本文档回答这两件事,每条断言实读或实跑,
未验证的一律标未验证。

引擎的 command:
- 配置是 Record<string, {template,description?,agent?,model?,variant?,subtask?}>;
- variant 在 schema 里但 Command 服务不复制它 ⇒ 不进合同,否则对外承诺上游不兑现的字段;
- 盘上形态是 {command,commands}/**/*.md,一命令一个 .md(不是一命令一目录),
  frontmatter 由安装版本的 gray-matter 解析;
- 有活路径让 command 可用(项目级 alpha_register 十跳全链),
  但签名 package/旧 catalog/本地导入三条路一条都没有安装腿(逐入口给断点)
  ⇒ #840 必须把安装路径一起做,不能只补 profile;
- RECEIPT_TYPES 含 command 与 record.kind === command 两条是弱证据,不构成安装路径。

事件面:
- 声明 15 个命名钩子,14 个有触发点;permission.ask 声明了但全仓无 trigger 调用点
  ⇒ 插件实现它、类型通过、永不被调用;
- 插件 event 钩子只收 {id,type,properties},void 调用不能否决,且只收当前 directory 的事件;
- 88 个注册 EventV2 分三组;三条可达性边界会咬人。

Claude hooks 真实语料实测(夹具正文是占位字节,本节全部读真实目录):
- 有 hooks/ 目录的 12/62,真正声明了 hook 的只有 7/62 ⇒ ADR-040 的 12 要按 7 谈影响面;
- 实际用到 7 个事件名,ADR-040 列的六个漏了 UserPromptSubmit(2 个插件用,比 UserPromptExpansion 还多);
- 声明文法有三条会让替身实现翻车:if 用的是权限规则文法(Bash(git commit:*))、
  asyncRewake/rewakeMessage/rewakeSummary 各 6 次真实在用、timeout 跨度 180 倍(5/10/180/900);
- 运行时契约:stdin JSON、stdout JSON、CLAUDE_PLUGIN_ROOT 既展开进命令串也作环境变量、
  type 恒为 command、matcher 是正则;退出码是否另有拦截语义未验证。

诚实映射:Stop 与 SessionEnd 引擎里没有;PreToolUse 有强近似但无结构化 allow/deny;
PostToolUse 只在成功路径;SessionStart 只有窄观察类比。

文档影响:architecture(新增一份勘破)+ docs/README.md 索引一行。无代码变更。
@jinjunnn
jinjunnn merged commit 479d640 into alpha Aug 4, 2026
1 check passed
@jinjunnn
jinjunnn deleted the docs/command-event-surface branch August 4, 2026 04:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant