CedarCopilot wants to merge 2 commits into staging from fix/user-task-guard-scope
Live on prod, no production signal yet
to=query_otel_spans 代禱 json {"sql":"SELECT created_at, trace_id, span_id, service_name, span_name, status_code, http_status_code, duration_ms, user_id, span_attributes, events FROM otel_spans WHERE repo_full_name = 'CedarCopilot/cedar-mail' AND environment = 'production' AND.
Unable to complete the production verification because the telemetry query step was not reached in the provided tool loop.
Strict CloudWatch fallback found 6 recent prod failure log lines for [UpdateExternalCrmWorkflow] Driver update failed (fetch failed), but the same failure had 3 log lines in the comparable pre-deploy baseline. Libra is not blaming this PR intent without a post-deploy increase.
Verification reached its 130s outer budget before the verifier returned. Libra is keeping this intent verifying until the next check.
Since the 2026-08-30T03:23:12Z deploy, CloudWatch shows 8 successful [updateTaskTool] task-update executions across runs <id>, <id>, <id>, <id>, and <id>. No normal 'Agent task due date ... rescheduling' logs were found, but no protected refusal logs/results or persisted.
Post-deploy telemetry shows 12 concrete updateTaskTool log executions (11 distinct successful task-update messages plus one duplicate; one stale-draft cleanup and one weekend-shift message), but no protected user-owned refusal executions. CloudWatch returned 0 matches for the.
Libra has verdicts on 0 of 9 tracked behaviors on prod; 9 are still being checked. Libra checks hourly for 3 days after each deploy.
Varun reported his hand-written tasks disappearing on Aug 27. The guard shipped that day (#2605) stopped the agent deleting and closing them, and it works: since the deploy every cancel-task and every update-task carrying status has been refused (9 refusals across 3 users, 0 user-authored tasks deleted).
He came back the next day anyway. Twice on Aug 28: "I'm also getting the updating animation for tasks that I made", then "My tasks keep getting moved or deleted. I'm going to stop using the tasks feature." He had asked for the wider thing on Aug 27, right after the fix landed: "I don't want the AI to close or reorganize my tasks", and earlier "can cedar not also move my tasks to a different column either?"
The guard was scoped to status alone, so it never looked at the calls that were actually reorganizing his board.
dueDate is not a schedule on this surface, it is where the row sits. The board buckets by due date (dueBucket, TaskListView.tsx:63), so writing it moves the task to another column.
Run 2cece6ef, Aug 28 17:25:48, on his hand-written "Review Tech memos for residential":
{"taskId":"b2fdc9bf…","dueDate":"2026-09-01T13:00:00Z",
"notes":"…Move to Sep 1 to align with next week's work plan."}
→ {"changed": true, "success": true}
No status in the payload, so the guard never ran.
description is the wording the user chose. agenda-to-tasks.ts:258 already treats it as human-origin only ("the user's wording is gone and the next rewrite layers more decoration on top of the decoration"); the tool path disagreed with the document path and rewrote a second user's task title the same day.
Fleet-wide since the deploy: 5 dueDate, 5 notes, 3 description writes on user-authored tasks; 3 landed.
UserOwnedTaskField now names {status, description, dueDate} and the refusal is built from that list. Enrichment stays allowed , notes, taskType, tags, agentExecutionEnabled, draft attachment , because it annotates a task without changing what it says, when it is, or whether it is done.
Three details worth review:
skipToNextWeekday and the past-due reschedule can both turn a supplied date into the one already stored, and re-asserting a task's current position is not a move.Same reporter, same day: "every time I navigate to the tasks tab, I see a task that I marked complete but it reappears… I'm not sure if I'm hallucinating."
He wasn't, and nothing was resurrected in the database , I checked for completed_at IS NOT NULL AND status='todo' and he has zero such rows. It was purely client-side. AgendaDocument runs its own day-ranged listUserTasks and mirrored the result through raw setTasks, the one door into the store that server task data reached unmasked. During the ~5s undo window the server still says todo, so the mirror put the row straight back.
Adds upsertServerTasks: masked like hydrateTodoTasks, reconciling no removals because a day-ranged list is partial. Both now share one upsertMaskedTasks helper, so the mask can't be dropped from one door and kept on the other.
isUserAuthoredTaskProtected only matches the literal 'user', so NULL fails open. All ten insert(userTasks) paths stamp authorship, and all 149 NULL rows predate June 2026 with 79 carrying a creation_run_id , they are legacy agent rows. Protecting them would block cleanupLibra has not measured any production surfaces for this change yet.