Retention: prune old report files in DATA_DIR #54

Closed
opened 2026-09-21 09:47:42 +02:00 by clawbot · 2 comments
Collaborator

Problem

internal/reportbuf writes reports-<timestamp>.jsonl.zst files to DATA_DIR and never removes any. #20 adds a hard cap that rejects writes once the directory is full, which bounds growth but turns a full disk into a permanent outage until an operator deletes files by hand.

Definition of done

  • A retention setting (age and/or total size) prunes the oldest report files on a timer and before the #20 cap rejects a write, so the cap is reached only if retention is disabled.
  • Defaults are documented in backend/README.md and configurable via the existing viper conventions.
  • Unit tests cover: oldest file removed first; nothing removed under the limit; a file currently being written is never removed.
  • make check green. TODO.md updated in the same commit. Commit title ends (closes #N).

Post-1.0: the 1.0 bound is the cap in #20; this issue makes the bound operable.

model: claude-fable-5

## Problem `internal/reportbuf` writes `reports-<timestamp>.jsonl.zst` files to `DATA_DIR` and never removes any. https://git.eeqj.de/sneak/netwatch/issues/20 adds a hard cap that rejects writes once the directory is full, which bounds growth but turns a full disk into a permanent outage until an operator deletes files by hand. ## Definition of done - [ ] A retention setting (age and/or total size) prunes the oldest report files on a timer and before the https://git.eeqj.de/sneak/netwatch/issues/20 cap rejects a write, so the cap is reached only if retention is disabled. - [ ] Defaults are documented in `backend/README.md` and configurable via the existing viper conventions. - [ ] Unit tests cover: oldest file removed first; nothing removed under the limit; a file currently being written is never removed. - [ ] `make check` green. `TODO.md` updated in the same commit. Commit title ends ` (closes #N)`. Post-1.0: the 1.0 bound is the cap in https://git.eeqj.de/sneak/netwatch/issues/20; this issue makes the bound operable. model: claude-fable-5
clawbot self-assigned this 2026-09-21 09:47:42 +02:00
Author
Collaborator

Plan. The report files' size cap, DATA_DIR_MAX_BYTES (default 1 GiB), stays the only size setting; it becomes the amount of reports kept instead of a wall that refuses new ones.

  1. When storing a report would take the report files past DATA_DIR_MAX_BYTES, internal/reportbuf first deletes the oldest report files (names sort by time) until it fits, and stores the report. It refuses with 507 only when it still cannot fit with every report file that may be deleted gone, which takes reports not yet written that alone fill the cap.
  2. A report file still being written is never deleted, and a file is no longer counted once deleted. At start, files already past the cap (the cap lowered since the last run) are pruned the same way.
  3. No timer and no age setting: pruning happens exactly when room is needed, so a timer would add nothing. No switch to turn it off: an operator who wants to keep more sets a bigger cap. This amends the issue's definition of done.
  4. Each deletion is logged at info with the file name and size; a failed deletion is logged as an error and counts as not freed.
  5. Tests: oldest file removed first; nothing removed under the cap; a file being written is never removed; the 507 case. Small files and a small cap, nothing near 1 GiB.
  6. backend/README.md and the DATA_DIR_MAX_BYTES line in the root README section "Running under upaas" say that the oldest reports are deleted to stay under it.

Model: opus-5-5

Plan. The report files' size cap, `DATA_DIR_MAX_BYTES` (default 1 GiB), stays the only size setting; it becomes the amount of reports kept instead of a wall that refuses new ones. 1. When storing a report would take the report files past `DATA_DIR_MAX_BYTES`, `internal/reportbuf` first deletes the oldest report files (names sort by time) until it fits, and stores the report. It refuses with 507 only when it still cannot fit with every report file that may be deleted gone, which takes reports not yet written that alone fill the cap. 2. A report file still being written is never deleted, and a file is no longer counted once deleted. At start, files already past the cap (the cap lowered since the last run) are pruned the same way. 3. No timer and no age setting: pruning happens exactly when room is needed, so a timer would add nothing. No switch to turn it off: an operator who wants to keep more sets a bigger cap. This amends the issue's definition of done. 4. Each deletion is logged at info with the file name and size; a failed deletion is logged as an error and counts as not freed. 5. Tests: oldest file removed first; nothing removed under the cap; a file being written is never removed; the 507 case. Small files and a small cap, nothing near 1 GiB. 6. `backend/README.md` and the `DATA_DIR_MAX_BYTES` line in the root README section "Running under upaas" say that the oldest reports are deleted to stay under it. Model: opus-5-5
Author
Collaborator

Built in #90: the oldest report files are deleted to keep them under DATA_DIR_MAX_BYTES, at start and whenever a report needs room, and a report is refused with 507 only when the reports not yet written fill the cap on their own. One deviation from the plan: a report file already deleted by hand counts as freed.

Model: opus-5-5

Built in https://git.eeqj.de/sneak/netwatch/pulls/90: the oldest report files are deleted to keep them under `DATA_DIR_MAX_BYTES`, at start and whenever a report needs room, and a report is refused with 507 only when the reports not yet written fill the cap on their own. One deviation from the plan: a report file already deleted by hand counts as freed. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/netwatch#54