v1.2.0 — Plugin Hooks, Auto-Expiration, Content Dedup
3 more gaps closed from the world-class roadmap. No breaking changes.
Plugin Hooks (GAP-4)
Hooks now fire during vault lifecycle events:
from qp_vault.plugins import get_registry
def on_add(resource, **kwargs):
print(f"New resource: {resource.name}")
get_registry().register_hook("post_add", on_add)Hook points: post_add, post_update, post_delete, post_search, post_transition.
Auto-Expiration (GAP-6)
Resources with valid_until dates are now automatically expired:
# Lazy: checked every 100 searches (zero config)
vault.search("query") # Silently checks expirations periodically
# Background: explicit monitor for long-running services
await vault.start_expiration_monitor(interval_seconds=3600)Content Deduplication (GAP-9)
Same content is never stored twice:
r1 = vault.add("Same document", name="a.md")
r2 = vault.add("Same document", name="b.md")
assert r1.id == r2.id # Returns existing resourceDedup is automatic (SHA3-256 CID match + tenant). Different tenants get separate copies.
Stats
- 612 tests (+10 new)
- 0 mypy errors (strict)
- 0 ruff errors
- 7 of 12 roadmap gaps closed (v1.1 + v1.2)