Files
kandev/docs/specs/integrations/system-design/github-review-task-cleanup.md
T
2026-09-23 17:39:51 +01:00

3.6 KiB

status, system, requirements, created, owners
status system requirements created owners
draft integrations
REQ-INTEGRATIONS-GITHUB-REVIEW-CLEANUP-001
2026-09-23
kandev

GitHub review task cleanup system design

Purpose and boundaries

internal/github owns review-watch deduplication, cleanup policy, and GitHub feedback requests. The task repository owns tasks.archived_at. The cleanup selector reads that state; it does not change task archive state. Shared provider backoff remains a Platform contract.

Requirement mapping

Requirement Design section
REQ-INTEGRATIONS-GITHUB-REVIEW-CLEANUP-001 Eligibility; Cleanup flow; Explicit actions

Eligibility

Add selectors for scheduled review cleanup in internal/github/store.go. Select a review-task record when its task_id is empty, its task row is missing, or its task row exists with archived_at IS NULL. Exclude a record only when a matching task row is archived. Use a left join or an equivalent predicate so missing tasks and incomplete reservations remain visible.

Keep ListReviewPRTasksByWatch and ListAllReviewPRTasks as complete inventory methods. Watch deletion, reset, and explicit cleanup use those inventories. Scheduled per-watch cleanup and the scheduled global orphan sweep use the new eligible selectors. The global sweep still skips enabled-watch records that the per-watch pass handled in the same cycle. A disabled watch remains eligible through the global sweep.

The dedup row stays in storage while the task is archived. Unarchive makes the same row eligible again, so the watch cannot create a duplicate task for that pull request. No schema migration or backfill is required.

Cleanup flow

Before a scheduled Auto feedback request, check the conditions that retain a task regardless of PR state: an enabled lifecycle prompt and a user-authored message. If either is present, skip feedback and keep the task and dedup row. If either local check fails, fail closed and keep both. Keep Always delete and Never behavior unchanged. Incomplete reservations have no task to inspect and retain their terminal-PR cleanup path.

Eligibility comes from the database before client resolution where practical. An empty eligible set does not resolve a credential or call GitHub. The poller must check eligibility again on each scheduled pass; archive and unarchive take effect without a service restart. A task archived after selection may finish an already-started request, but later passes exclude it.

Explicit actions

The manual all-workspace and workspace cleanup endpoints continue to inspect archived records under each watch's policy. Watch deletion and reset continue to enumerate archived tasks and apply their existing destructive behavior. Do not route these actions through a scheduled-only selector.

Failure and recovery

A missing task row remains visible to the cleanup path that removes stale dedup records. A task-not-found result from the session checker counts as no user-authored message so cleanup can remove its stale dedup record. Other task-retention check failures leave both task and record intact. A watch read failure leaves its records untouched for that cycle. Provider failures follow the Platform backoff design.

Verification

SQLite-backed service and poller tests cover enabled and disabled watches, archived and active tasks in one batch, incomplete and missing-task records, unarchive, Auto retention, and explicit actions. A counting GitHub client asserts feedback call counts over repeated scheduled cycles.