You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
抗 AI 写错:有一点真实收益 —— type 是事件信封上最容易被 AI 写错的键(业界惯例就是 type 作判别符),一块指向 name 的墓碑确实挡得住。但这个收益可以单独、诚实地拿到(直接给 kernel 的 Event 加一条 type → name 的 UNKNOWN_KEY_GUIDANCE / 墓碑),不需要为此把两个概念合并。schema → payload 则纯属牵强(一个是声明的形状,一个是实际数据)。
Activity
os-zhuang commentedon Aug 2, 2026
🤖 Claiming this issue.
session_01M9uWvoEp9CoLzYjNExj9sLclaude/issue-4658-event-schema-dual-source../objectstack-4658计划:先做四仓(objectstack + cloud + cloud-v1 + objectui)import 语句级扫描 + 两侧形状 diff,判定「同一概念 vs 两个概念」,再按 #4535「v17 重切」§1–§3 选路线(默认收敛 + re-export,非死删;两个概念则改名)。不会手编
authorable-surface.json(§2 / #4650),回归 pin 用运行时模块命名空间断言 + sabotage 验证(#4642)。判不出来会按 C5(#4653)的先例停下来升级而不是猜。若有更早的其他 session 已认领,请回复,我会立即退出。
Generated by Claude Code
os-zhuang commentedon Aug 2, 2026
🛑 停在裁决点:本簇存在机械死锁,未写任何代码
session
session_01M9uWvoEp9CoLzYjNExj9sL。四仓扫描 + 两侧形状 diff 已做完,并用两组实验把死锁跑出来了(下附真实输出)。结论:立单的判断(「两个概念,该改名而非收敛」)成立,但改名这条路在当前门禁下走不通,且不存在既关掉基线行、又不让可作者化 key 消失的路线 —— 唯一的例外是「收敛」,而收敛在本簇是事实错误。按军规不猜,交回裁决。1. 四仓 import 语句级扫描
扫了
objectstack(worktree @21676eb5d)、cloud@bce2bec、cloud-v1@e4c2040、objectui@f572849。EventSchema在packages/spec之外,四仓 import 为零。 三个兄弟仓连裸名EventSchema都是 0 命中(含多行 import 块的 multiline 扫描)。objectui唯一的暴露是packages/types/src/index.ts:937,940的export type * as Automation/export type * as Kernel—— 命名空间隔离,两侧不打架(与 C5 同形)。本仓消费方:
automationkernelkernel/events/dlq.zod.ts:24,71(嵌两次)、kernel/events.test.ts2. 两侧形状 diff:键集完全不相交
不是宽窄之差,是两个概念:
type,SCREAMING_CASE 词表。name,点号命名空间;还带payload/metadata。零键重叠。而且 kernel 自己已经区分了这两件事:同文件
core.zod.ts:93的EventTypeDefinitionSchema(name/version/schema/deprecated/tags)才是 kernel 侧的「事件定义」。automation 的EventSchema语义上对应的是 kernel 的EventTypeDefinition,而不是 kernel 的Event。⇒ 收敛是错的。立单判断成立。
3. 但 automation 侧不是「活的另一侧」,是孤儿声明
StateMachineSchema(同文件 :130)从不引用EventSchema—— 状态机里事件类型是on:的记录键(z.record(z.string(), ...)),纯字符串:EventSchema在src/automation/里的出现次数:1 次,就是它自己的定义行。没有任何父 schema 嵌它,没有任何模块 import 它。它进authorable-surface.json的唯一原因是automation/index.ts:26的export * from './state-machine.zod'把它带进了Automation命名空间,而build-schemas.ts把每一个导出的 ZodType 都发成 def(不问是否被嵌入)。这一点与 C5 不同,不能照搬 C5 的「零 importer ≠ 可死删」:C5 是两侧都被各自父 schema 引用;本簇 automation 侧连父 schema 都没有。这里确实有死侧。
补充一层证据 —— 两侧都够不到作者面:
check:liveness是 registry-rooted(从BUILTIN_METADATA_TYPE_SCHEMAS走)。automation/Event零引用当然够不到;kernel/Event只经 DLQ 形状,而 DLQ 只在测试里被 parse,不在任何 metadata type 下。两侧的authorable-surface.json条目都是过度收集的产物(#4535 §2 已承认该文件连 REST 信封字段都记)。可作者化 key 数复核 —— 与立单一致:automation 2 / kernel 4。
4. 死锁:改名 / 删除 / 收敛,三条路互斥
实验一 —— 删掉 automation 的孤儿(改名同理,
defKey一样整体位移):⇒ 立单 §3 的「若某侧可作者化 key 数为 0 则改那侧零成本」的例外在本簇不成立 —— automation 侧是 2 不是 0,C5 的便宜路子这里没有。改 kernel 侧更贵(4 个 key,且改的是活的那侧)。
唯一合法补救是 tombstone —— 但 tombstone 必须挂在
automation/Event这个 defKey 上,即./automation必须继续导出一个名字剥掉Schema后等于Event的符号。而check-dual-source-exports.ts判定的是符号同一性(「judged by symbol identity」),一个 tombstone 版的automation/EventSchema仍是与 kernel 不同的声明 ⇒ 基线行照报,22 → 22,本簇关不掉。实验二 —— 把 automation 两个 key 改成
retiredKey():检查 (a) 确实放行(无 vanish),检查 (b) 只要求补一条 surface 以
.schema结尾的 D2 conversion。注:automation/Event:type静默通过是门禁的 bug(叶名匹配撞上无关的flow.node.type),已按军规立案 #4659(unassigned,未在本单动手)。⇒ 死锁成立:「关掉基线行」与「不让可作者化 key 消失」在本簇不可兼得,除非收敛 —— 而收敛把两个不相干的概念声明成一个。
5. 三条路线,两轴分析
A. 删掉 automation 的孤儿声明(工程上正确的那条)
authorable-surface.json两行 —— 正是 authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650 / ✅ spec 双源清账主单:基线 52 → 0(2026-08-03 收官)—— #4446 gate 落地后的偿还 worklist #4535 §2 / 本单纪律 §2 明令禁止的动作。Event(kernel 信封),XState 时代的残留物被删掉而不是被做成标本。不写任何假话进合同。BUILTIN_METADATA_TYPE_SCHEMAS不可达的 def,其 key 可以出基线」。这恰好是 authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650 正在做的加固。StateMachineEventSchema+ 真的嵌进StateMachineSchema」,门禁代价与 A 完全相同(同样是那 2 个 key vanish),但把孤儿救活而不是删掉。B. 收敛:
./automationre-export kernel 的,把type/schema两块墓碑挂到 kernel 的EventSchema上kernel/Event:type/kernel/Event:schema会作为新增基线行进authorable-surface.json,即在 kernel 合同里凭空写下两段从未发生过的历史,让以后每个读到这两块墓碑的人被误导。这是典型的「为了门禁变绿而牺牲合同真实性」的 workaround。type是事件信封上最容易被 AI 写错的键(业界惯例就是type作判别符),一块指向name的墓碑确实挡得住。但这个收益可以单独、诚实地拿到(直接给 kernel 的Event加一条type→name的 UNKNOWN_KEY_GUIDANCE / 墓碑),不需要为此把两个概念合并。schema→payload则纯属牵强(一个是声明的形状,一个是实际数据)。type和name、同时有schema和payload的四不像形状,正是「消费侧宽容」的反面教材,建议直接排除。C. 原地 tombstone,基线行下轮再关
6. 我的建议
推荐 A(删孤儿),前提是维护者愿意批一个窄例外;否则退 C。B 建议否决。
两轴在此不冲突,但都不指向那条唯一能今天全绿的路:
Event,残留物删除。B 是用「在合同里写两条假历史 + 把两个不相干概念声明成一个」换一个绿灯,这正是纪律里点名的 workaround;它的长期成本会由以后每个读kernel/Event墓碑的人分期偿还。C 诚实但留债。type→name)可以脱离 B 单独取得。所以请裁两件事:
authorable-surface.json的删行禁令,是否容许一个窄例外:「从BUILTIN_METADATA_TYPE_SCHEMAS不可达的 def(可机器判定),其 key 可随 def 一并出基线」?批 ⇒ 本单走 A,并把该判定固化成 authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650 的一部分,免得下一簇再撞。不批 ⇒ 本单走 C,基线行本轮不减,C6 从 v17 worklist 移出。EventSchema是删还是救? 删 ⇒ A;想保留显式事件声明 ⇒ A′(改名 + 真的嵌进StateMachineSchema),门禁代价相同。顺带一提:
StateMachineSchema本身在ai/agent.zod.ts:197上挂着[EXPERIMENTAL — not enforced] ... Parsed but no runtime consumer yet (liveness #1878/#1893),而 ADR-0020 说记录状态机的真实作者面是object.validations[]里的StateMachineValidationSchema(完全不同的扁平形状)。若这一族整体要按 ADR-0049 处置,本单更不该先替它挑编码 —— 与 C5/#4657 同形。裁决给到我就继续。分支
claude/issue-4658-event-schema-dual-source无 commit,worktree 已清理,authorable-surface.json与基线文件均未改动。Generated by Claude Code
os-zhuang commentedon Aug 2, 2026
维护者裁决:路线 A —— 但执行顺延 v18
2026-08-02 裁决 A:在 #4650 里加一个可机检的窄例外(证明不从
BUILTIN_METADATA_TYPE_SCHEMAS可达的 def,允许删其基线行),据此删掉./automation的EventSchema孤儿,基线 22 → 21。采纳理由与升级分析一致:两侧键集完全不相交(XState 信号定义
{type, schema}vs 事件总线信封{id, name, payload, metadata}),收敛等于往合同里写两句假话 —— 既宣称状态机信号就是事件信封,又向 kernel 合同凭空新增type/schema两行伪造历史。B 已否决。但本簇执行顺延 v18。 同日 v17 范围按可达性收口到 4 簇(C8 / C9 / C11 / C12),
Event两侧均不在元数据文档管道上,不占发布窗口。备选 A′(改名StateMachineEventSchema并真的嵌进StateMachineSchema,救活孤儿而非删除)保留为实施时的选项。前置:#4650 的窄例外未落地前,本簇无法诚实收口 —— 现在删基线行仍然是「删证据」。
你另外发现的 #4659(检查 (b) 按 leaf name 匹配 conversion surface,
automation/Event:type靠不相干的flow.node.type蒙混过关)已记入主单 §2,与 #4650 同族。两个发现都很扎实,谢谢。Generated by Claude Code
os-zhuang commentedon Aug 3, 2026
🔒 认领(双源第二批首发 · 实施 B 线,与 #3207 并行——文件区零交集,入队串行按 #4535 新协议)
session_0176qgxgCXTJCUv4YFLtusP9claude/issue-4658-event-dual-sourceEventSchema,基线 13→12.changeset/pre.json实测仍mode: pre(2026-08-03 01:15Z)Generated by Claude Code
os-zhuang commentedon Aug 3, 2026
📦 路线 A 已实施,draft PR:#4745(会话
session_0176qgxgCXTJCUv4YFLtusP9,分支claude/issue-4658-event-dual-source)。check:dual-source-exports实跑:12 accepted dual-source);automation/Event:*走「def no longer emitted」自证路径(输出贴在 PR §2);StateMachineSchema本身可达 —— 删除是外科式的;@objectstack/specmajor(TS2305),零元数据迁移;Generated by Claude Code
os-zhuang commentedon Aug 3, 2026
✅ 验收通过(ACCEPT) — PR #4745 已转正并开 auto-merge。双源基线 13 → 12,第二批首单落地在望。
对实际 diff(11 文件)逐项核对的结论:
EventSchema;信号声明 → kernelEventTypeDefinitionSchema;状态机事件 →on:记录键),kernel 侧一字未动。StateMachineSchema本身可达,证明删除外科式不伤作者面。check:api-surface两个裁决点都满足;authorable-surface 删的两行与生成器规范形逐字节一致。package.jsonexports map 枚举(17 个,未来新入口逃不出唯一性断言)+「全入口范围内叫EventSchema的导出必须解析到 kernel 唯一声明」;S2 sabotage 专证被否决的收敛路线也会被拦(那条路线骗得过 dual-source gate 的符号同一性视角——pin 拦的是裁决本身)。RENAMED_DEFS/KNOWN_STILL_DUAL_SOURCE未动;releases 未碰。enable.trash/enable.mrucapability flags (ADR-0049 enforce-or-remove) #3207/PR fix(spec): #3207 收尾 — 补上 enable.trash/mru 退役缺失的 ADR-0087 迁移面,墓碑改指 #3146 #4734 生成物改动零文件重叠,队列可安全串行消化。合并后 #4535 勾 C6;B 线按排程接 C13+C15(#4738)——同 automation 区,正好等本单落地后起飞。
Generated by Claude Code
feat(spec)!: 移除 `./automation` 的孤儿 `EventSchema` —— C6 双源清账,信封唯一真源在 `…