Found while implementing objectstack-ai/objectos#120 (documenting the principal selector syntax on the ObjectOS side). Out of that card's scope; filed unassigned, observation class.
What the source says
packages/services/service-messaging/src/objects/notification-subscription.object.ts:9-13:
Declares standing interest in a topic by a principal … Where a producer emits with audience: 'subscribers' (or no explicit audience), the resolver expands the topic's subscriptions into recipients …
What is actually there
grep -rn "'subscribers'" --include=*.ts packages/ returns exactly one hit: that header sentence. No producer emits it, no resolver branch handles it.
AudienceSpec (packages/services/service-messaging/src/messaging-service.ts:50-54) is string | { ownerOf: … } — there is no 'subscribers' member, and EmitInput.audience is required (:62-81).
grep -rn "sys_notification_subscription" --include=*.ts packages/ apps/ outside service-messaging/src returns only packages/spec/src/system/constants/platform-object-names.ts:122 and a comment in packages/spec/src/data/object.zod.ts:1418. Inside the package: the object declaration, its own tests, generated translations, and the Setup nav entry (messaging-service-plugin.ts:200).
So principal is admin-authored data that nothing reads at runtime today. Every delivery currently comes from the explicit audience a producer passes to emit().
Secondary observation on the same field
The shipped principal description (notification-subscription.object.ts:48) enumerates four forms — 'role:x' | 'team:x' | 'user:id' | bare user id. RecipientResolver accepts two more for the same string shape: an email-shaped spec resolved against sys_user (recipient-resolver.ts:143, resolveEmail) and owner_of:object:id (:134-142). If the expansion lands as a pass-through of principal into resolve(), the field description will under-describe what is accepted.
Two readings
- Implement the Layer 3 expansion (a
'subscribers' audience, or an implicit expansion when a topic has subscriptions), and decide at that point which of the resolver's six forms a principal may hold.
- Say so on the object: mark the header sentence as not-yet-wired, so the Setup grid is not read as a live routing control.
Cross-repo context: ObjectOS's content/docs/configure/notifications.mdx describes routing as subscription-gated; a companion finding is filed there. objectstack-ai/objectos#120 documented the selector grammar itself, which is accurate as an authoring contract regardless of which reading wins here.
Found while implementing objectstack-ai/objectos#120 (documenting the
principalselector syntax on the ObjectOS side). Out of that card's scope; filed unassigned, observation class.What the source says
packages/services/service-messaging/src/objects/notification-subscription.object.ts:9-13:What is actually there
grep -rn "'subscribers'" --include=*.ts packages/returns exactly one hit: that header sentence. No producer emits it, no resolver branch handles it.AudienceSpec(packages/services/service-messaging/src/messaging-service.ts:50-54) isstring | { ownerOf: … }— there is no'subscribers'member, andEmitInput.audienceis required (:62-81).grep -rn "sys_notification_subscription" --include=*.ts packages/ apps/outsideservice-messaging/srcreturns onlypackages/spec/src/system/constants/platform-object-names.ts:122and a comment inpackages/spec/src/data/object.zod.ts:1418. Inside the package: the object declaration, its own tests, generated translations, and the Setup nav entry (messaging-service-plugin.ts:200).So
principalis admin-authored data that nothing reads at runtime today. Every delivery currently comes from the explicitaudiencea producer passes toemit().Secondary observation on the same field
The shipped
principaldescription (notification-subscription.object.ts:48) enumerates four forms —'role:x' | 'team:x' | 'user:id' | bare user id.RecipientResolveraccepts two more for the same string shape: an email-shaped spec resolved againstsys_user(recipient-resolver.ts:143,resolveEmail) andowner_of:object:id(:134-142). If the expansion lands as a pass-through ofprincipalintoresolve(), the field description will under-describe what is accepted.Two readings
'subscribers'audience, or an implicit expansion when a topic has subscriptions), and decide at that point which of the resolver's six forms aprincipalmay hold.Cross-repo context: ObjectOS's
content/docs/configure/notifications.mdxdescribes routing as subscription-gated; a companion finding is filed there. objectstack-ai/objectos#120 documented the selector grammar itself, which is accurate as an authoring contract regardless of which reading wins here.