Skip to content

feat(plugin-hono-server): registerStandardEndpoints 默认翻 false —— 便利面改为显式 opt-in(#4073 第一步) - #4280

Merged
os-zhuang merged 2 commits into
mainfrom
claude/vercel-startup-permissions-provider-iwtkqm
Jul 31, 2026
Merged

feat(plugin-hono-server): registerStandardEndpoints 默认翻 false —— 便利面改为显式 opt-in(#4073 第一步)#4280
os-zhuang merged 2 commits into
mainfrom
claude/vercel-startup-permissions-provider-iwtkqm

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

#4073 退役计划的第一正式步。前置拆分(#4144)与证据(#4260)都已合并,本 PR 执行决策:便利面从默认开启改为显式 opt-in。

改了什么

  1. 默认值 truefalse。flag 只覆盖废弃的重复供给面:raw C+R /data/:object + /discovery + /.well-known/objectstack
  2. boot 提示:flag 为 false 且 REST/dispatcher 都没挂时,启动打一条 warn,点名 flag、plugin-hono-server 的 registerStandardEndpoints 把「重复供给」和「独家供给」绑在同一个开关上 —— 拆开是退役的前置条件 #4073 与迁移路径。挂了任一 owner 就完全安静 —— 纯传输组合不会被唠叨。
  3. 默认行为获得自己的 pin 套件(6 例)—— 不搭显式 false 测试的便车。默认值在调用点不可见(本 issue 第一次订正的原话),构造函数 spread 漂移会静默回归,所以单独钉。
  4. flag 标 @deprecated,JSDoc 写明终态。changeset 含完整 FROM → TO。

谁受影响 —— 按「谁依赖默认值」查的,不是「谁传选项」

宿主 影响
os serve(serve.ts:1167,不传 flag) 无变化 —— REST + dispatcher 全挂,#4260 已证两个位置响应逐字节相同
objectstack dev(dev-plugin.ts:386,不传 flag) 无变化 —— 同构组合;仅显式 disable: ['rest','dispatcher'] 的小众配置会变,且会触发 boot 提示
仓库内其余依赖默认值的调用点(逐个查过) server-timing.integration、i18n-wire-dialect、notfound-405、verify harness、auth example —— 都不碰该面
测遗留面本身的三个套件 hono-discovery、hono-anonymous-deny 改为显式 true(它们测的就是这个面);server-timing-e2e 本来就绕过 flag 直调注册器,不动
/me/* 三条 不受影响 —— 从不在此 flag 后面(#4144),无条件注册
外部裸宿主(仓库内为零) 面不再默认挂载;boot warn 给出两条出路:挂 createRestApiPlugin(依赖同一个 objectql,换来完整 CRUD + 全闸门),或显式传 true 用到删除为止

为什么 warn 的静音条件是「挂了 REST 或 dispatcher」

对冲两个方向的错误:裸宿主静默 404(本轮反复付费的失败形状 —— --with-ui 静默回退、CI 绿 harness 死)与composed 宿主被误导去 cargo-cult 一个废弃 flag。6 例 pin 里三例专门钉这个矩阵:裸 boot 恰好一条 warn 且带出路;REST-composed、dispatcher-composed、已 opt-in 三种 boot 零输出。

验证

套件 结果
plugin-hono-server(含 6 例新 pin) 155/155
runtime 挂 hono 的 5 个集成套件(含 #4260 parity) 23/23
client 挂 hono 的 4 个套件 16/16
http-conformance(传 false 的传输契约门禁) 46/46
包内 tsc --noEmit / 改动文件 eslint 0 / 0

终态(不在本 PR)

观察一个 release → 删除 registerDiscoveryAndCrudEndpoints、flag 与三个死优先级常量 —— 插件回归纯传输适配器(ADR-0076 D11),并把这轮沉淀的四条设计规则(一条路由一个 owner;显式组合优于默认魔法;缺席要响亮;机器可读面不许撒谎)补进 AGENTS.md。

关联:#4073(决策记录在案)、#4260(证据)、#4144(前置)、#4018#2567#3298


🤖 Generated with Claude Code

https://claude.ai/code/session_016gEeLZ4oTeSXG6fKG1r3vd


Generated by Claude Code

… — the convenience surface is opt-in (#4073)

The flag mounts raw C+R `/api/v1/data/:object` plus `/api/v1/discovery` /
`/.well-known/objectstack`. Everything it mounts is duplicate — and lesser —
supply: C+R only, a subset of the gates, a pre-`DiscoverySchema` discovery
payload. REST serves full `/data` CRUD behind the whole gate stack, REST/the
dispatcher own discovery (#4018 cede), and #4260 pinned that a composed host
answers BYTE-IDENTICALLY with the flag on or off. The tax was real: #2567,
#3298 and #4018 each re-implemented a platform invariant here after the fact.

Who this changes, checked against who RELIES ON THE DEFAULT (the issue's first
correction), not who passes the option:

- composed hosts — `os serve` (serve.ts:1167), `objectstack dev`
  (dev-plugin.ts:386), every documented path: no change, REST/dispatcher
  already answered first (#4260);
- bare hosts (none in-repo; external unknowns): the surface no longer mounts.
  Boot logs ONE warn naming the flag, #4073 and the remedy — mount
  `createRestApiPlugin` (same `objectql` dependency the raw surface already
  required, full CRUD + gates in return) or opt in explicitly. Absence is loud;
  a silent 404 is the failure shape this whole thread kept paying for. The warn
  stays quiet whenever REST or the dispatcher is mounted, so transport-only
  compositions are not nagged into cargo-culting the flag back;
- `/me/*` — unaffected, never behind this flag (#4144).

The default's behavior gets its own pin suite
(`hono-standard-endpoints-default.test.ts`) rather than riding on the
explicit-`false` tests: defaults are invisible at call sites, so a constructor
drift would otherwise regress silently. Six pins: default mounts nothing of the
surface but keeps `/me/*`; explicit opt-in still works; bare boot warns once
with the remedy; REST-composed, dispatcher-composed and opted-in boots stay
quiet.

Three suites tested the legacy surface THROUGH the default and now opt in
explicitly (hono-discovery, hono-anonymous-deny — server-timing-e2e already
bypassed the flag by calling the registrar directly). The flag is marked
`@deprecated` with the end state in its JSDoc: one release of observation, then
`registerDiscoveryAndCrudEndpoints` and the flag are deleted and this plugin
becomes a pure transport adapter (ADR-0076 D11).

Verified: plugin-hono-server 155/155, runtime hono suites 23/23, client hono
suites 16/16, http-conformance 46/46, package tsc clean, changed-file lint 0.

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

vercel Bot commented Jul 31, 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 31, 2026 2:25am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Jul 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/plugin-hono-server.

6 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/getting-started/your-first-project.mdx (via @objectstack/plugin-hono-server)
  • content/docs/permissions/authentication.mdx (via @objectstack/plugin-hono-server)
  • content/docs/plugins/index.mdx (via @objectstack/plugin-hono-server)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-hono-server)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-hono-server)
  • content/docs/releases/v16.mdx (via @objectstack/plugin-hono-server)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

…in — its /data example needs it

The docs-drift check flagged six docs; five carry no drift (the quickstart runs
`objectstack dev`, a composed stack; plugins/index already describes the hono
plugin as transport; implementation-status already attributes /data to
@objectstack/rest). This one was real, and it is exactly the bare-host shape the
default flip changes: the setup example composes ObjectQL + Driver + Hono + Auth
with no REST, and a later snippet on the same page fetches
`/api/v1/data/task` — which under the new default 404s on that composition.

Fixed the way the changeset's migration path prescribes: mount
`createRestApiPlugin` in the example (full CRUD behind the gate stack, same
`objectql` dependency), NOT `registerStandardEndpoints: true` — docs should not
teach new readers a deprecated flag.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016gEeLZ4oTeSXG6fKG1r3vd
@os-zhuang
os-zhuang marked this pull request as ready for review July 31, 2026 02:38
@os-zhuang
os-zhuang merged commit 623e555 into main Jul 31, 2026
18 checks passed
@os-zhuang
os-zhuang deleted the claude/vercel-startup-permissions-provider-iwtkqm branch July 31, 2026 02:38
os-zhuang pushed a commit that referenced this pull request Jul 31, 2026
…2567 matrix

The drift check flagged nine docs; eight carry none (the quickstart and
authentication ones were settled in #4280, `http-protocol.mdx` entered only via
the CORS change this branch merged from main, and `delegated-administration.mdx`
came along as a same-package sibling with nothing to say about this).

`authorization.mdx` was real, and it is the kind that matters most: it documents
a SECURITY invariant, and it named the deleted surface twice — once in the list
of HTTP surfaces the anonymous-deny decision is uniform across, and once in the
implementation list, as `plugin-hono-server` `denyAnonymous`. Left alone, the
permissions doc would promise a gate on an entry point that no longer exists.

Both now read as history, matching how the same sentence already handles the
retired GraphQL endpoint: the surface LEFT the matrix (v17, #4073) because the
duplicate was deleted, not because it went ungated. The invariant is unchanged —
`shouldDenyAnonymous` still backs REST `/data` and the dispatcher's
metadata/AI paths, and the source-enumerating ratchet still fails CI on a new
ungated surface. It just has one fewer door to hold shut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016gEeLZ4oTeSXG6fKG1r3vd
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