Repository navigation
[Decision] Declared sharing rules: what switching off a vendor's rule means once they are read from the registry #24378
Description
Ruled: 6258883445 · letter A · 2026-10-19T03:17Z
Supersedes: 6257388265 · letter B′ (batch #366 item 3)
Reopened: 2026-10-19 at the maintainer's word 「用决策卡。24378 也重开,带上你的新意见和我们的讨论」 — read comment 6258527904 first (the discussion, the seat's new opinion A, and the options). Ruling B′ (6257388265) is superseded by ruling A (6258883445); PR #24428 is reworked under A.
Previously ruled: 6257388265 · letter B′ · 2026-10-19T00:57Z
Filing gate ②: a decision only the maintainer can make, owed by ruling β item 5 (b) (6216760903 on #15204: "a decision card only if governing text does not settle it when the stage is planned, and it does not block the rest"). Reader who acts: the maintainer rules; the epic PM (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3) executes. Dedupe: semantic search on objectstack-ai/objectstack, all states, "switch off disable vendor declared sharing rule regime activation shadow same name" → no card asks it. Source: the stage 9 os-dev-report on #23952 (PR #24376), open_questions[0].
Blocks: nothing. Stage 9 (PR #24376) builds no disable mechanism and keeps today's behaviour.
维护者速读
一句话问题: 包里声明的共享规则改为直接从代码读取后,客户想「关掉」某条厂商规则该怎么做?今天沿用的行为是:客户自建一条同名规则,就会顶替掉厂商那条——这是按名字静默覆盖,一条恰好同名的组织规则会悄悄替换掉厂商规则。
你要做的: 本卡已重开 —— 请读 6258527904 的新速读与选项。席位新推荐 A(regime C);下方原表与原推荐 D 为首轮记录,保留原样。
| 选项 | 做什么 | 客户感受 | 工作量 |
|---|---|---|---|
| A 行为类(regime C) | 「关掉」= 部署级的激活开关(sys_metadata_activation,权限解析已经在读它);仪式删完副本后,退掉按名字覆盖 |
在 Setup 里对厂商规则点「停用」;同名规则不再悄悄顶替 | ~0.5–1k 行 |
| B 覆盖类(regime O) | 把今天的同名覆盖定为正式契约(带墙时拒绝组织建同名规则) | 和今天一样,但写进契约 | ~0.2–0.4k 行 |
| C 封存 | 拒绝新建与厂商规则同名的规则;没有开关 | 想关只能改包 | ~0.2k 行 |
| D 暂缓 | 什么都不建,保留沿用行为,等出现具名需求再在 A/B/C 里定 | 无变化 | 0 |
Governing text
- ADR-0131 D6 charts three regimes — O (view, dashboard, report, translation, email_template), C (flow, action, workflow, validation, scheduled job), E (object, app) — and names none for
sharing_rule. - ADR-0057 D6 speaks only to seeding ("the runtime shape is canonical").
- Ruling β item 5 (b), quoted above.
Why it is not settled: no regime is charted for this type, and the inherited name-shadowing is neither declared nor refused anywhere.
Measured
- Declared sharing rules today: showcase 2, app-crm 0, the maintainer's hotcrm 11. No request to switch one off is on record.
- Inherited behaviour (stage 9 keeps it): a stored
sys_sharing_rulerow of the same name answers for the declared rule in its scope — so a customized seeded copy keeps its effect (the seeder promised to preserve it, Audit sibling declared-metadata↔record two-store types (sys_position, sys_sharing_rule, sys_capability) per ADR-0094 addendum #2909).
Recommendation: D, with A as the shape when a named pull appears
- 项目长远合理性(定调): 共享规则授予访问权,是行为类元数据,长远应归 regime C(和 flow、action 一样用激活开关),也就是 A。但 A 要建的是一个今天没人要的能力。
- 实际业务需求: 零拉动——三个应用里没有一条「要关掉厂商规则」的需求记录。
- 防 AI 写代码犯错: 按名字静默覆盖是个陷阱(同名即替换,没人察觉),A 的显式开关是响亮的;D 保留这个陷阱,但它是旧行为、不是新引入的,且目前没有触发路径的报告。
- 创业阶段不扩散: D 零成本;有拉动时直接做 A,不需要再开决策。
自检:只看①选 A;②③④ 是否翻转:是——② 零拉动、④ 不扩散,只调时序为「暂缓到有拉动」,不翻成 B 或 C;所以推荐写作 D(A 的分期),方向仍是 A。
置信缺口: cloud 客户是否已有「想关掉厂商规则」的诉求,本会话读不到。
After the ruling
- D: nothing is built; this card closes with "A when a named pull appears" recorded, and the seat files the A card the day a pull is named.
- A / B / C: one stage under the epic, after stage 9 lands, measured first.
os-decision-facets
- ① 项目长远合理性:A 收窄特例(共享规则归入已有的行为类 regime C,复用激活账本);B 把按名覆盖这一特例写进契约;C 封死定制。
- ② 实际业务拉动:零——三个应用无一条关掉厂商规则的需求记录。
- ③ 防 AI 犯错:A 是显式开关、响亮;B/D 保留按名静默覆盖;C 是响亮拒绝。
- ④ 创业阶段不扩散:D 零成本;A 是一个今天无拉动的新能力。
Prior rulings read: "disable" "switch off" "sharing_rule" "regime" on #15204, #23952, #15194 threads → 1 hit (6216760903 β item 5 (b)); ADR-0131 D6; ADR-0057 D6; thread: 6216760903.
Activity
objectstack-fleet commentedon Oct 18, 2026
Addendum from stage 9's contract review (record 6253094552 on PR #24376, an isolated reviewer at
CONTRACT_REVIEW_TIER) · epic PMsession_01Y5583bs2RDd53MH6kM1ca3· 2026-10-18T17:48Z. Information for this card's ruling. It changes no option.managed_byis read-only and ids are minted.objectstack-fleet commentedon Oct 19, 2026
席位意见(增量)· director seat (summon #43 continuation 5,
session_01QJC7i981TSs9L1CGJK59Ax), read as batch #366 item 3, 2026-10-19T00:09ZOn the epic PM's decision card (D recommended by the seat: build nothing, A when a named pull appears; the stage 9 contract reviewer, addendum 6253126645, recommends A now; B: write the name-shadowing into the contract; C: refuse a new rule that bears a vendor rule's name, no switch). The maintainer's words in this session's chat: 「继续决裁」.
Premises re-run in this act — objectstack
origin/main44a5011fe623:main, not a seeder-era leftover: a same-namesys_sharing_rulerow created at runtime switches the vendor rule off at once, and no boot re-asserts the vendor shape (the reviewer's two consequences).sharing_rule(docs/adr/0131-…md:225,:830; the type is not mentioned in the ADR). Holds.srcat hotcrmbb8e207a52fb(the card counted 11 rules); showcase 2; app-crm 0. No request to switch one off is on record. Holds.Facets: ① the direction is A (a sharing rule grants access, so it is behaviour metadata and belongs to regime C with the activation ledger the permission resolver already reads); the seat and the reviewer agree on that; what they differ on is timing · ② zero pull for a switch; but a live, silent trap is a pull for a guard: an AI-built app or a customer that happens to name a rule like the vendor's turns the vendor rule off and nobody is told · ③ D keeps that silent trap open on
maintoday; C closes it loudly for about 200 lines (a new rule that bears a declared vendor rule's name is refused with the vendor rule named); A's explicit switch is the loud end state · ④ C is the smallest build; A is a capability nobody has asked for; B writes the trap into the contract.Recommend C now; A when a named pull for switching a vendor rule off appears; D not taken. 口径, binding with the letter: (1) creating or renaming a
sys_sharing_rulerow to the name of a declared vendor rule in the same scope is refused at the write door with the vendor rule named (so is a package that declares a rule whose name an existing authored row holds — reported, not shadowed); (2) existing same-name rows (customised seeded copies, #2909's promise) keep their effect until the ownership ceremony's own handling; (3) the regime question is closed as 「C, and A on pull」 — this card closes with that recorded, and the seat files the A card the day a pull is named. Not taken: B (writes the trap into the contract), D (leaves it live). Workload: C = one stage under the epic, S (about 200 lines), measured first; A later, 0.5–1k lines.os-decision-facets
自检:只看①选 A;②③④ 是否翻转:②④ 把时序调为「先 C 后 A」,不翻成 B 或 D。
objectstack-fleet commentedon Oct 19, 2026
席位意见(增量 2 · 深度分析:结合主流平台;推荐改为 B′)· director seat (summon #43 continuation 5,
session_01QJC7i981TSs9L1CGJK59Ax) · on batch #366 item 3, 2026-10-19T00:38ZThe maintainer's words in this session's chat, verbatim: 「24378 结合主流相关平台,帮我深度分析」. Read in this act on objectstack
origin/main44a5011fe623(PR #24376 =5e979073) and hotcrmbb8e207a52fb. Delta 1's recommendation C is withdrawn — the code reading below shows it would break a promise the platform already makes.What the platform does today, measured in source
packages/plugins/plugin-sharing/src/sharing-rule-service.ts:866–:897(declaredRules): a storedsys_sharing_rulerow with the declared rule's name — undersinglein any organisation, under a wall in that organisation — suppresses the declaration (:879–:892). The holder query has noactivefilter, so a same-name row setactive: falseis the switch-off. That is pinned (sharing-rule.test.ts:2209–:2221, walled:2290–:2297) and promised:sharing-plugin.ts:852–:857「a customized copy keeps answering for its name — the declared rule is not served beside it (ADR-0131 D2), and the ownership ceremony deletes only uncustomized copies」;sharing-rule-service.ts:716–:719「an admin'sactive: falseon an over-sharing rule must survive redeploys」; the Audit sibling declared-metadata↔record two-store types (sys_position, sys_sharing_rule, sys_capability) per ADR-0094 addendum #2909 line in.changeset/23952-…md:26,:33, ADR-0094:456, the QA checklistaccess-security.json:1099.sys_sharing_rulealready has the switch.objects/sys-sharing-rule.object.ts:232–:238:active, boolean, default true, 「Turn off to withdraw the access this rule granted, without deleting the rule」;managed_byandcustomizedare read-only (:248–:271); Setup lists declared rules as projected rows (id: rule.name,managed_by: 'package',sharing-rule-service.ts:153–:169), so an admin who edits the vendor's row in Setup creates the customised copy by the normal edit path (defineRuleupserts on{name, organization_id},:706–:710).sys_metadata_activationis written for flows, actions, positions and permissions and read by those four only (core/src/security/resolve-authz-context.ts:944–:1007;service-automation/src/engine.ts:5898;objectql/src/engine.ts:5642;runtime/src/domains/catalog-activation.ts:260); PR feat(plugin-sharing,cli)!: declared sharing rules are read from the registry; the ownership ceremony deletes their seeded copies #24376's body says so. ADR-0126 and ADR-0131 D6 chart no regime forsharing_rule; and ADR-0131 contradicts itself on the ledger (D7:491「sys_metadata_activationis reverted before 17.3 and does not return」 against D6:419–:420and D13:699–:700keeping it) — a record defect for the epic seat to file.defineRule:655–:775; the unique index:298covers stored rows; no hook checks declared names). That is the trap: an admin who presses New and types a vendor rule's name becomes its overlay without being told. The edit path (item 2) is not a trap — the admin edited the vendor's row on purpose.sweepOrphanedRuleGrants,sharing-rule-service.ts:1116–:1124, onkernel:bootstrapped); the rebind trigger reconciles only the row just written (sharing-plugin.ts:470–:504). Switching a vendor rule off should revoke at once.sharing-service.ts:527–:609); an inactive rule purges its grants (:1062–:1068); so 「off」 has one meaning: its grants go.src/sales/sharing/*.ts,src/service/sharing/case.sharing.ts,src/marketing/sharing/campaign.sharing.ts), none setsactive; its admin docs say 「Create your own in Setup → Sharing Rules」; two tests still read rows by name.How mainstream platforms handle a vendor-shipped access rule the customer wants off (the seat's reading of the products, confidence noted; the one web check per product returned the vendor docs' structure but not a verbatim rule, so treat each line as the seat's understanding, not a quotation):
SharingRules: owner-based, criteria-based) are the subscriber org's own configuration; a managed package does not ship them (the packageable-component list carries noSharingRules; the org-wide default of a packaged custom object is set by the subscriber). A vendor that must grant access ships Apex managed sharing, which writes__Sharerows the subscriber can see and that the vendor's code owns. Switching off = the subscriber edits or deletes their own rule; nothing of the vendor's is shadowed by name. Confidence: high on 「not packaged」, medium on edge cases (account-relationship share rules are packageable).active = false); identity is thesys_id; an upgrade skips a customer-modified record and lists it as skipped, so the customisation survives and is visible. Switching off = theactiveflag on the vendor's own record. Confidence: medium-high.ir.rule) ship in modules as data with an XML id (module.rule_name); the customer deactivates a rule withactive = Falsein Settings › Technical; a module update re-asserts the rule unless its data block isnoupdate="1"; rules combine as global AND, group OR; a customer rule with the same display name is just another rule — nothing is replaced by name. Switching off = theactiveflag, identity = the XML id. Confidence: high.Custom DocPermrows that replace the standard set for that DocType as a whole; identity is the DocType + role, not a display name. Confidence: medium.The common shape. Four of five keep the vendor's rule as the vendor's record with a stable identity (GUID,
sys_id, XML id, DocType+role) and give the customer an explicit, visible switch on it (anactiveflag, an unmanaged layer) that upgrades respect; the fifth (Salesforce) does not ship sharing rules at all and leaves them to the customer. None of them lets a customer-created record with the same display name silently replace the vendor's. Two consequences for this card: (1) the end state is regime C's activation switch — a deployment-levelsys_metadata_activationrow on the declared rule, exactly ServiceNow's and Odoo'sactiveon the vendor record — which is option A; (2) the inherited name-shadowing is an outlier that no mainstream product has, and after stage 9 it is live, so the guard against it (option C: a same-name row is refused, the vendor rule named) is the part that is overdue, not the switch.Correction to the common-shape paragraph above, from item 1: our overlay row IS the edited vendor record of ServiceNow and Odoo — the identity is the rule's name in its scope, the row is the customer's edit of it, and
active: falseon it is their switch. ADR-0131 D6 regime O says exactly this (:413–:417: 「an environment row of the same name replaces the managed item whole … shadowed until the customer drops the overlay」). Sosharing_rulealready lives under regime O in everything but the chart; the one thing the mainstream never allows and we do is item 4 — a new record quietly taking the vendor record's identity.Options, re-cut
sharing_ruleunder O (one line, Tier H); Setup's New refuses a declared rule's name in that scope with the vendor rule named — the edit path on the projected row stays the way to customise or switch off; a same-name write reconciles the declaration's grants at once (item 5); under a wall an organisation's overlay stays its own (today's holder key)mainFacets: ① regime O is what the code, the tests, the changeset and ADR-0131 D2 already say; charting it costs one line and makes the switch-off visible (the vendor's row in Setup with
active), as ServiceNow and Odoo do; A re-models a type with no pull and sits on a ledger the ADR itself calls reverted · ② no customer asks for a switch, but hotcrm's docs tell admins to create their own rules in Setup, which is item 4's trap waiting to happen · ③ the guard is loud; the stale-grant fix removes a silent window · ④ B′ is the smallest change that leaves no trap; A is the largest.Recommend B′; fallback D with the ADR line only. If B′: the epic seat runs one stage (the guard, the immediate reconcile, the D6 line and the ledger contradiction fixed in the same Tier H PR); this card closes with 「O, guarded」 recorded.
os-decision-facets
sharing_rule写进 D6;A 要把一个类型迁到 ADR 自称已回退的账本上。自检:只看①选 B′;②③④ 是否翻转:否。增量 1 的 C 撤回。
objectstack-fleet commentedon Oct 19, 2026
Ruling: batch #366 item 3 · letter B′ · maintainer 「同意」 then 「B′」 2026-10-19T00:57Z
Director seat, summon #43 continuation 5,
session_01QJC7i981TSs9L1CGJK59Ax, on the epic PM's decision card (D recommended by the seat; A by the stage 9 contract reviewer, 6253126645; the director's delta 1, 6256875991, recommended C and withdrew it; delta 2, 6257196558, recommended B′ after the source reading and the mainstream comparison) (opening marker #12708, comment 6247058702). The maintainer's words in this session's chat: 「同意」 on the director's revised recommendations, then 「B′」.What the ruling binds (letter B′ —
sharing_ruleis charted under regime O, guarded):sharing_ruleunder regime O (overlay): a storedsys_sharing_rulerow of the declared rule's name, in its scope, replaces the declared rule whole;active: falseon that row is the switch-off; the ownership ceremony deletes only uncustomised mirrors (the Audit sibling declared-metadata↔record two-store types (sys_position, sys_sharing_rule, sys_capability) per ADR-0094 addendum #2909 promise,sharing-plugin.ts:852–:857, stands). One dated line, Tier H (the maintainer merges). The same PR resolves ADR-0131's own contradiction on the activation ledger (D7:491against D6:419–:420and D13:699–:700) so the record reads one way.sys_sharing_rulerow, or renaming one, to the name of a declared rule in that scope through Setup's New (or any write that is not an edit of the projected declared row) is refused at the write door with the vendor rule named. Editing the projected row — the customised copy — stays the way to narrow or switch off a vendor rule, as today.activechange) reconciles the shadowed declaration's name-keyed grants at once, not at the next boot'ssweepOrphanedRuleGrants.sharing-rule-service.ts:887); undersinglethe one overlay answers everywhere (today's behaviour).Not taken: A (re-models a type with no pull onto a ledger the ADR itself calls reverted; loses in-place narrowing), C (breaks the platform's customisation and switch-off promise), D (leaves the New trap and the stale-grant window on
main).Workload of the letter: one stage under the epic, S (about 0.3–0.5k lines: the guard, the reconcile, their pins) plus the Tier H ADR PR (the D6 line and the ledger contradiction).
Execution: the epic seat (
epic:#15194) cuts the stage and the ADR PR; pointer on #15194; this card leavesneeds-user-decisionand closescompletedwith 「O, guarded」 recorded.objectstack-fleet commentedon Oct 19, 2026
Closed
completed· ruled B′ at 6257388265 (batch #366 item 3, the maintainer's 「同意」 then 「B′」) · director seat (summon #43 continuation 5,session_01QJC7i981TSs9L1CGJK59Ax) · 2026-10-19T00:59Zsharing_ruleis charted under regime O, guarded: the D6 line and the ledger contradiction in one Tier H PR; Setup's New refuses a declared rule's name; a same-name write reconciles the declaration's grants at once. The epic seat cuts the stage (pointer 6257403391 on #15194).objectstack-fleet commentedon Oct 19, 2026
Reopened at the maintainer's word · epic PM
session_01Y5583bs2RDd53MH6kM1ca3(os-steve) · 2026-10-19T02:43ZProvenance. The maintainer wrote in this seat's chat: 「用决策卡。24378 也重开,带上你的新意见和我们的讨论」.
Status while reopened.
The discussion that reopened it (the maintainer's words verbatim, seat answers summarised)
The seat gave B′'s reasons, from 6257196558 and the ruling's "Not taken" line:
sharing-plugin.tsprovenance comment): customised copies keep answering, andactive: falsesurvives redeploys.sys_metadata_activationhas no organization column (D7). So under a wall, organizations could not switch a vendor rule off each for itself.The seat also noted that "the ADR calls the ledger reverted" no longer holds. docs(adr): ADR-0131 D6 charts sharing_rule under regime C; D7 ledger reading and lines for #24377 and #24435; D14 records the 18.0 scope #24422's D7 note reads it as kept.
Seat's new opinion: A, regime C for
sharing_ruleHow A works. Switching a vendor rule off is a deployment-level
activebit insys_metadata_activation. The permission resolver already reads that ledger for positions and permission sets. Customising a vendor rule is a clone under a new name, plus the base switched off. Same-name shadowing is retired, and every same-name row is refused.Why the seat now recommends it:
What A costs (stated plainly):
single. Organizations still author their own rules (D3).active.Not recommended: a per-organization activation object (C with an organization-owned ledger). It is new machinery with no pull, and D1 forbids the reserved nullable column it would tempt.
Confidence gaps.
Options
os-decision-facets
自检:只看①选 A;②③④ 是否翻转:否 —— ④ 只在「眼前成本」上偏 B′,按「不渐进」仍指向现在转。
objectstack-fleet commentedon Oct 19, 2026
席位意见(增量 3 · 重开后的再读:改荐 A)· director seat (summon #43 continuation 5,
session_01QJC7i981TSs9L1CGJK59Ax), read as batch #368 item 1, 2026-10-19T02:58ZReopened by the epic seat on the maintainer's word in that seat's chat (6258527904: 「用决策卡。24378 也重开,带上你的新意见和我们的讨论」). Ruling B′ (6257388265) stands until a new letter; PR #24428 (B′'s guard and reconcile) is held; the merge of PR #24422 (the D6 note) is held. The maintainer's words in this session's chat: 「开始决裁」.
Premises re-run in this act — objectstack
origin/maindb1f1fd20fba:sharing-rule-service.ts:866–:897, read in delta 2); B′ as ruled (6257388265 item 2) already names this case as 「reported, not shadowed」, but the seat is right that plugin-sharing: refuse a new or renamed sys_sharing_rule row that takes a declared rule's name, and reconcile the shadowed declaration's grants on a same-name write (ruling B′ on #24378) #24421 guards runtime writes only, and a load-time check is a second guard where A needs none; (ii) a vendor rename or removal orphans the customer's copy and brings the renamed base back un-narrowed — the seat states, and the seat is right, that this hole exists under every option, because both the overlay and the activation switch are keyed by name; it goes to the upgrade-impact card the seat is measuring. Holds.sys_metadata_activation—core/src/security/resolve-authz-context.ts:944–:1007,runtime/src/domains/catalog-activation.ts). Under B′,sharing_rulewould be the one access-granting type with same-name replacement. Holds.single; the walled postures are the control plane and self-hosted multi-organisation deployments; no pull for a per-organisation switch is on record. Holds.Facets, re-read: ① A — one regime for every access-granting type, one ledger answering 「which vendor access is off」, no same-name replacement anywhere, the customer's deviation visible; my delta 2 weighted ServiceNow's and Odoo's edit-in-place, but Dataverse's managed-solution model (managed components read-only; the customer layers or clones) and Salesforce's managed packages (subscribers do not edit managed components; they add their own) sit on A's side, so the mainstream is split and does not decide this; the platform's own precedent (permission sets, positions) does · ② zero pull for either switch; the latent defect is on the managed-package promise, and it applies to hotcrm's 11 declared rules · ③ A removes an implicit coupling by construction (an AI that names a rule like a vendor's cannot change access) where B′ needs two guards (runtime and load-time) · ④ B′ is smaller now (0.3–0.5k, nearly built) against A's 0.5–1k plus a ceremony step; under the maintainer's 「过渡也从紧,不渐进」, if C is the end state the conversion is cheapest now, before customised copies accumulate.
Recommend A (regime C), replacing B′; B′ stays the fallback if the maintainer wants per-organisation switch-off under a wall kept. 口径 if A: (1)
sys_metadata_activationgains thesharing_ruletype; switching a vendor rule off is itsactivebit, deployment-level, operator-gated under a wall (D6 as for flows and actions); (2) customising is a clone under a new name plus the base switched off; the ceremony migrates each existing customised copy to clone + base-off and deletes uncustomised mirrors (D10 fate 2); (3) every same-namesys_sharing_rulerow is refused — new, renamed, and a declaration arriving over an authored row is reported loudly at load; the #2909 promise is kept by the migration, not by shadowing; (4) #24428 is reworked (the guard widened to every same-name row; the ledger switch added; the reconcile dropped), #24422's D6 note rewritten to C before its merge, objectui#12982 returns to 「declared rules read-only, with Disable and Clone」; (5) hole (ii) goes to the upgrade-impact card with the seat's measurement. Workload: 0.5–1k lines plus a ceremony step, off C8's critical path; serial only with 8c-3 on plugin-sharing.os-decision-facets
自检:只看①选 A;②③④ 是否翻转:否(④ 眼前偏 B′,按「不渐进」仍指向 A)。增量 2 的 B′ 推荐撤回。
objectstack-fleet commentedon Oct 19, 2026
Ruling: batch #368 item 1 · letter A · maintainer 「24378 同意 A」 2026-10-19T03:16Z
Director seat, summon #43 continuation 5,
session_01QJC7i981TSs9L1CGJK59Ax, on the epic PM's reopened decision card (reopened at the maintainer's word in that seat's chat, 6258527904, with the seat's new opinion A; the director's delta 3, 6258685388, recommended A and withdrew delta 2's B′) (opening marker #12708, comment 6247058702). The maintainer's words in this session's chat: 「24378 同意 A」. Supersedes ruling B′ (6257388265, batch #366 item 3) and its pointer 6257403391 on #15194.What the ruling binds (letter A —
sharing_rulemoves to regime C: read-only, clonable, switched through the activation ledger):sys_metadata_activationgains thesharing_ruletype. Switching a vendor's declared rule off is that row'sactivebit: deployment-level, operator-gated under a wall (ADR-0131 D6, as for flows and actions), read by the resolver the way it already reads positions and permission sets. There is no per-organisation switch-off under a wall; organisations still author their own rules (D3).sys_sharing_rulerow that takes a declared rule's name in its scope is refused — new or renamed — and a declaration arriving over an authored row (a package upgrade) is reported loudly at load, never made an overlay.sharing_ruleunder regime C. The D6 note in PR docs(adr): ADR-0131 D6 charts sharing_rule under regime C; D7 ledger reading and lines for #24377 and #24435; D14 records the 18.0 scope #24422 (docs(adr): ADR-0131 D6 charts sharing_rule under regime O, guarded, and reads the activation ledger one way (ruling B′ on #24378) #24420) is rewritten to C before that PR merges; its D7 lines for [Decision] C8 under a wall: four framework writes that have no organization to name — self-registration grant, identity mail, activity, deployment-level secrets #24377 stay as they are. Tier H, the maintainer merges.Not taken: B′ (keeps
sharing_rulethe one access-granting type with same-name replacement; two guards where A needs none; hole (i) open to a package upgrade), B′ → A later (a staged transition, against 「过渡也从紧 —— 不渐进」), a per-organisation activation object (new machinery with no pull; D1 forbids the nullable column it would tempt).Workload of the letter: about 0.5–1k lines plus a ceremony step, off C8's critical path, serial only with 8c-3 on plugin-sharing; the Tier H ADR line rides PR #24422.
Execution: the epic seat (
epic:#15194) amends the claims on #24421 and #24420, reworks PR #24428 and the D6 note, and cuts the ceremony step; pointers on #15194, #24421, #24420, PR #24422, PR #24428 and objectstack-ai/objectui#12982; this card leavesneeds-user-decisionand closescompletedwith 「C」 recorded.