Skip to content

feat(history): add automatic transcription history clearing (#463)#504

Open
devzahirul wants to merge 4 commits into
altic-dev:mainfrom
devzahirul:feat/463-auto-clear-history
Open

feat(history): add automatic transcription history clearing (#463)#504
devzahirul wants to merge 4 commits into
altic-dev:mainfrom
devzahirul:feat/463-auto-clear-history

Conversation

@devzahirul

@devzahirul devzahirul commented Jul 2, 2026

Copy link
Copy Markdown

Description

Adds an Automatically Clear History setting so users who dictate sensitive content don't have to remember to clear transcription history manually. Options: Never (default, current behavior), End of Day, After 7 Days, After 30 Days, After 90 Days.

Implemented as retention-based pruning rather than a scheduled wipe (the app can't rely on being awake at a scheduled moment): entries older than the selected window are deleted at store load, before each new entry is added, at midnight while running (via NSCalendarDayChanged), and immediately when the user tightens the interval. Cutoffs are anchored to startOfDay, so a retained day never partially expires ("After 7 Days" keeps 7 full calendar days plus today). Pruned entries also delete their saved dictation audio via DictationAudioHistoryStore, and the sidebar selection is repaired if the selected entry expires.

Changes:

  • SettingsStore — new HistoryAutoClearInterval enum (display name, help text, cutoffDate) and persisted historyAutoClearInterval setting, included in backup export/restore as an optional SettingsBackupPayload field.
  • TranscriptionHistoryStore — new pruneExpiredEntries(); called from init, addEntry, and a calendar-day-change observer.
  • SettingsView — picker row under the history toggles. If changing the setting would immediately delete existing entries, a confirmation alert (matching the existing audio-budget prune flow) states how many entries are affected; Cancel leaves the setting untouched. The row is disabled while Save Transcription History is off.
  • Tests — HistoryAutoClearIntervalTests: no-cutoff case, end-of-day boundary (today survives, yesterday expires), start-of-day anchoring for the rolling windows, and raw-value fallback.

Default is Never, so there is zero behavior change unless the user opts in; unknown persisted values fall back to Never.

Type of Change

  • 🐞 Bug fix
  • ✨ New feature
  • 💥 Breaking change
  • 🧹 Chore
  • 📝 Documentation update

Related Issue or Discussion

Closes #463

Testing

  • Tested on Intel Mac
  • Tested on Apple Silicon Mac
  • Tested on macOS version: 26.1
  • Ran linter locally: swiftlint --strict --config .swiftlint.yml Sources — 0 violations
  • Ran formatter locally: swiftformat --config .swiftformat Sources — code added by this PR is clean (the only lint hit in touched files is pre-existing code at SettingsStore.swift:3466)
  • Ran tests locally: full suite green via xcodebuild test (Fluid scheme), including the 5 new tests

Screenshots / Video

The new Automatically Clear History row in Settings, below the existing history toggles. The help text updates with the selected interval:

Never (default):

Automatically Clear History set to Never

After 90 Days:

Automatically Clear History set to After 90 Days

Notes

  • Issue Feature Request: Automatic Transcription History Clearing #463 proposes scheduled wipes ("cleared daily at midnight"). Retention-based pruning gives the same observable result for End of Day — including for long-running sessions via the day-change observer — while also covering the case where the app wasn't running at midnight.
  • Codex review feedback (persist the new setting through backup/restore) was addressed in d661e84; older backups without the key decode as nil and leave the current setting untouched, matching the existing pattern for audioHistoryBudgetGB and notifyAIProcessingFailures.

…v#463)

Adds an 'Automatically Clear History' retention setting with Never,
End of Day, After 7 Days, After 30 Days, and After 90 Days options.
Expired entries and their saved audio are pruned at store load, before
each new entry, at midnight via NSCalendarDayChanged, and immediately
(behind a confirmation alert) when the user tightens the interval.
Cutoffs are anchored to start-of-day so a retained day never partially
expires.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 49c4977e9d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Sources/Fluid/Persistence/SettingsStore.swift
Adds historyAutoClearInterval to SettingsBackupPayload as an optional
field so restoring a backup preserves the retention policy instead of
silently falling back to Never. Older backups without the key decode as
nil and leave the current setting untouched.
@grohith327

Copy link
Copy Markdown
Collaborator

@devzahirul Can you update the PR description to match the current accepted format: https://github.com/altic-dev/FluidVoice/blob/main/.github/pull_request_template.md

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9e8405ff33

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

self.audioHistoryBudgetGB = audioHistoryBudgetGB
}
if let historyAutoClearInterval = payload.historyAutoClearInterval {
self.historyAutoClearInterval = historyAutoClearInterval

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prune restored history after applying retention settings

When a backup carries a non-never interval, this restores the retention policy before BackupService.restore loads document.transcriptionHistory (BackupService.swift:169), and TranscriptionHistoryStore.restore(from:) only sorts and saves the payload without calling pruneExpiredEntries(). Importing a backup can therefore immediately expose entries older than the selected window, including saved audio, until the next day-change/new dictation/app relaunch; apply the cutoff after restoring the history payload.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 2f43c35TranscriptionHistoryStore.restore(from:) now calls pruneExpiredEntries() after saving the restored payload, so a backup carrying a non-never interval prunes expired entries (and their saved audio) immediately on import instead of waiting for the next dictation, day change, or relaunch. Settings are restored before history in BackupService.restore, so the cutoff already reflects the imported policy at that point. Lint and the full test suite pass.

@devzahirul

Copy link
Copy Markdown
Author

@grohith327 Done — the description now follows the template, with screenshots of the new settings row in the Screenshots section. Also resolved the merge conflict with main and addressed the latest Codex review comment in the meantime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Automatic Transcription History Clearing

2 participants