#4535 的 C11 簇,v17 收口三簇之二 。基线行(仅 1 条,且只有 type、没有 Schema):
HttpRequest — [./shared (type)] ≠ [./ui (type)]
基线现为 19 条 (C9/#4684 因待裁决未落地,故口径是 19 不是 17),本簇目标 19 → 18 。
本簇大概率是三簇里最简单的一簇 —— const 本来就是单源
已在 origin/main(f2445c9)复核:
位置
内容
ui/view.zod.ts:21
import { HttpMethodSchema, HttpRequestSchema } from '../shared/http.zod';
ui/view.zod.ts:37
export { HttpMethodSchema, HttpRequestSchema }; —— 原样 re-export
ui/view.zod.ts:2039
export type HttpRequest = z.infer<typeof HttpRequestSchema>; ← 唯一的双源点
shared/http.zod.ts:46
HttpRequestSchema 唯一声明;:54 export type HttpRequest = z.infer<...>
HttpRequestSchema 从来就没有第二份声明 —— ui 是 import 进来再 re-export 的,所以基线里没有 HttpRequestSchema 行。被判为双源的只有那个本地 type 别名 :它 z.infer 的正是同一个 schema 对象,只是构成了第二个类型声明符号。基线文件表头说明了判据:
judged by symbol identity (a re-export of one declaration from many entries is fine and not listed)
所以处置就是把 :2039 那行从「本地 infer」改成「re-export shared 的类型」,让它变成表头说的 "a re-export of one declaration" 从而不再被记。
零 authorable key 消失、零 tombstone、零 conversion —— 本簇不触发 C9(#4684 )撞上的那个门禁死结(那是 def 改名导致 ratchet 认为 key 消失;本簇不改任何 def、不动 HttpRequestSchema)。
⚠️ 必须保持 ui 侧仍然导出这个类型
ui/view.test.ts:39 有 type HttpRequest 从 ./view.zod 的具名导入。删掉别名而不补 re-export 会打断它 ,这是本簇唯一的现实风险。export type { HttpRequest } from '../shared/http.zod'; 之类的写法可保持导入点不变 —— 具体形式由你定,但要保证 from './view.zod' 导入该类型的既有写法继续可用。
⛔ 不要顺手修隔壁的 HttpMethod
ui/view.zod.ts:2040,紧挨着的下一行 ,是形状完全相同的 export type HttpMethod = z.infer<typeof HttpMethodSchema>;。它的基线行是 HttpMethod — [./api, ./shared (type)] ≠ [./ui (type)],#4535 已把它排进 v18 (不在元数据文档管道上)。
诱惑很大且改动几乎零成本,但范围是维护者定的,不是就手方便定的 。本簇只清 1 条。若你确认它确实是同一形状,写进 PR 描述与 out-of-scope findings ,让维护者决定要不要并进来 —— 不要自己扩。
关于 breaking 级别:自己判,不要为了凑 major 而声称破坏
#4535 把三簇统称 breaking,但本簇需要你自己核实 :两个别名从同一个 schema 对象 infer,结构上应当完全相同,消费者侧可能是零类型差异。changeset 级别按实际情况 定并在正文说清理由。若确认零消费者影响,不要硬写成 major —— 谎报破坏和漏报破坏一样是污染升级指南。(反之若你发现两者其实不同,那是重要发现,写清楚。)
纪律(#4535 §1–§4 + 手册 6/7/8,开工前必读)
⛔ 禁止手编 packages/spec/authorable-surface.json (authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650 )。
⚠️ 门禁绿 ≠ 登记正确(build-schemas.ts 检查 (b) 用叶名匹配 conversion surface —— 无关簇的 .type 就能让一个 tombstone 冒充「已登记迁移」 #4659 ) ;默认值 / 约束变更不被任何门禁记录(spec 门禁盲区:可作者化 key 的「默认值 / 约束」变更不被任何 gate、tombstone 或 conversion 记录(#4650 / #4659 同族) #4666 ) —— 本簇若真是纯类型别名改动,这两条应当不触发,但要自己确认而不是假定。
回归 pin 用运行时模块命名空间断言 (packages/spec 的「编译期 pin」是失效的:tsconfig 排除了 *.test.ts,vitest 也不做类型检查 #4642 已证编译期 pin 空转),必须 sabotage 验证 并贴输出。
判不出来就升级,不要猜 (spec 双源清账 C5:ActivationEventSchema(./kernel ≠ ./studio)—— 1 条 #4653 / spec 双源清账 C6:EventSchema(./automation ≠ ./kernel)—— 1 条 #4658 / spec 双源清账 C8:RetryPolicy / RetryPolicySchema(./automation ≠ ./system)—— 2 条 #4661 / spec 双源清账 C9:RateLimitConfig / RateLimitConfigSchema(./integration ≠ ./shared)—— 2 条 #4684 先例)。分析本身就是交付物。
⚠️ 生成物冲突只能靠重新生成 (手册第 7 条)。v17 收尾期 main 前进很快 —— 推之前重新 git fetch origin main 判一次 ;spec-changes.json 是对象数组,必须跑 gen:spec-changes ,集合合并会丢条目并把 CI 打红。解完冲突务必本地跑对应 check:* 再推。
⛔ 不要碰 content/docs/releases/ 。
⛔ 不要碰门禁洞 issue (spec 门禁盲区:可作者化 key 的「默认值 / 约束」变更不被任何 gate、tombstone 或 conversion 记录(#4650 / #4659 同族) #4666 / authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650 / build-schemas.ts 检查 (b) 用叶名匹配 conversion surface —— 无关簇的 .type 就能让一个 tombstone 冒充「已登记迁移」 #4659 / authorable-surface.json 在 main 上不是 gen:schema 的输出 —— 基线手编的字节级实锤(#4650 加固建议) #4663 / packages/spec 的「编译期 pin」是失效的:tsconfig 排除了 *.test.ts,vitest 也不做类型检查 #4642 / spec 生成物没有 merge driver:两个 PR 各改几行,语义上是集合运算,却每次都打成文本冲突 #4675 / 投影类生成物是否该退出仓库 —— 分清「记忆」与「投影」,前者必须留在 PR 粒度,后者可以 CI 重算 #4676 ),它们等维护者排期。
验收
基线删掉上面 1 行,19 → 18 ,只减不增。
全绿:build、check:dual-source-exports、check:generated、test,加源码审计组(check:liveness / check:strictness-ledger / check:empty-state / check:variant-docs / check:exported-any / check:skill-examples),以及全仓 pnpm typecheck。
ui/view.test.ts 的既有具名类型导入继续可用。
changeset 一份,级别按上面「自己判」一节的结论定,含 FROM → TO(若确有消费者可见变化)。
注意 spec 现为 17.0.0-rc.1、pre-mode 仍开。
关联:#4535 (主单)、#4684 (C9,待裁决 —— 其门禁死结不适用于本簇 )、#4650 / #4659 / #4666 (门禁洞)、#4642 (pin 空转)、#4675 (生成物冲突)、ADR-0049、ADR-0087、ADR-0104
#4535 的 C11 簇,v17 收口三簇之二。基线行(仅 1 条,且只有 type、没有 Schema):
基线现为 19 条(C9/#4684 因待裁决未落地,故口径是 19 不是 17),本簇目标 19 → 18。
本簇大概率是三簇里最简单的一簇 —— const 本来就是单源
已在
origin/main(f2445c9)复核:ui/view.zod.ts:21import { HttpMethodSchema, HttpRequestSchema } from '../shared/http.zod';ui/view.zod.ts:37export { HttpMethodSchema, HttpRequestSchema };—— 原样 re-exportui/view.zod.ts:2039export type HttpRequest = z.infer<typeof HttpRequestSchema>;← 唯一的双源点shared/http.zod.ts:46HttpRequestSchema唯一声明;:54export type HttpRequest = z.infer<...>HttpRequestSchema从来就没有第二份声明 —— ui 是 import 进来再 re-export 的,所以基线里没有HttpRequestSchema行。被判为双源的只有那个本地 type 别名:它z.infer的正是同一个 schema 对象,只是构成了第二个类型声明符号。基线文件表头说明了判据:所以处置就是把
:2039那行从「本地 infer」改成「re-export shared 的类型」,让它变成表头说的 "a re-export of one declaration" 从而不再被记。零 authorable key 消失、零 tombstone、零 conversion —— 本簇不触发 C9(#4684)撞上的那个门禁死结(那是 def 改名导致 ratchet 认为 key 消失;本簇不改任何 def、不动
HttpRequestSchema)。ui/view.test.ts:39有type HttpRequest从./view.zod的具名导入。删掉别名而不补 re-export 会打断它,这是本簇唯一的现实风险。export type { HttpRequest } from '../shared/http.zod';之类的写法可保持导入点不变 —— 具体形式由你定,但要保证from './view.zod'导入该类型的既有写法继续可用。⛔ 不要顺手修隔壁的 HttpMethod
ui/view.zod.ts:2040,紧挨着的下一行,是形状完全相同的export type HttpMethod = z.infer<typeof HttpMethodSchema>;。它的基线行是HttpMethod — [./api, ./shared (type)] ≠ [./ui (type)],#4535 已把它排进 v18(不在元数据文档管道上)。诱惑很大且改动几乎零成本,但范围是维护者定的,不是就手方便定的。本簇只清 1 条。若你确认它确实是同一形状,写进 PR 描述与 out-of-scope findings,让维护者决定要不要并进来 —— 不要自己扩。
关于 breaking 级别:自己判,不要为了凑 major 而声称破坏
#4535 把三簇统称 breaking,但本簇需要你自己核实:两个别名从同一个 schema 对象 infer,结构上应当完全相同,消费者侧可能是零类型差异。changeset 级别按实际情况定并在正文说清理由。若确认零消费者影响,不要硬写成 major —— 谎报破坏和漏报破坏一样是污染升级指南。(反之若你发现两者其实不同,那是重要发现,写清楚。)
纪律(#4535 §1–§4 + 手册 6/7/8,开工前必读)
packages/spec/authorable-surface.json(authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650)。.type就能让一个 tombstone 冒充「已登记迁移」 #4659);默认值 / 约束变更不被任何门禁记录(spec 门禁盲区:可作者化 key 的「默认值 / 约束」变更不被任何 gate、tombstone 或 conversion 记录(#4650 / #4659 同族) #4666) —— 本簇若真是纯类型别名改动,这两条应当不触发,但要自己确认而不是假定。git fetch origin main判一次;spec-changes.json是对象数组,必须跑gen:spec-changes,集合合并会丢条目并把 CI 打红。解完冲突务必本地跑对应check:*再推。content/docs/releases/。.type就能让一个 tombstone 冒充「已登记迁移」 #4659 /authorable-surface.json在 main 上不是gen:schema的输出 —— 基线手编的字节级实锤(#4650 加固建议) #4663 / packages/spec 的「编译期 pin」是失效的:tsconfig 排除了 *.test.ts,vitest 也不做类型检查 #4642 / spec 生成物没有 merge driver:两个 PR 各改几行,语义上是集合运算,却每次都打成文本冲突 #4675 / 投影类生成物是否该退出仓库 —— 分清「记忆」与「投影」,前者必须留在 PR 粒度,后者可以 CI 重算 #4676),它们等维护者排期。验收
build、check:dual-source-exports、check:generated、test,加源码审计组(check:liveness/check:strictness-ledger/check:empty-state/check:variant-docs/check:exported-any/check:skill-examples),以及全仓pnpm typecheck。ui/view.test.ts的既有具名类型导入继续可用。17.0.0-rc.1、pre-mode 仍开。关联:#4535(主单)、#4684(C9,待裁决 —— 其门禁死结不适用于本簇)、#4650 / #4659 / #4666(门禁洞)、#4642(pin 空转)、#4675(生成物冲突)、ADR-0049、ADR-0087、ADR-0104