fix: GDPR purge gaps, utcnow deprecation, PDP enforcement module#29
Open
fix: GDPR purge gaps, utcnow deprecation, PDP enforcement module#29
Conversation
Closes persistence-layer gaps from PR #23 code review and adds the PDP plugin enforcement that was flagged as unbuilt in the SDK. GDPR/audit fixes: - purge_by_session() now scrubs exported JSON files (not just in-memory) - Tombstone receipt includes file_entries_removed and files_purged - export_json() tracks paths for later purge propagation - Tests cover file purge, missing file handling, path tracking datetime.utcnow() deprecation: - Fix last 2 instances in identity/registry.py (default_factory) - All source files now use datetime.now(timezone.utc) PDP enforcement module (vcp/enforcement.py): - PDPPlugin abstract interface for enforcement plugins - PDPEnforcer orchestrator with priority ordering and fail-closed - RefusalBoundaryPlugin: bundle verification enforcement - AdherenceLevelPlugin: minimum adherence level gating - BundleExpiryPlugin: expired bundle blocking - 23 tests covering all plugins and edge cases Co-Authored-By: Claude <noreply@anthropic.com>
…, adherence policy Thread safety (3 HIGH): - Move _purge_exported_files() inside self._lock in purge_by_session() - Protect export_json() path tracking with self._lock - Prevents TOCTOU between concurrent export/purge and path list mutation Enforcement module (2 MEDIUM): - Log warning when ESCALATE is promoted to BLOCK (no escalation handler) - Add require_declaration flag to AdherenceLevelPlugin so bundles without an adherence level can be blocked rather than silently allowed - Remove redundant hasattr check in BundleExpiryPlugin Co-Authored-By: Claude <noreply@anthropic.com>
Purge handler propagation (was: log_callback sinks undiscoverable): - Add register_purge_handler() so external sinks (Redis, DB) register their own session-purge logic - purge_by_session() calls all handlers, includes results in tombstone - Warns if log_callback is set but no purge handler covers it - 4 new tests: handler invocation, exception resilience, warning Enforcement plugins_evaluated accuracy (was: counted registered, not run): - Track actual evaluation count via loop counter Co-Authored-By: Claude <noreply@anthropic.com>
- Replace 12 datetime.utcnow() in test_vcp_redis_state.py and test_vectors.py - Fix ruff I001 import sorting in __init__.py - Fix ruff UP015 unnecessary "r" mode in audit.py - Wrap long lines in test_vcp_redis_state.py (E501) - Add CHANGELOG entry for v4.1.0 Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
purge_by_session()now scrubs exported JSON files and propagates to registered external sinks (Redis, DB) viaregister_purge_handler(). Thread-safe with tombstone receipts for regulatory evidence.datetime.utcnow()fully eliminated — all 14 instances across source and test files replaced withdatetime.now(timezone.utc).vcp/enforcement.py) — standalone policy enforcement for VCP bundles.PDPPlugininterface,PDPEnforcerorchestrator, 3 built-in plugins (refusal boundary, adherence level, bundle expiry). No safety-stack dependency required.Context
Follow-up to PR #23. The code review audit (2026-03-27) flagged persistence-layer gaps in the GDPR purge and the absence of PDP plugin enforcement in the SDK. Elena's PR addressed the in-memory tombstone and session_id_hash gating but left exported-file purge and external-sink propagation unhandled.
What changed
audit.pyenforcement.py(new)registry.py, 2 test files__init__.py,CHANGELOG.mdtest_vcp_audit.py,test_vcp_enforcement.py(new)Test plan
self._locklog_callbackset without handler🤖 Generated with Claude Code