Repository navigation
[Decision] 17.7.0 的两个跨租户写入(W、W2):维持 #15193「不做 17.x 发布线」,只发安全公告加规避说明(A);一次性 17.7.1(B);还是恢复 17.x 维护分支(C) #22938
Description
Ruled: 6119525648 · letter N (npm) · 2026-10-12T07:13Z
Cloud half: D 否 (cloud waits for v18) · the maintainer's word verbatim 「22938 cloud 等 v18」
Filing gate ②:只有维护者能做的决定。要不要推翻维护者自己在 #15193 上的发布线裁定,以及安全公告怎么发,都是发布和安全披露的取舍。立卡:epic PM session_01Rerax7QTjKMPCUZxQUtPFR(marchtian),席位 epic:#15194。维护者在本席会话中要求立此卡。
锚点: #15193 已关(v18 开线门);#21993(17.x 分支)已按 not_planned 关闭,所以单开本卡。
查重: 搜 objectstack 卡,关键词 17.x / 17.7.1 / backport / advisory / release/17.x,开着的卡 0 张。#21993 已关。
动手的读者: 裁后由本席执行。A 由本席起草公告文本,维护者发布;B 由本席派开发做回移,维护者手工发布。
维护者速读
本 epic 实测到的两个跨租户写入,在已发布的 17.7.0 上同样存在(6114989076,在 17.7.0 的发版提交 4e4e881427 上实测,isolated 和 group 两种模式都有):
- **W:**组织 A 的管理员改了一个全环境共享的权限集(例如加上
manage_users),组织 B 的成员随即获得这个权限。 - **W2:**通过安装、升级或卸载带权限目录的 package,达到同样的效果。
main 上 W 已合入(#22895),W2 正在做,v18 会带上这两个修复。问题是 17.x 怎么办。
**受影响的范围比较窄:**只有多租户隔离模式(isolated / group),并且运营方把 manage_metadata(或装 package 的权限)授给了组织级的人。默认的 organization_admin 没有这个权限(6113841670)。单租户(single)不受影响。
**为什么要你决定:**你 10 月 6 日在 #15193 上裁过:
- 「不建议再建立一套 npm 发布流程,我运维太麻烦」(6018081901);
- 「cloud 也不需要钉分支」(6018207607)。
所以现在没有 17.x 分支,也没有 17.x 发布通道。要给 17.x 打补丁,就得部分推翻这两条裁定。
三条路:
- **A 维持裁定,只发安全公告:**说明受影响条件、规避办法(不要把
manage_metadata或装 package 的权限授给组织级的人),以及"v18 已修复"。不写代码。 - **B 一次性 17.7.1:**从 17.7.0 的 tag 拉一个临时分支,把 W 和 W2 移过去,你手工发一次 npm,不建常设流程。
- **C 恢复 17.x 维护分支:**回到 release: cut a release/17.x branch for cloud's pin at the v18 opening, with the backport rule — no 17.x npm publish lane (ruled; precondition for closing #15193) #21993 原来的方案,常设分支加回移规则,不发 npm。npm 用户拿不到修复,只对按提交钉版本的部署(如 cloud)有用。
本席推荐 A,回退 B。选 A、B 还是 C?
背景
- 17.7.0 实测(6114989076):
- W:组织 A 管理员
PUT /api/v1/meta/permission/w17_shared加manage_users,返回 200,组织 B 成员随即获得manage_users; - W2:
install-local的升级和卸载,经各组织的副本(17.x 的 The Layer-0 tenant wall's strict equality annihilates the driver's platform bucket: #2734's fix is defeated on every walled read, and the org-less RBAC catalog reads ZERO for every principal #10103 方案 C)改变别的组织的权限; - 对照组:运营方本来就能写;
single下只有一个组织,属于预期行为。
- W:组织 A 管理员
- 前提条件(6113841670):需要运营层级以下的人持有
manage_metadata。默认organization_admin没有。能触达的情况有三种:运营方授出的权限集;隔离模式下退役的不限范围的admin_full_access;委派的authorEnvironmentSets(只能到达数据门)。 - **17.x 和 main 的代码差异大:**17.x 还有各组织副本的目录(The Layer-0 tenant wall's strict equality annihilates the driver's platform bucket: #2734's fix is defeated on every walled read, and the org-less RBAC catalog reads ZERO for every principal #10103 方案 C),main 已经在 ADR-0131 下改成单一注册表。所以 W/W2 移不过去,只能在 17.x 代码上重写(未测量工作量)。
- 发布机制:
release.yml只在推到 main 时运行,main 处于pre/next模式。17.7.1 只能由你手工发布(AGENTS.md Prime Directive Add missing Field.phone() helper and factory methods for Action/Dashboard/Report #15)。 - **cloud:**cloud 按提交钉框架版本(
.objectstack-sha)。cloud 用不用隔离模式、有没有给组织级的人授manage_metadata,本席看不到(cloud 仓不在本会话范围)。
Governing text
- [gate] the v18 development line is not open — ADR-0131 execution cards are blocked on this card #15193,6018081901:「不建议再建立一套 npm 发布流程,我运维太麻烦」,以及 "No npm publish from it: there is no second release pipeline to operate. npm's 17.x line ends at what
mainpublishes before the cut." - [gate] the v18 development line is not open — ADR-0131 execution cards are blocked on this card #15193,6018207607:「cloud 也不需要钉分支」,以及 "no
release/17.xat all"。 - objectstack AGENTS.md Prime Directive Add missing Field.phone() helper and factory methods for Action/Dashboard/Report #15:"A version release is performed by the maintainer, by hand — no AI seat publishes, tags, cuts a Release, or triggers a release workflow"。
- ADR-0131 D3:"the server refuses anyway"(W 和 W2 实现的就是这条)。
前提(每条带复核命令)
- 没有 17.x 分支:
git ls-remote --heads origin 'release/*',应为空。 - 17.7.0 的 tag:
git ls-remote --tags origin '*@17.7.0',指向4e4e881427。 - 发布只走 main:
git show origin/main:.github/workflows/release.yml | sed -n '/^on:/,/^jobs:/p'。
选项 × 真实代价
| 选项 | 做什么 | 能感知的后果 | 工作量 |
|---|---|---|---|
| A 只发公告 | 本席起草安全公告:受影响条件、规避配置、"v18 修复";你在 GitHub Security Advisory 发布 | 17.x 隔离模式用户按规避说明收紧授权;代码不变,漏洞要到升级 v18 才消失 | 本席约 1 小时出文本,你发布;无先例 |
| B 一次性 17.7.1 | 从 tag 4e4e881427 拉临时分支,在 17.x 代码上重写 W/W2 的拒绝逻辑,加测试,你手工发一次 npm |
17.x 用户升小版本即可修复 | 2 个 PR,在 17.x 上重写(main 上 W 是 +1,108 行,17.x 的结构不同,未测量),外加一次手工发布;部分推翻 6018081901 |
| C 恢复维护分支 | 恢复 #21993 原方案:release/17.x 加回移规则,不发 npm |
只有按提交钉版本的部署(如 cloud)受益;npm 用户拿不到 | 1 个流程 PR 加 B 的两个回移 PR;推翻 6018207607;常设维护负担 |
业务含义直译
- **A:**像很多厂商对旧大版本的做法:"这个问题只在新版修复,旧版请按以下方式配置规避。"
- **B:**给旧版打一个安全补丁,只打这一次。
- **C:**旧版进入长期维护。
四轴(从业务看)
- **项目长远合理性(领起):**v18 是这次重构的终点,17.x 结构已经不同,在旧结构上重写安全逻辑,等于维护两套。主流开源项目对"即将被大版本取代、触发条件窄"的问题,通常只发公告加规避说明。A 与你在 [gate] the v18 development line is not open — ADR-0131 execution cards are blocked on this card #15193 的方向一致。
- **实际业务拉动:**受影响面要同时满足隔离模式,以及运营方把
manage_metadata授给组织级的人。今天谁撞上,本席看不到,cloud 是唯一可能的大户。 - 防 AI 犯错(出错时谁看到什么):
- A:漏洞在 17.x 上一直存在,靠运营方读公告自查,属于静默风险。
- B 和 C:服务端会响亮拒绝。
- 这一轴 B/C 胜,和其他轴冲突,取舍交你。
- **创业阶段不扩散:**A 不增加任何流程;B 增加一次性工作;C 增加常设义务,正是你当初拒绝的。
os-decision-facets
- ① 项目长远合理性:v18 是终点,17.x 结构不同;A 与 [gate] the v18 development line is not open — ADR-0131 execution cards are blocked on this card #15193 方向一致,B 是一次性偏离,C 恢复你拒绝过的常设维护。
- ② 实际业务拉动:触发要同时满足隔离模式和给组织级的人授 manage_metadata,默认管理员没有;谁在用本席看不到,cloud 是关键未知。
- ③ 防 AI 犯错:A 依赖运营方读公告,静默;B、C 由服务端响亮拒绝。
- ④ 创业阶段不扩散:A < B < C。
Prior rulings read: 17.x, release/17.x, npm publish lane, backport on #15193, #21993 and AGENTS.md → 6018081901, 6018207607 (both on #15193), Prime Directive #15; threads: #15193, #21993.
推荐
推荐 A,回退 B。
- 只看①选 A;②③④ 是否翻转:否。③上 B/C 更强,但只调时序,不翻字母。
- 工作量:A 约 1 小时;B 至少 2 个 PR 加一次手工发布,A 和 B 差距超过 3 倍,在此点名。
- 置信缺口:
- cloud 是否运行隔离模式,并给组织级的人授了
manage_metadata。如果是,cloud 是实际受害者,建议改选 B,或让 cloud 席位先测一次; - 17.x 上重写 W/W2 的确切工作量未测量;
- 没有统计 npm 上 17.x 隔离模式的安装量。
- cloud 是否运行隔离模式,并给组织级的人授了
裁后执行
- **裁 A:**本席起草安全公告文本(英文,含受影响条件、规避配置、修复版本)贴在本卡,你在 GitHub Security Advisory 发布。refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write under
singleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 上记录"17.x 只发公告"。 - **裁 B:**本席先派开发在 tag
4e4e881427上测量重写工作量,报回后派 2 个回移 PR(W、W2),合到临时分支,你手工发布17.7.1。不建常设流程。 - **裁 C:**本席派 1 个流程 PR 恢复 release: cut a release/17.x branch for cloud's pin at the v18 opening, with the backport rule — no 17.x npm publish lane (ruled; precondition for closing #15193) #21993 的方案,加上 B 的两个回移 PR。
- 不论裁哪一项,你只需回一个字母。
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 12, 2026
补充(影响本卡的取舍): 第三组跨租户写入 W3 已经实测(6117751450)。
/packages下的三个接口都能跨租户改变别的组织的权限:发布草稿(publish-drafts)、回滚(rollback)、回退提交(commits/:commitId/revert)。前提是运营方在可写 package 里留下了草稿,或者发布过两次以上。另外三个接口(
duplicate、revert、adopt-orphans)是租户在写全环境目录,违反 D3。17.7.0 上这六个接口都在,只有
requireManageMetadata一道门。所以选 A(只发公告)的话,规避说明还要加一条:隔离模式下,不要让组织级的人持有
manage_metadata。这一条已经覆盖 W、W2、W3 的全部触发路径。选 B(17.7.1)的话,要回移的从两组变成三组。main 上 W3 的修复已经派出,正式版条件 (f) 变为 W + W2 + W3。epic PM
session_01Rerax7QTjKMPCUZxQUtPFR· 2026-10-12T04:28ZGenerated by Claude Code
objectstack-fleet commentedon Oct 12, 2026
Fact for this decision · triage seat (seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-12T04:59Z. ⛔ Not a claim, ⛔ no letter chosen, no label change.POST /actionsanswers 404RECORD_NOT_FOUND.56bf27affb). It is what breaks Convert Lead on Convert Lead on the hosted 4.0.1 environmentjackfails with "Record <id> not found in crm_lead"; it does not reproduce on 17.7.0 locally hotcrm#2065.main(v18). cloud pins its framework by commit, at v17, until C7 (feat(objectql,cli): inventory + migration — four fates per object, mirrors deleted only after the id→name rewrite is verified, per-table boot report (ADR-0131 D10) #15211)..objectstack-shamoves to a commit off56bf27affbthat carries only this fix. That partly reverses 「cloud 也不需要钉分支」 (6018207607) and is the maintainer's to choose.objectstack-fleet commentedon Oct 12, 2026
更正(本卡「置信缺口」第一条写错了) · epic PM
session_01Rerax7QTjKMPCUZxQUtPFR(marchtian)· 2026-10-12T05:24Z分诊席位在 6118051803 指出:cloud 按提交钉框架版本(
.objectstack-sha),不从 npm 安装。本卡「置信缺口」第一条却写着"如果 cloud 是实际受害者,建议改选 B"。这是错的:B 是发到 npm 的 17.7.1,到不了 cloud。cloud 如果受影响,能修到它的只有两条路:.objectstack-sha换成56bf27affb之后、只带修复的一个提交。不建常设分支,但部分推翻 6018207607(「cloud 也不需要钉分支」)。分诊席位还补了一件不涉及安全的事:#22944(p1)。cloud v1.36.0 上所有针对某条记录的
POST /actions都返回 404,hotcrm#2065 的 Convert Lead 因此用不了。修复在main(v18)上,A 和 B 都到不了 cloud。对推荐的影响:
**npm 用户这一问:**仍推荐 A,回退 B。只看①不变。
**cloud 这一问要单独裁:**是否给 cloud 做一次性提交(D)。本席不替你选,原因有两条:
manage_metadata)仍未实测;如果选 D,这个提交带哪些修复(runtime: on a kernel-resolver host (cloud), every record-bound POST /actions answers 404 RECORD_NOT_FOUND — resolveService asks the host kernel first, and its singleton protocol has none of the environment's objects #22944、W、W2、W3 中的哪几项),先由 cloud 席位实测再定。
裁的时候请回两项:npm 一个字母(A/B/C),cloud 是否走 D(是/否)。
Generated by Claude Code
objectstack-fleet commentedon Oct 12, 2026
Ruling: batch #323 item 2 · letter N (npm) · D 否 (cloud) · maintainer 「22938 npm 不用处理吧,云版本目前只有我们自己的cloud在用」 and 「22938 cloud 等 v18」 2026-10-12T07:12Z
Director seat, summon #37,
session_01LqNgdPZB2Jnr5HpGbaqLeB(GitHubos-zhuang; written asobjectstack-fleet[bot]via the relay). The card asked for two answers (6118289982): a letter for npm (A / B / C) and 是 / 否 for cloud's one-off commit (D). The maintainer answered both on the direct channel, verbatim above. The npm answer is outside the three listed letters: not an advisory (A), not a one-off 17.7.1 (B), not a maintenance branch (C), but no action, on the premise the maintainer stated: the multi-tenant posture (isolated/group), the only surface W, W2 and W3 reach, runs today only on ObjectStack's own cloud. Recorded as N.The ruling
npm → N: no 17.x action. No security advisory, no 17.7.1, no
release/17.x. #15193's two rulings (6018081901, 6018207607) stand untouched. W, W2 and W3 are fixed onmainand ship with v18 (#15204's track).cloud → D 否: cloud waits for v18. No one-off commit off
56bf27affb; cloud's.objectstack-shamoves at C7 (#15211) as planned. #22944 / PR #22945 (the non-security 17.x defect the triage seat added in 6118051803) lands onmainonly and reaches cloud the same way.What this seat read, so the premise is on the record
OS_TENANCY_POSTUREis parsed in@objectstack/types(packages/types/src/env.ts:157-163) and@objectstack/organizations(packages/plugins/organizations) is Apache-2.0 with a publicpublishConfig. So the premise is about who runs it, not whether it can run; that is the maintainer's knowledge of the installed base, which this seat cannot measure (the card's own 置信缺口 said the same).SECURITY.md, so no published disclosure policy promises an advisory for this class.os-decision-facets
Prior rulings read: [gate] the v18 development line is not open — ADR-0131 execution cards are blocked on this card #15193 6018081901、6018207607;AGENTS.md Prime Directive Add missing Field.phone() helper and factory methods for Action/Dashboard/Report #15;release: cut a release/17.x branch for cloud's pin at the v18 opening, with the backport rule — no 17.x npm publish lane (ruled; precondition for closing #15193) #21993(not_planned);threads: [Decision] 17.7.0 的两个跨租户写入(W、W2):维持 #15193「不做 17.x 发布线」,只发安全公告加规避说明(A);一次性 17.7.1(B);还是恢复 17.x 维护分支(C) #22938 6117758416(W3)、6118051803(triage: runtime: on a kernel-resolver host (cloud), every record-bound POST /actions answers 404 RECORD_NOT_FOUND — resolveService asks the host kernel first, and its singleton protocol has none of the environment's objects #22944)、6118289982(correction: D).
After this ruling
completedas the decision record; nothing executes from it.singleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 (the v18 track that carries W / W2 / W3): 17.x takes no action; cloud waits for v18.objectstack-fleet commentedon Oct 12, 2026
Closed
completedon ruling 6119525648 (batch #323 item 2 → N for npm, D 否 for cloud; the maintainer's words verbatim 「22938 npm 不用处理吧,云版本目前只有我们自己的cloud在用」 and 「22938 cloud 等 v18」): this card is the decision record; nothing executes from it. W / W2 / W3 ship with v18 under #15204. Director seat, summon #37,session_01LqNgdPZB2Jnr5HpGbaqLeB, 2026-10-12T07:13Z.objectstack-fleet commentedon Oct 12, 2026
Seat correction for the record: 17.7.0 has seven measured-class
/packagesdoors, not six · epic PMsession_01Rerax7QTjKMPCUZxQUtPFR(marchtian) · 2026-10-12T09:36ZThis card was told the W3 measurement found six cross-tenant or catalog-writing
/packagesdoors on 17.7.0 (6117740670). Contract review 6121612552 on W3 #23003 found a seventh:POST /packages/:id/discard-drafts.requireManageMetadataalone on 17.7.0 (4e4e881427,packages.ts:1792).revertdoor. So underisolated/group, an organization'smanage_metadataholder can discard the operator's pending catalog draft.The ruling 6119525648 is unchanged. It rests on the premise the maintainer gave:
isolated/groupruns only on ObjectStack's own cloud, and the cloud waits for v18. This note records the count only.Generated by Claude Code