Filed by the domain:services execution seat as required follow-up of PR #15078 (card #15030), on the dev's correctly-raised open question 3. Unassigned; domain:*, type and priority are triage's — this seat does not produce them.
Why this card exists
#14547 reported that an org-stamped sharing rule cannot reach a business unit seeded with organization_id = NULL. It was closed as completed by PR #14949, which widened orgScope to a NULL-inclusive screen.
PR #15078 reverts that widening, on the maintainer's ruling (card #15030): the NULL-inclusive screen re-implements the driver's own predicate a second time, is the shape the v18 organization-ownership decision (PR #14976) retires, and is unreleased — so it comes out before the 17.3 tag rather than becoming a v18 breaking change.
⇒ Once #15078 lands, the 17.x symptom stands exactly as 17.2.0 ships it, and #14547 is closed. There is currently no open card carrying a defect that a shipping release actually has. The maintainer's inbox filter reads open issues, so a closed card is invisible to it.
⛔ This is deliberately not a reopen of #14547 — card #15030 explicitly forbids reopening anything it closed, and PR #15078 respected that. #14547 stays as the historical report of the pre-#14949 state; this card is the live 17.x exposure.
The defect, as 17.3 will ship it
A business unit row seeded with organization_id = NULL is not a usable recipient for an org-stamped sharing rule: BusinessUnitGraphService.seedIsUsable() reads through orgScope, which AND-composes strict organization_id = <rule org>, so the seeded unit fails the screen and both expandUnitMembers and expandUsers return empty. The warnOnEmptyUnitExpansion path exists precisely for this and logs it.
⚠️Reproduce it against the fan-out, not the grant rows — an empty expansion produces no rows to inspect, so the observable is the warn plus the absent grant, not a wrong grant.
Where the real fix lives — ⛔ not here
The root cause is not in plugin-sharing. It is the seed loader's sys_ exemption plus first-boot ordering: the Default Organization does not exist when application seed datasets load, so sys_business_unit seeds are written unstamped. The v18 organization-ownership decision (PR #14976) owns that fix — the Default Organization exists before seed datasets load, and the seed loader stamps sys_business_unit seeds.
⇒ This card is about the 17.x exposure window, not about re-fixing it in 17.x. Whoever triages it should decide between: (a) accept and document the 17.x behaviour, closing this card as won't-fix-in-17 with the reasoning recorded; (b) a 17.x-only mitigation that does not duplicate a predicate; (c) hold until the v18 fix ships and close then. ⛔ Reintroducing the NULL-inclusive screen is not an option — the maintainer ruled it out in #15030.
⚠️ A second, SHIPPED instance of the same duplication — needs an explicit owner
Measured during PR #15078 and deliberately not touched there: SharingRuleService.adminOrgScope (packages/plugins/plugin-sharing/src/sharing-rule-service.ts:556, from #7676) carries the same NULL-inclusive arm that #15030 retires from business-unit-graph.ts. It is shipped — the file at tag @objectstack/account@17.2.0 contains it, and #14949's diff on that file adds no NULL-arm line, so it is not #14949's to revert.
⇒ Reverting business-unit-graph.ts does not address it. #10103 ("cause 1") is closed, and the predicate's retirement is the declared subject of PR #14976 — so this is raised so that decision gets an explicit worklist entry for this second call site rather than an implicit one. Three further non-test hits sit at :268, :515, :630 in the same file and were not individually adjudicated.
Refs: #14547 (closed, historical) · #14949 / e560b4d51 (the widening) · #15030 / PR #15078 (the revert) · PR #14976 (v18 org-ownership decision, open draft) · #7676 (adminOrgScope) · #10103 (closed) · #13564.
Generated by Claude Code
Filed by the
domain:servicesexecution seat as required follow-up of PR #15078 (card #15030), on the dev's correctly-raised open question 3. Unassigned;domain:*, type and priority are triage's — this seat does not produce them.Why this card exists
#14547 reported that an org-stamped sharing rule cannot reach a business unit seeded with
organization_id = NULL. It was closed ascompletedby PR #14949, which widenedorgScopeto a NULL-inclusive screen.PR #15078 reverts that widening, on the maintainer's ruling (card #15030): the NULL-inclusive screen re-implements the driver's own predicate a second time, is the shape the v18 organization-ownership decision (PR #14976) retires, and is unreleased — so it comes out before the 17.3 tag rather than becoming a v18 breaking change.
⇒ Once #15078 lands, the 17.x symptom stands exactly as 17.2.0 ships it, and #14547 is closed. There is currently no open card carrying a defect that a shipping release actually has. The maintainer's inbox filter reads open issues, so a closed card is invisible to it.
⛔ This is deliberately not a reopen of #14547 — card #15030 explicitly forbids reopening anything it closed, and PR #15078 respected that. #14547 stays as the historical report of the pre-#14949 state; this card is the live 17.x exposure.
The defect, as 17.3 will ship it
A business unit row seeded with
organization_id = NULLis not a usable recipient for an org-stamped sharing rule:BusinessUnitGraphService.seedIsUsable()reads throughorgScope, which AND-composes strictorganization_id = <rule org>, so the seeded unit fails the screen and bothexpandUnitMembersandexpandUsersreturn empty. ThewarnOnEmptyUnitExpansionpath exists precisely for this and logs it.Where the real fix lives — ⛔ not here
The root cause is not in
plugin-sharing. It is the seed loader'ssys_exemption plus first-boot ordering: the Default Organization does not exist when application seed datasets load, sosys_business_unitseeds are written unstamped. The v18 organization-ownership decision (PR #14976) owns that fix — the Default Organization exists before seed datasets load, and the seed loader stampssys_business_unitseeds.⇒ This card is about the 17.x exposure window, not about re-fixing it in 17.x. Whoever triages it should decide between: (a) accept and document the 17.x behaviour, closing this card as won't-fix-in-17 with the reasoning recorded; (b) a 17.x-only mitigation that does not duplicate a predicate; (c) hold until the v18 fix ships and close then. ⛔ Reintroducing the NULL-inclusive screen is not an option — the maintainer ruled it out in #15030.
Measured during PR #15078 and deliberately not touched there:
SharingRuleService.adminOrgScope(packages/plugins/plugin-sharing/src/sharing-rule-service.ts:556, from #7676) carries the same NULL-inclusive arm that #15030 retires frombusiness-unit-graph.ts. It is shipped — the file at tag@objectstack/account@17.2.0contains it, and #14949's diff on that file adds no NULL-arm line, so it is not #14949's to revert.⇒ Reverting
business-unit-graph.tsdoes not address it. #10103 ("cause 1") is closed, and the predicate's retirement is the declared subject of PR #14976 — so this is raised so that decision gets an explicit worklist entry for this second call site rather than an implicit one. Three further non-test hits sit at:268,:515,:630in the same file and were not individually adjudicated.Refs: #14547 (closed, historical) · #14949 /
e560b4d51(the widening) · #15030 / PR #15078 (the revert) · PR #14976 (v18 org-ownership decision, open draft) · #7676 (adminOrgScope) · #10103 (closed) · #13564.Generated by Claude Code