Part of #5040(E 系列第 7 单,**发布目标 v17**,维护者裁决 2026-08-04:执行器直接进 v17,v17 切版等 E 系列全绿)。**Blocked-by: #5091(E4)+ #5092(E5)+ #5093(E6)** —— 执行面齐备前 publish 不得放行。 ## 范围(以 #5040 设计与 ADR-0121 为准,spec 车道) 1. **收窄 #4936 的整面硬拒**(`packages/spec/src/stack.zod.ts`):非空 `apis:` 不再一律拒绝,改为逐端点过门 —— - **支持子集门**:仅放行 17.x 实际执行的形状(E2–E5 已落的匹配与委派能力);词表里声明了但执行器不支持的组合仍**响亮拒绝**(错误文案指向具体键与替代方案,不留 declared≠enforced 缝隙); - **命名空间门**:`path` 必须落在本包命名空间的挂载前缀下(`/api/v1/apps/<ns>/…`),跨命名空间/越界路径拒绝(ADR-0076 一路一主在 publish 时即成立);同栈内重复 METHOD+path 拒绝(运行时的字典序裁决只兜 publish 之外的直写)。 2. 生成物整体重生成(os-regen 四步;错误文案、spec-changes、**upgrade-guide** 均会动)。 3. **升级文档 = 安全承载件**(维护者裁决:不加激活开关,靠文档让 AI 维护者知情):upgrade-guide 条目必须显式包含 —— v16 休眠 `apis:` 配置在 v17 会被校验并激活;指令 AI 维护者**审视历史配置,尤其显式 `authRequired: false` 条目**(词表缺省即 `true`,E1 已物化,漏写不构成风险);不改 `content/docs/releases/`(Prime Directive,发版说明由 changeset 集中编译)。 4. Changeset:`@objectstack/spec` 相应级别,明确「v17 破坏面 = 校验从整面拒绝改为条件放行」。 ## 约束 词表冻结(`ApiEndpointSchema` 零改动 —— 门是校验逻辑,不是新键);执行器车道程序卡(`session_01EYGdmvWP1ieZSLqvAW6uyd` 按序派发),**其它车道请勿认领**。 关联:ADR-0121、#4936(被收窄的裁决)、#5089/#5090/#5091/#5092/#5093、#5040 设计 §6。
Activity
os-zhuang commentedon Aug 4, 2026
来自 E4(#5091 / PR #5135)的 publish 门补充项 —— 四条,第 1 条是安全相关
E4 把三个策略键接进运行时时,在词表侧撞到几处「运行时能答、但应该在 publish 就被打回」的形状。按「归挂不散落」记在本单(它们都落在本单收窄硬拒的完成范围内),不另开卡:
1.⚠️ D6「
authRequired: false必须伴随rateLimit」的门必须校验enabled === true,而不只是「键存在」。RateLimitConfigSchema.enabled的 schema 默认值是false(packages/spec/src/shared/http.zod.ts:131)。因此这样一条声明:parse 之后是
enabled: false—— 一个完全不计量的匿名端点,却满足了「伴随 rateLimit」的字面要求。运行时这边按声明即执行的读法处理(deriveBucketConfig返回null,不计量,E4 有测试钉住),所以这道缝只能在 publish 门堵:门的判据应为rateLimit?.enabled === true,拒绝文案带处方(「匿名端点必须显式rateLimit: { enabled: true, … };只写窗口和配额不会启用限流」)。ADR-0121 D6 立这条门正是为了匿名面不被白嫖,按字面实现会让门形同虚设。2. 端点级
rateLimit的maxRequests/windowMs≤ 0 应在 publish 拒绝。server 级预算由
deriveBucketConfig在 boot 期抛错挡住;端点级没有 boot 期这一说,E4 的裁断是 fail closed —— 每次命中该端点都抛错(经兜底器成 5xx),因为「作者要求计量、实际不计量」是更坏的结果。但作者应该在 publish 就被告知,而不是上线后每请求一个 5xx。文案可直接复用 server 级那两段(零预算会连自己的健康检查都拒;要关限流请写enabled: false)。3. 负数
cacheTtl应在 publish 拒绝。cacheTtl: z.number().optional(),没有.int()也没有下界,所以-5合法。运行时不能不答,E4 的裁断是负值与0同义 →Cache-Control: no-store;但负的「响应缓存秒数」在授权面上是没有意义的一句话,应在 publish 打回。(小数同理未拒,E4 按Math.floor截断成整秒 —— 这个可以不拒,截断是无歧义的。)4. 非 GET 端点上的
cacheTtl(设计 §3.3 已列在本单清单里)——确认保留。运行时侧 E4 已做成「不发头 + warn 点名端点」,不静默丢弃;门落地后这条 warn 就只会在绕过 publish 直写metadata.register()的路径上出现。以上四条都不需要动词表(
ApiEndpointSchema零改动),纯校验逻辑,与本单卡面「门是校验逻辑,不是新键」的约束一致。Generated by Claude Code
os-zhuang commentedon Aug 4, 2026
E5c(#5137 / PR #5167)交来的 publish 门清单 —— 映射键部分
E5c 已把
inputMapping/outputMapping接进执行链(packages/runtime/src/api-mapping.ts)。runtime 侧对无法服务的声明给结构化 501NOT_IMPLEMENTED(点名条目,带处方),但那只是「绕过 publish 直写metadata.register()」的兜底 —— 本门才是作者应该遇到的第一道关口。请把下列三类并入本单的「不支持子集」硬拒(runtime 侧的判定逻辑集中在mappingDeclarationRejection,可逐条照读):transform子键(设计 §3.4 已定,此处仅确认落项):全仓无「transformation function name」注册表;处方 = 用source/target的搬运改名能力,函数式变换待 transform 注册表另行立项;source/target路径:空串、空段(a..b、前后缀点)、JS 原型键(__proto__/prototype/constructor);target:同栈同一端点内两条写同一路径,或一条写进另一条内部(x与x.y)—— 后者会静默丢弃前者,是典型的「写了但没生效」。两个留给本单裁决的问题(runtime 侧未擅自发明)
inputMapping的来源域:词表 describe 写的是 Map Request Body to Internal Params,E5c 因此只读请求体,未采纳设计 §3.4 提过的{...query, ...body}(合并会凭空发明一条谁覆盖谁的优先级规则)。若维护者认为映射也应看见 query,那是对现解读的兼容放宽,加来源即可;反向则是破坏性收紧。inputMapping写在不读 body 的操作(object_operation的find/get/delete)上时,今天是一条合法但什么也不做的声明 —— 与cacheTtl写在非 GET 上同形(本单已收 GET-only 拒绝),建议一并按同样的姿态处理。Generated by Claude Code
os-zhuang commentedon Aug 4, 2026
认领 —— PM 会话
session_01EYGdmvWP1ieZSLqvAW6uyd(执行器车道),分支claude/issue-5111-publish-flip,即刻派发。前置 E1–E6 + E5b/E5c 全部落 main(至1203bb2),执行链在真实 boot 上验证通过。两项词表裁决随认领落定(依程序自身原则,PM 裁定):
inputMapping声明在不读 body 的操作上(find/get/delete)→ publish 拒绝,与cacheTtl于非 GET 同类同判(「声明合法、执行惰性」正是本程序要消灭的状态);inputMapping的 source 域维持 body-only(E5c 已实现的窄读)—— 门无需动作,将来放宽是词表加法。文件面声明(#4604):
packages/spec/src/stack.zod.ts(硬拒收窄为逐端点门)+ 生成物整体重生成(os-regen 四步,spec-changes/upgrade-guide预计移动)+ 门测试 + changeset。升级文档为安全承载件(维护者裁决 2026-08-04):升级指引必须含「审视历史apis:配置、尤其显式authRequired: false条目」的 AI 维护者指令。Generated by Claude Code
feat(spec)!: narrow the `apis:` hard reject to per-endpoint publish g…
fix(metadata,spec): publish 门兜底 —— publishPackage 接门 + 匹配器装载期拒绝 (obje…
test(spec): the first api/ file group's test titles state each cited …