Skip to content

Commit cd4c2cb

Browse files
committed
chore(spec): classify sys_notification_preference.user_id's empty state as scope in the empty-state registry
Declared cross-lane on the spec seat post (#6017, 6334445279): one row, no schema, scanner or other entry moves. An empty User is the admin-wide default (ruling A), it selects the users a delivery toggle covers and grants no access. Claude-Session: https://claude.ai/code/session_01UnHcTADjeg3VwxF21QHj7W Co-authored-by: Claude <noreply@anthropic.com>
1 parent d272b23 commit cd4c2cb

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

‎packages/spec/scripts/liveness/empty-state-registry.mts‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,14 @@ export const EMPTY_STATE_REGISTRY: EmptyStateEntry[] = [
209209
rationale:
210210
'Which files under a storage prefix get indexed into a knowledge source. Ingestion scope, not read authorization — retrieval is gated separately. NOTE the shape though: it is a vacuous-allow-list ("allow-list" whose empty value admits everything), the same shape as #3896. `storage.zod.ts` models the identical concept the better way — an explicit `mode: "whitelist"` discriminator plus `.min(1)`, so an empty whitelist cannot be expressed at all. Prefer that form for new allow-lists; changing this one is a breaking change to an authorable field and is not in scope here.',
211211
},
212+
{
213+
file: 'packages/services/service-messaging/src/objects/notification-preference.object.ts',
214+
property: 'user_id',
215+
semantics: 'scope',
216+
rationale:
217+
"Which users a notification delivery toggle covers. An empty User makes the row the admin-wide default for every user of the organization — ADR-0118 D1's empty reference in a user column rather than a sentinel, as maintainer ruling A decided (ruling record 6304380498). It selects the range a mute or allow applies to and grants no data access: a user's own row overrides it, and mandatory topics bypass the matrix entirely. The one way the empty state could widen by accident — the lookup default `set_null` turning a deleted person's own row into the default for everyone — is closed by `deleteBehavior: 'cascade'` on the field.",
218+
evidence: 'packages/services/service-messaging/src/preference-resolver.ts (resolveRow — the user-specific row is consulted before the empty-User default)',
219+
},
212220

213221
// ---- Engine output, not authorable -------------------------------------
214222

0 commit comments

Comments
 (0)