get-convex / get-convex/agent

Expose age-only orphan-file cleanup without bypassing the final reference check

Open
#361 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
349
Forks
92
Avg merge
3d 10h
Merged PRs (30d)
24

Description

`@convex-dev/agent@0.7.1` protects recently registered/detached files for 24 hours. That default is useful, but a bounded development reset has no supported way to enumerate recent unreferenced files and then delete them while retaining the final reference check.

`getFilesToDelete` only returns zero-reference files old enough to pass the grace period. `deleteFiles({ force: true })` bypasses both grace and reference ownership. Those controls cannot express “ignore age, but never delete a file that has acquired a reference”.

## Reproduction and expected capability

Using the component test harness (`@convex-dev/agent/test` plus `convex-test` with transaction limits):

1. Freeze time; insert two `files` rows with distinct `hash`/`storageId`, `refcount:0`, and `lastTouchedAt:now`.
2. `files.getFilesToDelete({paginationOpts:{cursor:null,numItems:2}})` returns neither recent orphan.
3. In a proposed age-only enumeration mode, receive the two orphan IDs.
4. Before deletion, call `files.copyFile` for one of those IDs, which increments its reference count.
5. An age-only deletion mode should delete only the still-zero-reference row. The newly referenced row must remain. Current `force: true` deletion also deletes the referenced row.

The exact 24-hour boundary and the existing default/explicit-force semantics were independently verified against native source and distributed functions. This is a request for a distinct capability, not a claim that current documented force semantics are incorrect.

## Local compatibility approach

We add optional enumeration `force` to skip only the age predicate while preserving the indexed `refcount = 0` filter, plus a distinct deletion `ignoreGracePeriod` option that keeps the final reference check. Our application limits this capability to development and uses bounded pages/deletions. It never uses deletion `force` for this path.

The local regression suite proves the 24-hour boundary, recent-orphan enumeration, exclusion of referenced files, reference acquisition between enumeration and deletion, default behavior, invalid pagination refusal and bounded batches for both source and distribution. Application-specific numeric caps need not become universal package limits.

Please consider an explicit age-only cleanup API, independently of force-delete semantics, with documented pagination/deletion bounds. Adoption of a released equivalent would let us remove our local compatibility hunks while keeping the exact reference-race regressions.

Contributor guide

Open the contributing guide

Research direction

Start with the getFilesToDelete, deleteFiles, and copyFile entry points and the component test harness using @convex-dev/agent/test with convex-test. Verify the existing grace-period, reference-count, force, pagination, and batch behaviors before defining the separate age-only options. Done means recent zero-reference files can be enumerated and safely deleted while a reference acquired between those steps prevents deletion, with source and distribution regressions passing.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend-api-design, databases
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.