hoangsonww / hoangsonww/Diffuse-Native-Apps

Give retention per-capability policies instead of one global window

Open
#10 0 comments 0 reactions 1 assignee Claimed by @hoangsonww View on GitHub
accessibility bug documentation enhancement good first issue help wanted question
Dominant language
Swift
Stars
2
Forks
0
Avg merge
1h 53m
Merged PRs (30d)
14

Description

## Motivation

`RetentionPolicy` (`Packages/DiffuseStorage/Sources/DiffuseStorage/Retention/RetentionPolicy.swift`) exposes exactly one `age`, one `maximumBytes`, one `maximumCount`, and two protection flags, applied uniformly to whole snapshots. Retention is all-or-nothing: a snapshot is kept entire or deleted entire.

That forces a bad trade-off. The most valuable long-horizon signals — OS version history, installed applications, developer toolchain drift — are tiny and change rarely. The bulkiest sections, process lists and full volume inventories, are the ones nobody needs at 90 days. Today, keeping a year of OS-version history means keeping a year of process tables, so users either blow past the 1 GiB budget or lose the history that mattered.

## Proposed Solution

Extend `RetentionPolicy` with an optional per-`CapabilityID` override table, and teach `RetentionPlanner` to emit section-level pruning in addition to whole-snapshot deletion. A pruned snapshot keeps its identity, metadata, and remaining sections, and records the pruned capability as a placeholder section with a `retentionPruned` status — the same mechanism disabled capabilities already use, so the UI, the privacy ledger, and export need no special case.

`RetentionPlan` gains the pruning detail so the existing "this will delete N snapshots" preview can also say what it will thin.

## Acceptance Criteria

- [ ] `RetentionPolicy` carries optional per-capability overrides; the global policy remains the default
- [ ] `RetentionPlanner` can prune sections without deleting the snapshot
- [ ] Pruned sections become placeholders that still render, search, and appear in the privacy ledger
- [ ] The newest snapshot is never pruned, matching the existing never-delete-newest invariant
- [ ] Reversing or loosening a policy never resurrects data — pruning is irreversible and documented as such
- [ ] Kotlin `RetentionPlanner` matches, proven against shared fixtures
- [ ] `Documentation/Storage.md` documents the model

## Additional Context

Invariants to preserve are listed in the README under "Design principles encoded in tests". Skill: `retention`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.