uttrflow / uttrflow/uttrflow-swift

A newly copied picture evicted immediately by the disk budget leaves its PNG orphaned on disk

Open
#777 0 comments 0 reactions 0 assignees View on GitHub
area:clipboard bug P2 performance
Dominant language
Swift
Stars
4
Forks
17
Avg merge
4h 27m
Merged PRs (30d)
286

Description

## Problem

The noticed-picture path writes a PNG before deciding whether the clip survives retention and disk limits. If the new image is dropped immediately, `save()` cannot delete it: cleanup compares images in the previous list with the retained list, and the new file appears in neither. Repeated rejected pictures can consume disk outside the declared budget.

## Evidence

Reviewed `main` at `8d93f5b8574f3c7b8c30086d9c817bf7f5d4827d`. Reproduced against the unchanged production source in an isolated Swift package on macOS, with fake transport or temporary stores as appropriate. These checks assert the observed defect; they are not a claim that the full app test suite passed.

With a temporary store and a deliberately tiny disk budget of one byte:

1. Record three distinct two-byte picture payloads through `record(NoticedClip, keeping:)`.
2. Each call returns zero retained clips.
3. `Images/` contains three files (six bytes).
4. Reopen the store and read clips: the three files remain, because the launch sweep refuses to sweep an empty list.

The data is intentionally tiny to exercise accounting without allocating a real oversized image; the store does not decode these bytes. The same path applies when a new picture exceeds the configured disk quota. This test establishes orphan retention, not a claim about typical screenshot sizes.

## Relevant code

- [Sources/UttrflowClipboard/ClipboardStore.swift:171](https://github.com/uttrflow/uttrflow-swift/blob/8d93f5b8574f3c7b8c30086d9c817bf7f5d4827d/Sources/UttrflowClipboard/ClipboardStore.swift#L171)
- [Sources/UttrflowClipboard/ClipboardStore.swift:362](https://github.com/uttrflow/uttrflow-swift/blob/8d93f5b8574f3c7b8c30086d9c817bf7f5d4827d/Sources/UttrflowClipboard/ClipboardStore.swift#L362)
- [Sources/UttrflowClipboard/ClipboardStore.swift:428](https://github.com/uttrflow/uttrflow-swift/blob/8d93f5b8574f3c7b8c30086d9c817bf7f5d4827d/Sources/UttrflowClipboard/ClipboardStore.swift#L428)
- [Sources/UttrflowClipboard/ClipboardStore.swift:451](https://github.com/uttrflow/uttrflow-swift/blob/8d93f5b8574f3c7b8c30086d9c817bf7f5d4827d/Sources/UttrflowClipboard/ClipboardStore.swift#L451)

## Fix and acceptance criteria

Delete a newly created picture if its index entry is not retained or cannot be persisted, without deleting a previously shared image. Make orphan recovery safe for trustworthy empty indexes. Test immediate eviction, a refused index write, and repeated copies, asserting actual files and byte totals.

## Existing work checked

#404 protects pictures when an index is unreadable. This case has trustworthy empty indexes and newly-created files that never enter either index.

Contributor guide

Open the contributing guide

Research direction

Read Sources/UttrflowClipboard/ClipboardStore.swift around lines 171, 362, 428, and 451, starting from record(NoticedClip, keeping:), then inspect the index and disk-cleanup paths. Reproduce the tiny-budget scenario and add coverage for immediate eviction, refused index writes, and repeated copies; done means actual files and byte totals stay within the budget without deleting shared images.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift
Domain
database, desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.