WordloopWordloop
WorkMeeting RecordingTechnical Design DocMilestones08 Live Tasks And Reconciliation

Core — Task Reconciliation

source field ownership tracking (user/system), PUT /meetings/:id/tasks/system reconciliation semantics, and TaskEvent broadcast during the live session.

Core — Task Reconciliation

Owner: Core Engineer Domain: core Complexity: M Prerequisite: Milestone 04 merged

When this slice is complete, every task tracks whether its fields are source: system (generated, unedited) or source: user (user-created, or a system task the user has edited or completed). During an active recording, task create/update/complete/delete fan out as com.wordloop.task.v1 events. PUT /meetings/{id}/tasks/system reconciles the final generated candidate set against live drafts and user edits: unedited system tasks absent from the new set are removed, user-owned tasks and edits are preserved by identity (not duplicated), and a task the user deleted is reported back as an explicit conflict rather than silently resurrected.

Required Capabilities

  • POST /tasks { content, meeting_id, source } creates a task with the given source (user or system, service auth required for system).
  • PATCH /tasks/{id} on any field — including marking a task completed — promotes a source: system task to source: user.
  • DELETE /tasks/{id} removes the task.
  • GET /tasks?meeting_id={id}&filter=all lists all tasks for the meeting.
  • Every create/update/delete on a meeting-bound task broadcasts com.wordloop.task.v1 { meeting_id, task, action } to the meeting's live session.
  • PUT /meetings/{id}/tasks/system { tasks: [...] } reconciles the final candidate set: a candidate matching an existing live draft by content keeps that draft's identity instead of delete+insert; unmatched drafts are replaced; user-created and user-edited tasks are preserved and not duplicated even when a final candidate matches their content.
  • A final candidate matching a task the user deleted is not silently recreated — it is reported in the response's conflicts[] with reason: "deleted_by_user".
  • PUT /meetings/{id}/tasks/system responds {reconciled: int, conflicts: [{content, reason}]} and is idempotent — re-running it with the same candidate set does not change the task set again.

Dependencies

  • Milestone 04 (live-transcript-to-final-rebuild) must be merged — the live recording WebSocket session used to exercise task events during an active session.

Domain Notes

Reconciliation is identity-preserving, not delete-and-recreate: a final candidate whose content matches an existing task (live draft, or user-owned) keeps that task's row and id. This is what lets a user-owned edit or completion survive finalization even though the final generated set never mentions the edited content verbatim in the same words the user typed.

Test Cases

Test cases map to tests/bets/meeting-recording/test_milestone_08_live_tasks_and_reconciliation.py. Run via ./dev test bet meeting-recording.

TestLocationAssertion
test_draft_tasks_appear_during_live_transcripttest_milestone_08A source: system task created via the service write-back during an active recording fans out as com.wordloop.task.v1 { action: created } and is listed with source: system.
test_user_can_create_edit_complete_and_delete_taskstest_milestone_08User task create, content edit, completion, and delete each succeed and are reflected in GET /tasks/{id}; the live session sees the CRUD sequence as ["created", "updated", "updated", "deleted"] task.v1 events.
test_user_owned_task_fields_are_trackedtest_milestone_08Editing a source: system task's content promotes it to source: user; completing a source: system task also promotes it; an untouched generated task stays source: system.
test_final_rebuild_reconciles_generated_task_candidatestest_milestone_08A final candidate set is reconciled against live drafts: a matching candidate keeps the existing task's id (case/whitespace-insensitive match), an unmatched draft is replaced, a brand-new candidate is added as source: system; re-running reconciliation with the same candidates is idempotent.
test_user_created_tasks_survive_final_reconciliationtest_milestone_08User-created tasks (including one whose content matches a final candidate) remain after reconciliation with source: user, are not duplicated, and only the genuinely new candidate counts toward reconciled.
test_user_edits_are_not_overwritten_by_final_generationtest_milestone_08A user-edited task's content and a user-completed task's status both survive reconciliation unchanged, without being duplicated by a matching final candidate.
test_deleted_user_owned_tasks_do_not_reappear_silentlytest_milestone_08A user-deleted task (whether originally user- or system-owned) does not reappear after reconciliation; the response's conflicts[] reports each as reason: "deleted_by_user" rather than dropping them silently.

Completion Checklist

  • Code merged and deployed
  • Bet progress tests pass (./dev test bet meeting-recording)
  • Permanent service tests implemented per testing strategy
  • Code review completed
  • API review completed (PUT /meetings/{id}/tasks/system reconciliation contract)
  • Testing review completed
  • System documentation updated (as applicable)

On this page