发现于 #5244(showcase 注释把 cacheTtl 的响应头写成 public)的实现过程。观察类,今天没有用户会踩到,只是一处可收紧的断言,记下来交 PM 分诊。
事实
packages/qa/dogfood/test/showcase-declarative-endpoints.dogfood.test.ts:202:
expect(res.headers.get('cache-control'), 'cacheTtl: 30 must reach the wire').toMatch(/max-age=30/);
这条断言只钉 max-age=30 这一半,不钉 private / public 这一位。也就是说:如果哪天运行时把
private 翻成 public,这条真实 boot 断言仍然是绿的。
而 private 在这条链上不是调优选择而是安全规则(packages/runtime/src/endpoint-policy.ts
的 computeCacheControl 文档块成文):任何一条响应都可能按调用者被 RLS 裁剪,共享缓存绝不能
存下来再发给别人。被漏钉的恰好是这条链上唯一有安全含义的那一位。
为什么仍然只算观察类,而不是缺陷
private 在下面三处是钉死的,真翻成 public 会被逮到:
packages/runtime/src/endpoint-policy.test.ts:312、:316、:331
packages/runtime/src/api-endpoint-step.test.ts:349、:522
packages/runtime/src/dispatcher-plugin.endpoint-fallback.integration.test.ts:499
(这条查的是真实 Response 头)
所以这不是一个没人守的洞,而是唯一一层观察真实 boot wire 的断言比它下面几层松。收紧它的
价值在于:单测钉的是 computeCacheControl 的返回值,dogfood 钉的是「整条栈跑完之后真正发出去
的东西」—— 中间任何一层若改写了这个头,只有 dogfood 这层看得见,而它现在看不见这一位。
修法(一行)
.toMatch(/^private, max-age=30$/)
或至少 toContain('private')。同文件 :213 那条「错误答案不得带缓存指令」的断言是对的,不用动。
边界
发现于 #5244(showcase 注释把
cacheTtl的响应头写成public)的实现过程。观察类,今天没有用户会踩到,只是一处可收紧的断言,记下来交 PM 分诊。事实
packages/qa/dogfood/test/showcase-declarative-endpoints.dogfood.test.ts:202:这条断言只钉
max-age=30这一半,不钉private/public这一位。也就是说:如果哪天运行时把private翻成public,这条真实 boot 断言仍然是绿的。而
private在这条链上不是调优选择而是安全规则(packages/runtime/src/endpoint-policy.ts的
computeCacheControl文档块成文):任何一条响应都可能按调用者被 RLS 裁剪,共享缓存绝不能存下来再发给别人。被漏钉的恰好是这条链上唯一有安全含义的那一位。
为什么仍然只算观察类,而不是缺陷
private在下面三处是钉死的,真翻成public会被逮到:packages/runtime/src/endpoint-policy.test.ts:312、:316、:331packages/runtime/src/api-endpoint-step.test.ts:349、:522packages/runtime/src/dispatcher-plugin.endpoint-fallback.integration.test.ts:499(这条查的是真实
Response头)所以这不是一个没人守的洞,而是唯一一层观察真实 boot wire 的断言比它下面几层松。收紧它的
价值在于:单测钉的是
computeCacheControl的返回值,dogfood 钉的是「整条栈跑完之后真正发出去的东西」—— 中间任何一层若改写了这个头,只有 dogfood 这层看得见,而它现在看不见这一位。
修法(一行)
或至少
toContain('private')。同文件:213那条「错误答案不得带缓存指令」的断言是对的,不用动。边界
cacheTtl的响应头写成public, max-age=30—— 运行时发的是private,而private是安全规则 #5244 不相交:showcase 端点注释把cacheTtl的响应头写成public, max-age=30—— 运行时发的是private,而private是安全规则 #5244 的完成面是examples/app-showcase的一段注释(PR docs(examples): showcase 的 cacheTtl 注释写成 private —— 运行时发的就是它,且它是安全规则 (#5244) #5395),改不到 qa/dogfood;故独立立单而非挂作其子单。