When an assignee on a task isn't in the plan's M365 group member listing
(guests, ex-members, cross-tenant collaborators), we previously leaked the
raw GUID into preview/result cards. Now we fall back to /users/{id} via the
delegated User.ReadBasic.All scope, cache the resolved name on the bot
instance, and show "사용자 {short-guid}…" only if every lookup fails.
Also: allow assigneeUserIds to retain ids that are already on the task even
if not in the current member list, so additive assignments don't strip
existing assignees. Prompt rule added: never put GUIDs into user-facing
text fields.
NOTE: requires User.ReadBasic.All delegated permission on the AAD app
(add + grant admin consent; users must re-login to pick up the new scope).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Classifier now receives a ConversationContext: a compact LLM-maintained
WorkingMemory (topic/focusPlan/lastTaskTitle/openLoops/notes), the last 2
raw turns, and a pendingDigest derived each turn from the pending action.
The LLM emits an optional memoryUpdate patch alongside its action in the
same tool call (no extra API hop). Volatile fields decay after 10 min idle,
notes truncate at 500 chars, raw turns ring-buffer at 2, openLoops cap at 5.
Logout wipes everything.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Confirmation preview enumerates every side-effect (plan-level label creation,
assignee diff, bucket move, checklist truncation) so nothing happens that
wasn't shown on the card. Explicit-but-missing labels trigger a 3-button
choice (register / drop / cancel) since creating them mutates the Plan's
categoryDescriptions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>