From 9cfac94aa4241ca043b6c6573365387a47cfb8aa Mon Sep 17 00:00:00 2001 From: Noa Flaherty Date: Sat, 28 Feb 2026 22:49:30 -0500 Subject: [PATCH] feat: propagate guardianPrincipalId through runtime contexts Co-Authored-By: Claude Opus 4.6 --- assistant/src/daemon/session-runtime-assembly.ts | 2 ++ assistant/src/runtime/actor-trust-resolver.ts | 5 +++++ assistant/src/runtime/guardian-context-resolver.ts | 4 ++++ assistant/src/runtime/local-actor-identity.ts | 1 + 4 files changed, 12 insertions(+) diff --git a/assistant/src/daemon/session-runtime-assembly.ts b/assistant/src/daemon/session-runtime-assembly.ts index 1a525eb7f3a..4fec7b3cc5a 100644 --- a/assistant/src/daemon/session-runtime-assembly.ts +++ b/assistant/src/daemon/session-runtime-assembly.ts @@ -38,6 +38,8 @@ export interface GuardianRuntimeContext { trustClass: 'guardian' | 'trusted_contact' | 'unknown'; guardianChatId?: string; guardianExternalUserId?: string; + /** Canonical principal ID for the guardian binding. Nullable for backward compatibility — M5 will make this required. */ + guardianPrincipalId?: string | null; requesterIdentifier?: string; requesterDisplayName?: string; requesterSenderDisplayName?: string; diff --git a/assistant/src/runtime/actor-trust-resolver.ts b/assistant/src/runtime/actor-trust-resolver.ts index 60ae337fc57..9034fb6baa7 100644 --- a/assistant/src/runtime/actor-trust-resolver.ts +++ b/assistant/src/runtime/actor-trust-resolver.ts @@ -35,6 +35,8 @@ export interface ActorTrustContext { guardianExternalUserId: string; guardianDeliveryChatId: string | null; } | null; + /** Canonical principal ID from the guardian binding. Nullable for backward compatibility — M5 will make this required. */ + guardianPrincipalId?: string | null; /** Ingress member record, if any, for this sender. */ memberRecord: IngressMember | null; /** Trust classification. */ @@ -102,6 +104,7 @@ export function resolveActorTrust(input: ResolveActorTrustInput): ActorTrustCont return { canonicalSenderId: null, guardianBindingMatch: null, + guardianPrincipalId: undefined, memberRecord: null, trustClass: 'unknown', actorMetadata: { @@ -181,6 +184,7 @@ export function resolveActorTrust(input: ResolveActorTrustInput): ActorTrustCont return { canonicalSenderId, guardianBindingMatch, + guardianPrincipalId: binding?.guardianPrincipalId ?? undefined, memberRecord, trustClass, actorMetadata: { @@ -210,6 +214,7 @@ export function toGuardianRuntimeContextFromTrust( guardianChatId: ctx.guardianBindingMatch?.guardianDeliveryChatId ?? (ctx.trustClass === 'guardian' ? externalChatId : undefined), guardianExternalUserId: ctx.guardianBindingMatch?.guardianExternalUserId, + guardianPrincipalId: ctx.guardianPrincipalId, requesterIdentifier: ctx.actorMetadata.identifier, requesterDisplayName: ctx.actorMetadata.displayName, requesterSenderDisplayName: ctx.actorMetadata.senderDisplayName, diff --git a/assistant/src/runtime/guardian-context-resolver.ts b/assistant/src/runtime/guardian-context-resolver.ts index 3d0a2c724b0..62102ed37e3 100644 --- a/assistant/src/runtime/guardian-context-resolver.ts +++ b/assistant/src/runtime/guardian-context-resolver.ts @@ -24,6 +24,8 @@ export interface GuardianContext { trustClass: ActorTrustClass; guardianChatId?: string; guardianExternalUserId?: string; + /** Canonical principal ID from the guardian binding. Nullable for backward compatibility — M5 will make this required. */ + guardianPrincipalId?: string | null; requesterIdentifier?: string; requesterDisplayName?: string; requesterSenderDisplayName?: string; @@ -50,6 +52,7 @@ export function resolveGuardianContext(input: ResolveGuardianContextInput): Guar guardianChatId: trust.guardianBindingMatch?.guardianDeliveryChatId ?? (trust.trustClass === 'guardian' ? input.externalChatId : undefined), guardianExternalUserId: canonicalGuardianExternalUserId, + guardianPrincipalId: trust.guardianPrincipalId, requesterIdentifier: trust.actorMetadata.identifier, requesterDisplayName: trust.actorMetadata.displayName, requesterSenderDisplayName: trust.actorMetadata.senderDisplayName, @@ -150,6 +153,7 @@ export function toGuardianRuntimeContext(sourceChannel: ChannelId, ctx: Guardian trustClass: ctx.trustClass, guardianChatId: ctx.guardianChatId, guardianExternalUserId: ctx.guardianExternalUserId, + guardianPrincipalId: ctx.guardianPrincipalId, requesterIdentifier: ctx.requesterIdentifier, requesterDisplayName: ctx.requesterDisplayName, requesterSenderDisplayName: ctx.requesterSenderDisplayName, diff --git a/assistant/src/runtime/local-actor-identity.ts b/assistant/src/runtime/local-actor-identity.ts index 0224390ccf2..53aa3ce908e 100644 --- a/assistant/src/runtime/local-actor-identity.ts +++ b/assistant/src/runtime/local-actor-identity.ts @@ -52,6 +52,7 @@ export function resolveLocalIpcGuardianContext( return { sourceChannel, trustClass: 'guardian', + guardianPrincipalId: undefined, }; }