3.6 KiB
status, system, requirements, created, owners
| status | system | requirements | created | owners | ||
|---|---|---|---|---|---|---|
| draft | integrations |
|
2026-09-23 |
|
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.