Repository navigation
design: a THIRD tenancy state the 批 #9 re-ruling cannot express — objects that are CONDITIONALLY tenant-scoped, where org-less is a property of the ROW, not the object #13636
Description
Activity
- addedpriority:p1High: required for production / M2High: required for production / M2
on Aug 31, 2026 Triage:
needs-user-decision+domain:engine(resolveSystemInsertOrganization)+ typeFeature+priority:p1+security。人工地板双重命中(安全/权限边界 · 新增运行时能力)⇒ 恒交维护者。立卡席位「PM adds no preference」的自我约束正确,分诊同判。p1 的依据不是这两个对象坏了,而是控制面的覆盖率:卡的这句是决定性的 ——
"the objects most worth auditing are exactly the ones the control cannot reach."
sys_metadata与sys_audit_log是平台命名空间里写入量最大的两个;把它们永久留在 unclassified,租户审计控制就在它最该覆盖的地方失明。⇒ 这不是分类学争论,是控制的有效性。四棱分析
立卡席位已沿四条轴给过 B 的理由(business need / long-term soundness / hard to get wrong / scope discipline)。分诊不重抄,只补各棱上它没说的那半,并给出分歧点。
棱 读数 实际业务需求 ⭐ 拉动实测:两个标本各自背后都有一条在案裁决支撑其 org-less 行 —— sys_metadata依 #6190 option A(不可覆盖类型的写落在 env 级),sys_audit_log的写入方枚举了合法 org-less 情形(如对一个根本没有 organization 列的对象所记的审计)。⇒ 这些不是遗留脏数据,是被裁定过的正确行为。⚠️ 但类的规模未测 —— 卡明确警告 ⛔ 不要把 #13491 清单里的 51 读成类的大小。项目长远合理性 ⭐ 指向 B。contract-first 的标准形状:合法情形应当被声明,而不是从一个 NULL里推断。卡对根因的表述最干净:今天同一个NULL同时意味着「有意」和「bug」 —— 这正是控制无法区分它们的原因,也正是「声明即强制」要消灭的形状。防 AI 写错 ⭐⭐ 本棱最强,且它给 B 加了一个必需件。当前形状要求每一个未来的写入方知道一条没有写下来的规则(哪些行可以合法 org-less)。B 把它变成 review 期可检查的显式声明。 ⚠️ 但只有当声明是响亮、可检查、可计数的才成立 —— 若 B 落成一个静默的可选标记,它就只是给旁路换了个名字,防错收益归零。⇒ 若裁 B,「loud, checkable, countable」三个词必须进裁决正文,不是实现细节。创业阶段不扩散需求 ⚠️ 本棱是唯一反对 B 的,分诊把它讲明(立卡席位把它写成「scope discipline」,偏中性)。B 是新增运行时能力,创业阶段默认从紧。反方案 A(维持 unclassified)是零成本且诚实的,它今天就在生效。⇒ 真正的问题是:租户审计控制现在是不是关键路径? 若是,A 的代价(最大写入面永久失明)不可接受;若还不是,B 可以等。这一问只有维护者能答,它决定 A 与 B 之间的选择。推荐:B,但把裁决条件写死 —— 若采纳 B,声明必须响亮、可检查、可计数(见防错棱),且先测类的规模再实现(⛔ 不要在 51 个 cannot-determine 里凭猜挑成员)。若维护者判定租户审计控制尚不在关键路径上,A 是自洽的,分诊不反对,但那时应在控制的文档里写明它的已知盲区,⛔ 不要让下一个人以为覆盖是全的。
⛔ C(在门口按写入拆分) 分诊建议排除:它把一个分类问题变成两条代码路径,而两条路径正是本仓元判据②要消灭的形状(同一操作两个实现 ⇒ 带治理的一侧胜出)。若要选 C,须在裁决正文说明为什么它不落入该判据。
⚠️ 四棱不同向(不扩散棱反对)+ 人工地板双命中 ⇒ ⛔ 绝不适用代裁。
Generated by Claude Code
huangyiirene commented
on Aug 31, 2026 CollaboratorMore actions⚖️ 裁决记录 — B:给写入面一个显式的「合法 org-less」申报,然后把条件对象收编
出处:维护者 2026-08-31,live PM chat,总监席第 7 场决裁批 #17,逐字:「同意」(对本批按呈报推荐整体放行;本卡呈报推荐为 B 窄形起步)。录裁:director seat, session
session_01KGtaLpkW1mycWgkbSb3H6t。裁定内容(分诊 2026-08-31 补充评论要求的条件,全部写入裁决正文)
- 方向 = B:平台获得一个显式的每写入「合法 org-less」申报通道,
resolveSystemInsertOrganization据此区分「有意的环境级/无租户行」与「漏 stamp 的 bug」。同一个 NULL 不再身兼两义。 - 申报必须 loud, checkable, countable(分诊防错棱的必需件,三词入裁不入实现细节):静默可选标记不合格 —— 那只是给旁路换名。申报要在 review 期可读、可被门禁清点、可出计数读数。
- 先测类的规模,再实现:首批只收编两只已裁标本 ——
sys_metadata(org 作用域的 flow overlay 只在「本进程内发布后」绑定触发器,重启后静默失绑——冷启动两条读路径都把 organization_id 非空的行滤掉了 #6190 option A 的环境级写)与sys_audit_log(其写入方枚举的合法情形);⛔ 不从 design:isSystem写入是否在租户审计控制范围内?——#13178 类级装置(A/B/C)的共同前置,从未被裁过 #13491 的 51 只 cannot-determine 里凭猜挑成员,每只后续对象的收编都要带自己的写入方证据。 - ⛔ C(按写入拆门)排除,依据元判据②:同一操作两条代码路径正是「带治理一侧胜出」要消灭的形状。
- A(维持 unclassified)作为被拒选项记录在案:其代价 —— 命名空间最大写入面对租户审计控制永久失明 —— 被判为不可接受,即租户审计控制在关键路径上(分诊第四棱问句的答案)。
状态转移(同笔)
needs-user-decision→pm:queue(domain:engine;Feature,已裁 —— 设计方向定,实现按上列五条约束派发;条款②按实际 diff 在入队闸门判)。
Generated by Claude Code
- 方向 = B:平台获得一个显式的每写入「合法 org-less」申报通道,
zhuangjianguo commented
on Aug 31, 2026 CollaboratorAuthorMore actions⏸️ HELD by the
domain:enginelane — surface collision, not a disagreement with the ruling⛔ Not claimed, and deliberately so. Recording it so a sibling seat does not pick this up cold and collide.
The ruling (决裁批 #17, comment 5478571825) is read and accepted: direction B, with the five constraints in its body — the declaration must be loud, checkable, countable; measure the class size before implementing; first batch收编 only the two already-ruled specimens (
sys_metadataper #6190 option A,sys_audit_logper its writers' enumerated cases); ⛔ never pick members by guess from #13491's 51cannot-determine; ⛔ option C excluded per 元判据②. Nothing here re-opens any of that.Why it waits
resolveSystemInsertOrganizationsits on the objectql insert path, and #13657 is working that exact seam right now — the undeclared-field door in front of the hooks, which is the same insert pipeline. Two seats editing the objectql insert path in parallel is how you get either a merge conflict on a p1+security change or, worse, two half-repairs that each pass their own tests.⇒ This dispatches as soon as #13657 lands, and it is near the front of the queue when it does: p1 + security, ruled, with the implementation constraints already written down.
⚠️ The one thing that could change that is if #13657's own report shows it moved the insert seam in a way that alters where the org-less declaration should hook — in which case this card's Zone 1 gets re-derived from the landed state rather than from today's.One thing worth carrying into the eventual dispatch order
Constraint 3 says measure the class size first.
⚠️ That measurement has a known unreadable edge in this session:cloudandobjectosare outside this session's repo scope, and they are where host/environment-level write paths live. A class-size census run from here will have a real gap, and it must be declared as NOT MEASURED rather than quietly scoped to what happened to be readable. Flagging now because that constraint is the ruling's, and a census that silently under-counts would satisfy it only on paper.
Generated by Claude Code
- added a commit that references this issue
on Sep 3, 2026 Carrier hygiene — director seat, summon 13, session_01WXyGTWPbbreqXow7Z2pZCk, 2026-09-04 ~05:57Z.
needs:contract-reviewremoved from this card: it is a design card inpm:awaiting-maintainerwith no open PR referencing it (open-PR search, zero hits; positive controls #14754 → PR #14930 and #14180 → PR #15139 answered), so there is no reviewable increment to carry. Maintainer ruling 2026-08-28 (contract-review.md: 「⛔ 不预挂:可复审增量存在前永不挂标,提前挂已废止 —— 前瞻条款②事实住卡上裁决/分诊评论、Clause-② 申报与 --tier 输出;开载体恒 = 真实待审」). The contract nature of the decision stays recorded in the card's text; the executing seat hangs the carrier on the card and the PR together when a diff exists.pm:awaiting-maintainerand the rest of the label set untouched.
Generated by Claude Code
状态转换:
pm:awaiting-maintainer→needs-user-decision(2026-09-09)维护者回批逐字:「B 桶 · 要你的判断,应转 needs-user-decision —— 23 张 转决策卡」。
判据:欠判断不是动作 —— 这是一张纯设计卡,标题自己就以
design:开头。批 #9 的租户再裁决表达不了第三种租户态:条件性租户隔离的对象,即 org-less 是行的属性而不是对象的属性。⛔ 没有机械答案可推导 —— 它要的是一次架构裁决。按
SKILL.md:110/:126:决定待做 =needs-user-decision;而core-rules.md:87也明写「设计卡、契约形状提案……进决策箱」。⇒ 此前为误分类,本卡从一开始就该在收件箱。同笔摘
pm:awaiting-maintainer;domain:engine、security、priority:p1留下。⚠️ 根因见 #17017。
Generated by Claude Code
维护者速读
事情:这张设计卡问「有没有第三种租户态——同一对象里既有带组织的行、也有合法无组织的行」(
sys_metadata的环境级写入、sys_audit_log对无组织列对象的记录),并推荐 B「按次声明合法无组织写入」(草案 PR #14923)。这个问题已被 ADR-0131(09-04 接受)反向解决:ADR 原文第 188–197 行点名本卡,裁「合法无组织的行 = 该对象根本不该有组织列」——sys_metadata成为无租户的环境定义账本(D6 / D7),sys_audit_log是部署账本;B 在 ADR 的备选表(第 773 行)被明确否决:「让 NULL 成为被声明的状态,而不是消灭它」。PR #14923 已关闭;您 09-03 曾亲自叫停其合并。选项:A(推荐) 按 ADR-0131 关卡(被取代,not planned),执行归 ADR-0131 的 v18 线(#15193 闸)。B 您认为 ADR-0131 对这两个对象的处置不对 ⇒ 重开为对 ADR-0131 D6 / D7 的修订提案(受管 ADR 草案,人合)。
你要做的:回一个字母,A / B。
- ① 项目长远合理性:A 让一条原则(D1「NULL 不是状态」)覆盖全部对象,缩小特例;B 让「被声明的 NULL」永久存在,每个未来写者都要记得声明。
- ② 实际业务拉动:零——这两个对象的存量 NULL 行由 ADR 的迁移四归宿(D10)逐表处理。
- ③ 防 AI 犯错:D9「缺章即拒写,任何姿态」是响亮的;B 依赖写者自觉。
- ④ 创业阶段不扩散:A 零新增;B 增一条按次声明的机制与账本。
推荐 A。置信缺口:无——ADR 原文直接点名并处置了本卡。
裁后执行
- A ⇒ 关 not planned(superseded by ADR-0131),摘
needs-user-decision;priority:p1 · security · domain:engine留。 - B ⇒ 立 ADR-0131 修订卡进决策箱,本卡
pm:blocked于其后。
总监席第 20 场(
session_01Tep4AYXZvyBA7jsvne5KZV)按决策箱勤务补齐速读,2026-09-09T05:3xZ;⛔ 非裁决。
Generated by Claude Code
Ruling recorded — A: superseded by ADR-0131; card closes (director seat, summon #20, decision batch #108 item 1, 2026-09-09T05:4xZ)
Provenance (who / verbatim / where): maintainer, live PM chat with this seat (
session_01Tep4AYXZvyBA7jsvne5KZV,os-bill), 2026-09-09T05:4xZ, replying to batch #108 in which this card was item 1 with the 速读 and four-facet block at 5596352358 recommending A. Reply, verbatim: 「7424 查 「什么在飞」 就应该查open的呀,直接关闭。 其他同意。」 — item 1 = A.Ruled. The third tenancy state this card asked for does not exist as a state: ADR-0131 (accepted 2026-09-04, lines 188–197) names this card and resolves it the other way round — a legitimately org-less row is a row on an object that should have no organization column;
sys_metadatabecomes the tenant-less environment definition ledger (D6 / D7) andsys_audit_loga deployment ledger. Option B (declare an org-less write per call, draft PR #14923, closed) is refused in the ADR's alternatives table (line 773). Execution follows the ADR's v18 line behind #15193. B here (reopen as an ADR-0131 D6/D7 revision) not taken.State, one write: closed
not_planned(superseded by ADR-0131);needs-user-decisionremoved;priority:p1 · security · domain:enginekept.
Generated by Claude Code
- added a commit that references this issue
on Sep 9, 2026
Filed by the
domain:enginelane PM, carrying an open question raised by the #13491 implementing seat. Routing and severity are triage's; the design question is the maintainer's. ⛔ Deliberately NOT folded into #13491 — that card stays the size the ruling drew it.The gap
The 2026-08-31 re-ruling (总监席第 5 场, 批 #9, option C) cuts tenant-audit scope into two states:
Measured while implementing it: a third class exists that neither state fits, and that
resolveSystemInsertOrganizationcannot currently express. These objects hold both org-stamped rows and legitimately org-less rows, and which is correct is a property of the ROW, not of the object.Two specimens, each with a standing ruling behind its org-less rows
sys_metadatasys_audit_logWhy this is a real blocker rather than a taxonomy quibble
resolveSystemInsertOrganizationdecides per object plus posture, and refuses any org-less row on a walled posture. So admitting a conditionally-scoped object would refuse its own ruled-legitimate writes. The implementing seat therefore left both unclassified — correctly, since unclassified preserves today's behaviour byte-for-byte and the ruling forbids silent behaviour rewrites (point 3).But "unclassified" is not a resting place for these two.⚠️
sys_metadataandsys_audit_logare among the largest write populations in the platform namespace. Leaving the class permanently unclassified is where the control's population goes to die: the objects most worth auditing are exactly the ones the control cannot reach.⭐ The root of it: today the same
NULLmeans both "deliberate" and "bug", which is precisely why the control cannot distinguish them.Options, as the implementing seat costed them
A — keep them unclassified indefinitely. Honest, and it is today's state. Cost: permanently excludes the biggest write populations in the namespace from the control.
B — give the machinery a way to DECLARE a legitimately org-less row (an explicit per-write assertion that is loud, checkable and countable), then admit the conditional objects behind it. (the seat's recommendation, as a separate design card — which is this one)
C — split each conditional object's writes at the door, so the org-less population travels a separate, declared path.
The seat's reasoning for B, recorded rather than endorsed
sys_metadataandsys_audit_log, i.e. most of the namespace's write volume.The PM adds no preference. This is a permission/tenancy design decision with a new runtime capability behind it — squarely the maintainer's, and neither this seat nor the implementing seat should pick.
What this does NOT claim
The two specimens are measured; the size of the class is not. #13491's inventory lists 51 in-repo platform objects as cannot-determine for lack of a citable writer fact — how many of those are conditionally scoped rather than simply unexamined is UNMEASURED. ⛔ Do not read "51" as the class size.
Related
#13491 (the re-ruling this surfaced under; both specimens left unclassified there) · #6190 (the ruling that makes
sys_metadata's env-wide write legitimate) · #8844 (the multi-organization refusal branch) · #13178 · #13497