Problem
Expired cache entries are only marked with evicted_at; cached_text remains in SQLite indefinitely. The table also lacks the documented purpose, redaction state, provenance, and review fields.
Optional cloud LLM extraction sends sender, subject, folder, and date metadata without a central redaction/pseudonymization stage or explicit provider-mode policy.
Relevant code
src/mailplus_intelligence/cache.py:43-117
src/mailplus_intelligence/llm_extractor.py:82-99,145-225
src/mailplus_intelligence/migrations/003_cache_and_queue.sql:3-15
docs/selected-message-text-cache-policy.md
docs/privacy-redaction-boundaries.md:24-65,158-177
docs/operational-safety.md
Scope
Cache lifecycle
- Physically delete, overwrite, or cryptographically destroy expired selected text.
- Bound TTL values and reject invalid/unsafe retention.
- Record purpose, class, redaction state, provenance, creation/expiry, and review requirement.
- Add privacy-safe durable events for write, read, miss, denial, expiry, and disposal.
- Document WAL/backup implications and verify owner-only permissions for database sidecars where practical.
Model egress
- Add a provider policy such as
disabled | local | cloud, with cloud disabled by default.
- Require explicit operator configuration for cloud use.
- Redact or pseudonymize sensitive subject/sender/folder values before cloud requests where the task does not require them.
- Record what data classes and provider/model were used without logging payload content.
- Fail closed when policy and requested extractor disagree.
Non-goals
- No bulk body cache.
- No live mailbox fetch in this issue.
- No claim of secure deletion from unmanaged filesystem snapshots/backups; document the boundary.
- No provider-specific secrets in config files or logs.
Acceptance criteria
Validation
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src python3.12 -m unittest tests.test_cache tests.test_llm_extractor -v
bash scripts/check-detect-secrets.sh --all-files
bash scripts/ci/run-fast-checks.sh
Parent
Part of #98.
Problem
Expired cache entries are only marked with
evicted_at;cached_textremains in SQLite indefinitely. The table also lacks the documented purpose, redaction state, provenance, and review fields.Optional cloud LLM extraction sends sender, subject, folder, and date metadata without a central redaction/pseudonymization stage or explicit provider-mode policy.
Relevant code
src/mailplus_intelligence/cache.py:43-117src/mailplus_intelligence/llm_extractor.py:82-99,145-225src/mailplus_intelligence/migrations/003_cache_and_queue.sql:3-15docs/selected-message-text-cache-policy.mddocs/privacy-redaction-boundaries.md:24-65,158-177docs/operational-safety.mdScope
Cache lifecycle
Model egress
disabled | local | cloud, with cloud disabled by default.Non-goals
Acceptance criteria
cached_textin active database rows.Validation
Parent
Part of #98.