Project rule: every create_task must be assigned, and only the signed-in
user can ever be the assignee. PlannerBot coerces non-self ids to self
and the preview card surfaces the coercion with a 🔒 advisory line so the
user can see exactly what was substituted before confirm.
- prompt.ts: rewrites the 할당 section — LLM must always fill assigneeUserIds
with the isMe user on create_task, never assign others, never ask_clarify
about non-self assignees
- PlannerBot.ts: derives selfId from plan.members, computes coerced state
and attempted non-self names for the card, forces finalAssigneeIds to
[selfId] on create_task and on any update_task that signals an
assignment change
- confirmationCard.ts: ActionContext gains assignmentCoercedToSelf +
attemptedNonSelfNames; renders the advisory as a warning line
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>