Skip to content

#4463 运行时发布门在 host-config 拓扑(environmentId 未绑定)上整体不跑——#5086 只把 code-only 拒绝移出了同一条短路 #6710

Description

@os-zhuang

观察到的缺口

ObjectStackProtocolImplementation.assertRuntimeAuthoringRules(packages/metadata-protocol/src/protocol.ts,#4463 的运行时发布门)第一行是:

if (this.environmentId === undefined) return;

这条短路本身是既有设计且正确——它是 ADR-0005「控制面 / 包作者自有通道」的 carve-out,与其下方 #3050 authoring gate 的 if (this.environmentId !== undefined) 同一口径,protocol.runtime-authoring-gate.test.ts 也把它作为刻意行为钉住。本单不是要求撤掉它。

问题在于 environmentId === undefined不只意味着控制面内核。#5086 在同一文件里(saveMetaItem 的 code-only 拒绝块注释)留下的原话即是证据:

「…the premise the carve-out rests on ("this kernel is the package author's own bootstrap channel") is simply not true for the CLI's lightweight assembler: a host config with instantiated plugins (isHostConfigshouldBootWithLibrary === false) boots new ObjectQLPlugin() with NO environmentId, so the flagship showcase — a self-hosted app server whose PUT /api/v1/meta/* is an END-USER surface — ran with this entire gate disengaged.」

#5086 据此把 code-only 类型的拒绝移出了 environmentId 门(「Keying authorization off a row-scoping key is what made a type-level declaration depend on deployment topology; the declaration decides it here instead」),但只移了那一处#4463 的运行时发布门(共享 AUTHORING_RULES 的 26 条规则)仍留在短路后面。

于是在 host-config 拓扑上,PUT /api/v1/meta/* 这个终端用户面上一条作者时规则都不跑——而 #4463 立单的理由恰恰是「对 Studio 租户 / MCP-AI 作者来说这不是四道门里较弱的一道,而是唯一的一道」。

现状核验(本单只测了这些,未测的如实标出)

已实测:每条常规服务路径都绑定 environmentId,所以它们照常进门——

路径 environmentId 位置
os dev env_local(默认) packages/cli/src/commands/dev.ts:225
os start env_local(默认) packages/cli/src/commands/start.ts:197
standalone artifact stack proj_local(默认) packages/runtime/src/standalone-stack.ts:378
cloud 单项目内核 各自项目 id packages/objectql/src/plugin.ts:295

未实测:host-config 拓扑今天是否仍会走到无 environmentId 的装配。仓内有两处形状可疑——packages/cli/src/commands/serve.ts:1000config.objects && !hasObjectQL 自动注册分支(new ObjectQLPlugin(),无 environmentId),以及任何 objectstack.config.ts 里手写 plugins: [new ObjectQLPlugin()] 的 host。上面引的注释是 #5086 当时的测量,不是我这轮的复测。定级前应先复现这一条:若该拓扑已随其它改动消失,本单可直接关掉;若仍在,则是一个终端用户面上的门整体失效。

为什么单独立单

发现于 #6285(PR #6708)。该单的 dispatch 明确要求「若短路使护栏在关键部署形态不可达,STOP 上报,⛔ 不得擅自拓宽 gate 激活面」。核验结论是本护栏可达(多组织部署都在上表的路径上),所以 #6285 按裁决正常落地、未动激活面。但拓宽与否会同时改变全部 26 条共享规则的影响面,是独立的契约决定,不该搭在一个护栏单里顺手做。

可能的方向(不预判,留给分诊/维护者)

  1. metadata: allowRuntimeCreate:false is not enforced — PUT /meta creates job and agent items the registry declares code-only #5086 的思路,把门的激活environmentId(一个行作用域键)改为按拓扑/来源判定,让「包作者自有通道」这个真实意图有一个自己的表达,而不是借用 environmentId;
  2. 维持现状,但把「host-config 拓扑无 environmentId」本身当缺陷修掉(让该装配也绑一个 environmentId),这样短路的前提重新成立;
  3. 若复现不出该拓扑,关单。

Refs:#4463(门的立单与四项裁决)、#5086(同一前提的上一次修补,只移了 code-only 一处)、#6285 / PR #6708(本次核验的来处)、#6602(同族:另一处只按 environmentId 而不按 org 把关的 seam)。


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions