@@ -80,6 +80,27 @@ function makeShareId(): string {
8080/** System-elevated context for the plugin's own queries / mutations. */
8181const SYSTEM_CTX = { isSystem : true , positions : [ ] , permissions : [ ] } as const ;
8282
83+ /**
84+ * [ADR-0138 D8] Recipient values `RecordShareRecipientType` no longer declares,
85+ * each with the refusal {@link SharingService.grant} answers when one still
86+ * arrives at runtime — a REST body, an untyped caller. A retired value is told
87+ * where its access actually lives; every other non-`user` value keeps the
88+ * generic refusal in `grant()`. Keyed by the value exactly as a caller sends it.
89+ */
90+ const RETIRED_RECIPIENT_TYPE_REFUSALS : Readonly < Record < string , string > > = {
91+ guest :
92+ "recipientType 'guest' was removed (ADR-0138 D8) — a record share to the anonymous principal "
93+ + 'was never honoured, because guest access flows through the guest position and share links '
94+ + '(ADR-0090 D11). Expose the record through a public form or a share link instead.' ,
95+ } ;
96+
97+ /** The retired-value refusal for a `recipientType` a caller sent, or `undefined`. */
98+ function retiredRecipientTypeRefusal ( value : unknown ) : string | undefined {
99+ return typeof value === 'string' && Object . prototype . hasOwnProperty . call ( RETIRED_RECIPIENT_TYPE_REFUSALS , value )
100+ ? RETIRED_RECIPIENT_TYPE_REFUSALS [ value ]
101+ : undefined ;
102+ }
103+
83104/**
84105 * Owner field convention. Hard-coded to `owner_id` for MVP — the
85106 * sharing model in Salesforce / ServiceNow / Dynamics all assume a
@@ -1346,9 +1367,15 @@ export class SharingService implements ISharingService {
13461367 // (ADR-0078). Group / business-unit principals are delivered via sharing
13471368 // rules, whose evaluator expands them into per-user rows.
13481369 if ( recipientType !== 'user' ) {
1370+ // [ADR-0138 D8] A retired value no longer typechecks, yet still reaches
1371+ // here untyped. It is told where guest access lives, never that a sharing
1372+ // rule delivers it: the rule vocabulary retired the same recipient.
1373+ const retired = retiredRecipientTypeRefusal ( recipientType ) ;
13491374 throw new Error (
1350- `VALIDATION_FAILED: recipientType must be 'user' (received ${ JSON . stringify ( recipientType ) } ) — `
1351- + `group/position recipients are delivered via sharing rules (ADR-0111 D7)` ,
1375+ retired !== undefined
1376+ ? `VALIDATION_FAILED: ${ retired } `
1377+ : `VALIDATION_FAILED: recipientType must be 'user' (received ${ JSON . stringify ( recipientType ) } ) — `
1378+ + `group/position recipients are delivered via sharing rules (ADR-0111 D7)` ,
13521379 ) ;
13531380 }
13541381 // Validate BEFORE any write. Previously anything at all was persisted
0 commit comments