# Retention Sweep

> REPORT-ONLY PDPA data-retention analysis for ActiveCAMT. Given candidate retention durations, it reports how many rows WOULD be affected per table — it NEVER deletes or anonymizes anything. A working purge requires a written retention policy + a /safe-deploy migration first. Use to scope a retention policy, not to enforce one.

- Skill: `daydeda/retention-sweep` (Agent Skill)
- Install (CLI): `npx skillmds@latest add daydeda/retention-sweep`
- Raw SKILL.md: https://api.skillmd.com/api/skills/daydeda/retention-sweep/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: daydeda (https://skillmd.com/u/daydeda)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/daydeda/retention-sweep

---


# Retention Sweep (ActiveCAMT) — DRY-RUN / REPORT-ONLY

PDPA expects data minimization: personal data shouldn't be kept past its purpose.
This skill helps you *scope* a retention policy by reporting impact. **It does not, and
will not, delete or modify any data.** Enforcement is deliberately out of scope until a
policy exists, because prod deletion is the single most dangerous operation in this repo
(a `DELETE` once wiped the whole activity feed; see `/safe-deploy` and `src/db/guard.ts`).

## Why it's report-only
- **No retention policy is defined yet** — how long to keep attendance / medical fields / form submissions / shop orders is a decision the team must make, not one to infer.
- A purge against prod is irreversible and high-risk; it must go through `/safe-deploy` with the DELETE-rule scrutiny, never an ad-hoc script.

## What it does now
Given candidate durations from the user (e.g. "attendance > 2 years", "inactive-student medical fields > 1 year"), run **read-only `SELECT COUNT(*)`** per relevant table to report what *would* be affected:
- `attendance` (by check-in/event date), `formSubmissions`, `scoreHistory`, `shopOrders` (+ items), and **medical fields on `users`** for long-inactive accounts.
Present a table: table · cutoff · rows affected. Then STOP.

## NEVER
- Never run `DELETE` / `UPDATE` / `TRUNCATE` against any database from this skill. Counts only.
- Never touch `audit_logs` — it's retained on a separate legal/tamper-evidence basis (see `/audit-verify`).
- Prefer counting against the **local** DB (`/db-local`); if pointed at prod, issue **only** `SELECT COUNT`, never a write.

## When a policy IS decided (handoff, not done here)
Any future enforcement must: be a written policy first; **anonymize/convert-in-place rather than hard-delete** where feasible (e.g. null the medical fields, keep the attendance row); be idempotent + tightly scoped; require `CONFIRM=yes` per `guard.ts`; exclude `audit_logs`; and ship via `/safe-deploy`. Build that as a separate, reviewed migration — not from this skill.

## Output
An impact-count table per proposed cutoff, and an explicit statement that **nothing was deleted** and a written policy + `/safe-deploy` migration are required before any purge.

