# Retention

A **retention rule** keeps only the newest versions of the files under a directory. Older versions keep their commits and history, but Oak stops serving their content and reclaims the storage. It's for directories whose history you don't need byte for byte: build artifacts, exported datasets, rendered assets, large binaries that change often.

```bash
oak retention set build/artifacts --keep 3   # the newest 3 versions of each file
oak retention                                # list rules and what they've expired
oak retention remove build/artifacts
```

Retention is in preview. An admin turns it on per repository; until then the commands answer that retention isn't on for the repo.

## What counts as a version

A version is a distinct content of a file on `main`. Walking `main` from the newest commit back, the first N distinct contents of each path keep their bytes and older ones expire. A file reverted to an old content counts that content as new again, so it's kept.

The deepest matching rule wins: `assets/` can keep 5 versions while `assets/raw/` keeps 1. A rule for `/` covers the whole repository.

Commits on branches don't count as versions, but their content under a rule expires too once it's old and no longer in use, so editing a file 30 times on a branch doesn't keep 30 copies.

## What is always kept

- **Everything an open branch or a release points at.** The current tree of `main`, of every open branch, and of every tagged commit is complete. A closed branch's old content can expire like any other history.
- **Content a file outside the rule uses.** Oak stores content once per organization, so if the same bytes are also in a directory without a rule, they stay.
- **Recent content.** A version newer than 24 hours keeps its bytes even if it's past the limit.

## What happens to an expired version

- **History is untouched.** Commits, trees and hashes stay exactly as they were, so `oak log`, blame, and every hash check work as before. Only the bytes of the old version go.
- **Clone and pull skip it.** They report the versions they skipped (`N historical file version(s) are no longer stored on the server`), and checking out an old commit leaves those files out. `oak clone --shallow` never needs them.
- **The web and raw API say so.** Opening an expired version shows that it expired; `GET /api/:owner/:name/raw/:commit/*path` answers `410 Gone`.
- **Storage is reclaimed after 7 days.** Until then, removing or loosening the rule brings the versions back. After that, the bytes are gone for good.

Older Oak CLIs can't skip expired versions, so a full clone or a pull that needs them fails with a message asking you to upgrade (or to clone `--shallow`).

## Managing rules

Organization owners and admins change rules, from the repository's **Settings → Retention** or the CLI. Every change is in the organization's audit log, with the rule before and after. Anyone who can read the repository can list the rules.

```bash
oak retention --json                        # rules, expired counts and bytes, can_edit
oak retention set / --keep 100 --repo acme/data
```

Rules take effect on the next retention run, which a change queues right away; repositories are also rechecked daily.

The same operations are on the [HTTP API](/docs/api): `GET`, `PUT` (`{"path", "keep_versions"}`) and `DELETE ?path=` on `/api/:owner/:name/retention`.
