发现于 #5673 的实施(界外发现,关键词 + 文件路径查重无命中,故新开)。
现象
/discovery 有两个 生产者,#5673 的裁定只点名了其中一个:
生产者
服务方
NODE_ENV 未设置时 environment
HttpDispatcher.getDiscoveryInfo()(packages/runtime/src/http-dispatcher.ts)
dispatcher-plugin.ts / packages/adapters/hono
production(#5673 已改)
MetadataProtocol.getDiscovery()(packages/metadata-protocol/src/protocol.ts:2900)
packages/rest/src/rest-server.ts:3050
development (未改)
第二个生产者把宿主真实的缺省值原样递给映射函数:
environment : resolveDiscoveryEnvironment (
( globalThis as { process ?: { env ?: Record < string , string | undefined > } } )
. process ?. env ?. NODE_ENV ,
) ,
resolveDiscoveryEnvironment(undefined) 走 typeof raw !== 'string' 分支返回 development(packages/spec/src/api/discovery.zod.ts:341-344),所以经 @objectstack/rest 暴露的 /discovery 在「忘记设 NODE_ENV 的生产部署」上仍然自称 development —— 正是 #5673 判定为危险方向的那一个。
为什么 #5673 没有一并解决
#5673 的 maintainer 裁定(2026-08-06)把落点明确限定在 packages/runtime/src/http-dispatcher.ts,并把 packages/metadata-protocol 标为跨域文件面、要求「若必须改它就 STOP + needs_decision」。派发单进一步禁止改 packages/spec / packages/metadata-protocol。所以 #5673 的 PR 在 runtime 侧就地翻默认,并在注释里如实写明本条残留,而不是悄悄绕过。
两条可能的落点(需要裁定,不要直接猜)
默认收进共享映射函数 —— resolveDiscoveryEnvironment 把「缺省」判为 production,两个生产者都不再各自带默认。契约优先,单点决策,两个 discovery 生产者都在线上返回 schema 未声明的顶层字段(scoping / features / endpoints),且 REST 形状永远无法通过 DiscoverySchema #4828 建这张共享表的初衷就是防两个生产者漂移;代价是动 packages/spec,且要同步改 NODE_ENV_TO_DISCOVERY_ENVIRONMENT 上方那张表格里「unset / anything else → development」那一行(该行现在对 runtime 调用方已经过时)。
只在 metadata-protocol 生产者就地补默认 —— 与 NODE_ENV 未设置时 /discovery 广播 environment=development,而 os start 默认 NODE_ENV=production、CLI doctor 也按 production 解析 #5673 的做法对称,不动 spec;代价是同一个「缺省语义」在仓里有两处副本,正是共享表要防的漂移。
倾向 1(单点决策、契约优先、AI 写元数据时不给消费方留宽容分支),但落点跨域,交 maintainer 裁。
附带的文档面漂移(同一处,顺带记录)
packages/spec/src/api/discovery.zod.ts 映射表上方注释仍写:
| unset / anything else | development | preserves the pre-existing getEnv('NODE_ENV', 'development') default…
#5673 之后 runtime 调用方已不再传该默认,这句话对映射函数自身仍为真、对调用方已不为真。无论走上面哪条路,这行都要一起改。
参考:#5673 (runtime 侧 + doctor 提示行)、#4828 (枚举映射的由来)、Prime Directive #9 (NODE_ENV 是第三方边界上的既有例外)。
发现于 #5673 的实施(界外发现,关键词 + 文件路径查重无命中,故新开)。
现象
/discovery有两个生产者,#5673 的裁定只点名了其中一个:NODE_ENV未设置时environmentHttpDispatcher.getDiscoveryInfo()(packages/runtime/src/http-dispatcher.ts)dispatcher-plugin.ts/packages/adapters/honoproduction(#5673 已改)MetadataProtocol.getDiscovery()(packages/metadata-protocol/src/protocol.ts:2900)packages/rest/src/rest-server.ts:3050development(未改)第二个生产者把宿主真实的缺省值原样递给映射函数:
resolveDiscoveryEnvironment(undefined)走typeof raw !== 'string'分支返回development(packages/spec/src/api/discovery.zod.ts:341-344),所以经@objectstack/rest暴露的/discovery在「忘记设 NODE_ENV 的生产部署」上仍然自称development—— 正是 #5673 判定为危险方向的那一个。为什么 #5673 没有一并解决
#5673 的 maintainer 裁定(2026-08-06)把落点明确限定在
packages/runtime/src/http-dispatcher.ts,并把packages/metadata-protocol标为跨域文件面、要求「若必须改它就 STOP + needs_decision」。派发单进一步禁止改packages/spec/packages/metadata-protocol。所以 #5673 的 PR 在 runtime 侧就地翻默认,并在注释里如实写明本条残留,而不是悄悄绕过。两条可能的落点(需要裁定,不要直接猜)
resolveDiscoveryEnvironment把「缺省」判为production,两个生产者都不再各自带默认。契约优先,单点决策,两个 discovery 生产者都在线上返回 schema 未声明的顶层字段(scoping / features / endpoints),且 REST 形状永远无法通过 DiscoverySchema #4828 建这张共享表的初衷就是防两个生产者漂移;代价是动packages/spec,且要同步改NODE_ENV_TO_DISCOVERY_ENVIRONMENT上方那张表格里「unset / anything else → development」那一行(该行现在对 runtime 调用方已经过时)。倾向 1(单点决策、契约优先、AI 写元数据时不给消费方留宽容分支),但落点跨域,交 maintainer 裁。
附带的文档面漂移(同一处,顺带记录)
packages/spec/src/api/discovery.zod.ts映射表上方注释仍写:#5673 之后 runtime 调用方已不再传该默认,这句话对映射函数自身仍为真、对调用方已不为真。无论走上面哪条路,这行都要一起改。
参考:#5673(runtime 侧 + doctor 提示行)、#4828(枚举映射的由来)、Prime Directive #9(
NODE_ENV是第三方边界上的既有例外)。