Skip to content

test(runtime): 把「谁在服务 /data 与 /discovery」钉成事实,用证据挡住 #4073 的默认值翻转 - #4192

Merged
os-zhuang merged 1 commit into
mainfrom
claude/vercel-startup-permissions-provider-iwtkqm
Jul 30, 2026
Merged

test(runtime): 把「谁在服务 /data 与 /discovery」钉成事实,用证据挡住 #4073 的默认值翻转#4192
os-zhuang merged 1 commit into
mainfrom
claude/vercel-startup-permissions-provider-iwtkqm

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

#4073 的退役计划是:registerStandardEndpoints 默认翻 false → 观察一个 release → 删除 registerDiscoveryAndCrudEndpoints前置拆分已经完成#4144 把三条 /me/* 挪出了这个门),所以下一步本该是翻默认值。

我去做这一步,先验证它是不是计划所说的 no-op。不是。

实测

真实 HonoServerPlugin + 真实 dispatcher + 真实 createRestApiPlugin,真实监听端口,按 serve.ts 的注册顺序装配:

REST flag GET /api/v1/data/account
ON 401 —— 路由已挂载,#2567 匿名闸门生效
OFF 404 —— 无人接手
ON 401
OFF 404

这个面的两半,性质完全不同:

所以本 PR 只做一件事

不翻默认值。加上说明这一点的测试,断言当前矩阵,让下一次尝试必须正面回应它,而不是重新推导一遍那个假设。无任何生产代码改动。

/data 那两条断言的失败信息直接写了下一步该干什么:

if this is no longer 404, another plugin now serves /data — re-read #4073, the flip may be safe

边界(文件里也写了,免得被过度解读)

REST 在这个 harness 里只配了最小服务集(objectql + auth)。真实 os serve 还有 metadata/protocol 等服务,REST 可能要等这些解析完才挂 /data。所以本 PR 证明的是**「flag 关掉后,这些装配里没有任何东西服务 /data」**,不是「REST 从不服务 /data」。

但这已足以挡住一个假设了相反前提的默认值翻转 —— 而且如果完整供给的 REST 确实会挂上这条路径,那条断言就会失败,那正是该回头重读 #4073 的信号。

这也正是 #4073 自己订正过一次的那类错误("我当时查的是谁传这个选项,没查谁依赖这个默认值")—— 这次是"查的是谁声称提供,没查真实监听器上谁应答"。

关联

#4073#4018(cede 机制)、#2567(匿名闸门,401 的来源)、#4144(前置拆分,已合并)。


🤖 Generated with Claude Code

https://claude.ai/code/session_016gEeLZ4oTeSXG6fKG1r3vd


Generated by Claude Code

…flip on evidence

#4073's retirement plan — flip `registerStandardEndpoints` to `false`, observe a
release, delete `registerDiscoveryAndCrudEndpoints` — rests on the whole surface
being DUPLICATE supply. Booted for real (real HonoServerPlugin + dispatcher +
`createRestApiPlugin`, real listener, `serve.ts` registration order), that holds
for only one half:

  rest=true  flag=ON  → /api/v1/data/account  401  (mounted, #2567 gate fired)
  rest=true  flag=OFF → /api/v1/data/account  404  (nothing serves it)
  rest=false flag=ON  → 401
  rest=false flag=OFF → 404

`/discovery` is the opposite and is safe: it cedes on an explicit
`kernel.hasPlugin(rest|dispatcher)` check (#4018), so the dispatcher's computed
payload answers either way — order-independent, verified both ways here.

`/data/:object` has no such check. Its shadowing was asserted purely on "REST
registers first and wins", and that is not what the listener does. Flipping the
default would turn the path into a 404 rather than handing it to REST.

Narrower than it may read, and the file says so: REST is mounted with a minimal
service set, so this proves "nothing in these compositions serves /data once the
flag is off", not "REST never serves it". That is still enough to block a default
flip that assumes otherwise — and if a fully provisioned REST does mount it, the
assertion that fails is the signal to re-read #4073, which the message says
inline.

No production code changes.

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

vercel Bot commented Jul 30, 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 Jul 30, 2026 2:48pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Jul 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

@os-zhuang
os-zhuang marked this pull request as ready for review July 30, 2026 15:05
@os-zhuang
os-zhuang merged commit d82f8c0 into main Jul 30, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the claude/vercel-startup-permissions-provider-iwtkqm branch July 30, 2026 15:05
os-zhuang added a commit that referenced this pull request Jul 31, 2026
… composed host (#4260)

#4192 (mine) concluded that turning `registerStandardEndpoints` off makes
`/api/v1/data/:object` a 404, and blocked #4073's retirement on it. Wrong, and
wrong in the same shape the issue has already been corrected for twice.

That test mounted `createRestApiPlugin({})` against a STUB `objectql` service.
REST generates its CRUD from the object registry, so it needs a real engine —
driver plus registered objects — and its own `api.api` config. Under-provision it
and it serves nothing; the 404 was a fact about the harness, not about REST.

`packages/client/src/client.environment-scoping.test.ts` had the answer the whole
time: it boots `registerStandardEndpoints: false` and asserts
`GET /api/v1/data/task` → 200, served by REST, with a comment saying that is the
point. Reproducing that provisioning:

  /api/v1/data/task?top=5     flag ON == flag OFF
  /api/v1/discovery           flag ON == flag OFF
  /.well-known/objectstack    flag ON == flag OFF

Byte-identical responses, both halves. The surface is duplicate supply, and the
flip is a no-op for any host mounting REST or the dispatcher — every composed
deployment, `os serve` included.

The test now compares the two positions instead of asserting a status, because a
status is exactly what misled the previous version: `/data/task` answers 404
`OBJECT_NOT_FOUND` — the ENGINE's answer, reached through a working route — where
a routing miss would be `{"error":"Not found"}`. Parity does not depend on telling
those apart, and a separate assertion pins that the compared routes are live so
parity cannot be satisfied by two identical misses.

What this does NOT do is flip the default. That remains a real change for a BARE
host mounting neither, which is the composition the flag was written for — an API
decision, not one a test should make. It is now unblocked and evidenced, which is
what #4192 wrongly denied it.

No production code changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants