# Collection history

Source: https://holofolder.com/app/docs/collection-history

See what changed in your collection and safely undo a change.

## Activity in the app

Open **Activity** from the collection's manage menu. Entries are grouped by day and say what happened, with the card, person and local time.

Simple additions and removals are compact receipts. Choose **View changes** for meaningful before/after values such as a printing swap; bulk changes expand a few at a time. A previous member is labelled **Previous member**; an unattributed entry stays **Unknown**. These labels do not invent historical profile names.

**Filters** searches the complete recorded history, including deleted cards. Choose a collection, person, action or inclusive UTC date range. **Older page** and **Newer page** follow server cursors, so long histories stay reachable. Displayed times use your device's timezone.

## Undo a change

Undo works for recorded copy, slot and collection changes, such as adding, moving, assigning, removing or regrading a copy, slot edits, bulk changes and creating a collection. Choose **See what undoing does** to get a preview from the server, then **Undo this change** to apply it. If the change can no longer be undone, the preview says so and offers nothing to apply.

When a change removed cards, tick the ones to bring back. They return to your collection as Unassigned copies, not to a pocket. Undoing the creation of your default binder asks which binder should open first instead.

The server checks current access and later changes before applying. A newer edit to the same data is a conflict, and there is no force overwrite. Undo adds a new history entry linked to the original, and the original shows **Undone** once its linked undo is on the loaded page.

Settings, sharing and appearance changes cannot be undone from Activity.

## Offline and connection failures

Previously opened activity pages remain available on this device with their last-update time. They are saved pages, not a complete offline history. Reconnect to load another page or start an undo. Pending local edits must sync first.

A confirmed undo is saved on the device before it is sent, so a lost connection or reload does not lose it. The app shows **Undo saved on this device** until the server confirms it, then checks your collection again before showing **Undone**. Use **Try again** or **Check my collection** to continue; a retry sends the same request and cannot apply it twice. If the server rejects the undo because your collection changed, nothing was applied. You can then **Discard this undo** and **Start a new undo** from a fresh preview.

## REST and MCP

Developer access requires current entitlement, credential grants and owner/linked-partner access. The app uses its signed-in session. Responses are private and use `no-store`. Public share links have no private Activity.

`list_collection_audit` (`GET /collection/audit`) and `get_collection_audit` (`GET /collection/audit/{id}`) require `collection:read`. Event IDs are strings. Lists return `data` and `nextCursor`, with up to 100 entries. Keep the same filters when following a cursor. Filters include `collectionId`, `pokemonId` and `cardId` (matched against slot targets, owned copies and wanted cards), `inventoryItemId`, `slotId`, `actorId`, `action`, `since`, `until` and `recoveryOfEventId`. The last filter finds undo events linked to an original. An undo entry also includes `recovery_of_event_id`.

Undo through REST and MCP uses the native storage recovery operations (`preview_storage_recovery`, `apply_storage_recovery` and their v2 forms), described below. Each entry's `changes` lists the rows it changed, reduced to the fields Activity shows. Private certificates, label assets, uploaded artwork references and share tokens are never returned in history or recovery responses.

Every write records one entry as part of the same transaction, so history and the collection never disagree. Binder renames, reordering, layout, sharing, appearance and settings saves are recorded too.

## Native storage recovery

The app and the registered REST/MCP operations use the same recovery executor. A preview lists public-safe changes and explicit conflict reasons; applying it needs the exact reviewed plan, explicit confirmation and a retry-stable operation ID. There is no offline optimistic restoration and no automatic replacement request.

### Recovery rejection

The v1/v2 apply contract declares REST `409 storage_recovery_rejected`, or MCP `isError:true`, only for a committed strict `error.rejection` containing `outcome:"rejected"`, the original `operationId`, known `code` and `inventoryRevision`. Codes are `recovery_plan_conflict` and `recovery_dependency_conflict`. Arbitrary 409/SQL errors, missing receipts, cancellation and billing/access errors are not noncommit proof. Exact accepted/rejected replay requires current authority and precedes mutable plan reconstruction.

After a committed rejection, the app reads your current collection again before offering **Discard this undo**. A discarded undo is kept as discarded, never as applied. A new undo needs a new preview, explicit confirmation and a new operation ID. Unknown and accepted requests can only be retried or checked, never discarded. No private inverse, evidence, certificates or assets are exposed.

### Find an exact operation

REST `GET /app/api/v1/collection/audit?operationId=synthetic-original-operation` and MCP `list_collection_audit` with `{"operationId":"synthetic-original-operation"}` find the exact original operation within your currently authorized history. The example ID is synthetic. Keep the same filters when following `nextCursor`, then use `get_collection_audit` with the selected event ID to inspect it. An empty result does not prove that a command failed. Multiple events require choosing an exact event; never use the newest event as a guessed inverse. Operation IDs are bounded opaque strings, up to 200 characters without surrounding whitespace or line breaks. Private recovery evidence remains server-only.