Skip to content

docs(examples): showcase 的 cacheTtl 注释写成 private —— 运行时发的就是它,且它是安全规则 (#5244) - #5395

Merged
baozhoutao merged 2 commits into
mainfrom
claude/issue-5244-showcase-cachettl-comment
Aug 5, 2026
Merged

docs(examples): showcase 的 cacheTtl 注释写成 private —— 运行时发的就是它,且它是安全规则 (#5244)#5395
baozhoutao merged 2 commits into
mainfrom
claude/issue-5244-showcase-cachettl-comment

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Fixes #5244

纯注释修真,零行为变更。改动面只有一个文件的一段注释:
examples/app-showcase/src/system/apis/index.ts(TaskFeedEndpoint.cacheTtl 上方)。

前提复核(按 origin/main 逐条验过)

事实 证据
注释仍写着 public examples/app-showcase/src/system/apis/index.ts:80(改前)
运行时发的是 private packages/runtime/src/endpoint-policy.tscomputeCacheControl:return + 反引号模板 private, max-age=${Math.floor(ttl)}
cacheTtl: 0no-store 同函数:`if (!Number.isFinite(ttl)
private 是安全规则而非调优 同文件 computeCacheControl 上方文档块已成文,并说明它在 authRequired: false 上同样成立

前提成立,且只有 public 这一个词是错的 —— 注释后半句(只随成功答案上线、不随
401/429/5xx、GET-only)本来就对,原样保留。

为什么这一个词值得一个 PR

private 在这条链上是安全规则:任何一条响应都可能按调用者被 RLS 裁剪,共享缓存绝不能
存下来再发给别人。而这份文件是声明式端点唯一的一手示例,是 AI 作者最可能整段抄走的
那份 —— 抄走 public 的作者会顺理成章地推断「共享缓存可以存这条响应」,而这正是该规则
要挡住的推断。

改法(按 issue 口径)

  1. publicprivate;
  2. 带上「不是本示例的调优选择」这半句,并点明它在 authRequired: false 上同样成立
    —— 这是抄走后最容易出的第二层错误推断;
  3. 引用而不复述:把完整规则指向 packages/runtime/src/endpoint-policy.ts
    computeCacheControl 文档块,避免在示例里养出第二套会各自漂移的说法;
  4. 顺带把 cacheTtl: 0 的语义(no-store,而不是「不发头」;「什么都不说」是靠省略这个
    键来表达的)一并指过去 —— issue 让核一下是否值得点一句,这里能自然接在同一句引用后面,
    故点了。

措辞与 endpoint-policy.ts 文档块、以及 content/docs/protocol/kernel/http-protocol.mdx
的口径一致(后者早已写的是 private,showcase 是最后一处 public)。

边界

  • ⛔ 不动运行时、不动声明本身(cacheTtl: 30 是对的)、不动 content/docs/releases/
  • 全仓 grep public, max-age 的其余命中都是真·公共面(OIDC discovery、静态资源、
    marketplace 公共目录),不在本次范围内,也没有发现同类失真。

验证

在专用 worktree 里做的,重活都走 flock /tmp/os-heavy-verify.lock + 4G 堆上限:

pnpm --workspace-concurrency=2 --filter "@objectstack/example-showcase^..." build   # 先建依赖
pnpm --workspace-concurrency=2 --filter @objectstack/example-showcase typecheck
  → tsc --noEmit,零输出零错误
pnpm --workspace-concurrency=2 --filter @objectstack/example-showcase test
  → Test Files 12 passed (12) / Tests 124 passed (124)
node scripts/check-nul-bytes.mjs
  → OK (scanned 5418 tracked text file(s); no raw NUL bytes)

首轮 typecheck 曾整屏 TS2307 Cannot find module '@objectstack/*' —— 是新 worktree 未
建依赖所致(报错无一落在本次改动的文件上),补 ^... build 后转全绿。

changeset

没有加 changeset,请打 skip-changeset 标签。 理由:

随手记

packages/qa/dogfood/test/showcase-declarative-endpoints.dogfood.test.ts:202 这条真实
boot 断言只 toMatch(/max-age=30/),并不钉 private/public 这一位。已按 Prime
Directive #10 另开 observation 单,不在本 PR 修。

🤖 Generated with Claude Code

https://claude.ai/code/session_01VkPSGsX9o17MsGv3Lbxu2w


Generated by Claude Code

…5244)

`examples/app-showcase/src/system/apis/index.ts` 里 `TaskFeedEndpoint.cacheTtl`
上方的注释把响应头写成 `Cache-Control: public, max-age=30`,运行时发的是
`private, max-age=30`(`packages/runtime/src/endpoint-policy.ts` 的
`computeCacheControl`;PR #5230 的真实 boot 探针 P1 也打印了实测值)。

`private` 在这条链上不是调优选择而是安全规则:任何一条响应都可能按调用者被 RLS
裁剪,共享缓存绝不能存下来再发给别人。而这份文件是声明式端点唯一的一手示例,是 AI
作者最可能整段抄走的那份 —— 抄走 `public` 正好得出该规则要挡住的推断。

因此除了把 `public` 改成 `private`,注释还点明它不是本示例的调优选择(在
`authRequired: false` 上同样成立),并**引用** `computeCacheControl` 的文档块而不是
复述第二套规则;顺带把 `cacheTtl: 0` 的语义(`no-store`,不是「不发头」)一并指过去。

注释的后半句(只随成功答案上线、不随 401/429/5xx、GET-only)本来就是对的,保留。

零行为变更:不动运行时,不动声明本身(`cacheTtl: 30` 是对的)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkPSGsX9o17MsGv3Lbxu2w
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 5, 2026 7:23am

Request Review

@github-actions github-actions Bot added the size/s label Aug 5, 2026
@baozhoutao baozhoutao added documentation Improvements or additions to documentation skip-changeset PR has no user-facing published change; bypasses the changeset gate size/s and removed size/s documentation Improvements or additions to documentation labels Aug 5, 2026 — with Claude
自查时发现上一版注释里「the runtime emits it for every ttl」本身就不准:`private`
只出现在正 ttl 上,`cacheTtl: 0` 走的是 `no-store`,并不带 `private`。这正是本 PR 要
消灭的那一类失真,故就地收紧为「every positive ttl」,与紧随其后的 `cacheTtl: 0`
说明自洽。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkPSGsX9o17MsGv3Lbxu2w
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

showcase 端点注释把 cacheTtl 的响应头写成 public, max-age=30 —— 运行时发的是 private,而 private 是安全规则

2 participants