# Forgejo package prune (retention)

Workplan: `ACTIVITY-WP-0020` · complements `docs/forgejo-backup.md`

## Policy

| Rule | Value |
| --- | --- |
| Versions kept per package | **3** (newest by `created_at`) |
| Package types (phase 1) | `container`, `pypi`, `npm`, `generic` |
| Org scope | `coulomb` |
| Protected versions | Image tags referenced in `railiance-apps` production Helm values / chart defaults |
| Default mode | dry-run (no deletes) |
| Schedule | Weekly Sunday 03:30 UTC via `activity-core` (`weekly-forgejo-package-prune`) |

OCI container layers dominate `forgejo dump` size (~80% of blob zip). Pruning old
tags slows backup growth and shortens chunked-copy duration.

## Operator commands

### 1. Authenticate to the approved token lane

The steady-state credential path is `CCR-2026-0006`: OpenBao lane
`platform/workloads/forgejo/forgejo-admin`, field `API_TOKEN`.

1. Confirm the sanctioned route first:

```bash
warden plan "forgejo admin api token" --json
```

2. Login with an identity allowed to read the lane:

```bash
bao login -method=oidc -path=netkingdom role=forgejo-admin-workload-kv-read
```

3. Run prune normally. If `FORGEJO_TOKEN`, `FORGEJO_ADMIN_TOKEN`,
   `FORGEJO_TOKEN_FILE`, and `FORGEJO_ADMIN_TOKEN_FILE` are unset, the loader
   now resolves the PAT directly from OpenBao.

Do not commit the token or paste it into workplans, State Hub, chat, or shell
history.

### 2. Break-glass overrides

Short-lived overrides are still supported when the lane is unavailable or when
an attended operator session needs an explicit handoff:

```bash
# Option A — token env for one shell session
export FORGEJO_TOKEN='<pat>'
# alias: export FORGEJO_ADMIN_TOKEN='<pat>'

# Option B — explicit file path for one invocation
warden access forgejo-admin-api-token --out "$XDG_RUNTIME_DIR/forgejo-admin.token" --field API_TOKEN
FORGEJO_TOKEN_FILE="$XDG_RUNTIME_DIR/forgejo-admin.token" make forgejo-package-prune-dry-run
rm -f "$XDG_RUNTIME_DIR/forgejo-admin.token"
```

The retired `/tmp/forgejo-tegwick-api-token` drop is no longer the default. Use
it only while unwinding legacy local state:

```bash
FORGEJO_ALLOW_LEGACY_FILE_FALLBACK=1 make forgejo-package-prune-dry-run
```

### 3. Run prune

```bash
cd ~/railiance-platform
make forgejo-package-prune-dry-run   # list would-delete candidates
make forgejo-package-prune           # delete beyond retention depth
```

## Rollback

If a needed tag was removed, restore from the latest Nextcloud `forgejo-dump-*.zip.age`
(`make forgejo-backup` evidence) using `railiance-infra/tools/forgejo-restore-drill.sh`,
or re-push the image from CI.

## Evidence

activity-core posts `forgejo_package_prune` progress to State Hub with non-secret
counts (`deleted_count`, `candidate_count`, `skipped_protected_count`, `errors`).

## Related

- `railiance-apps/docs/forgejo-package-registry.md`
- `docs/forgejo-backup.md`
- `docs/workload-kv-access-lanes.md`
