fix: QA batch 2 — security hardening, bug fixes, and 15 new test suites
Security fixes:
- Rate limiting on AI proxy endpoint (30 req/min)
- Share expiry enforcement on WebSocket connections
- Document existence validation on blob upload
- DB migration wrapped in transaction for crash safety
- Minimum passphrase length increased to 8 chars
Bug fixes:
- Emergency save tries fresh Yjs state first, falls back to cached (#535)
- Conditional form validation skips hidden required fields (#520)
- Circular dependency detection for conditional logic (#518)
- Outline extraction extended to H4-H6 (#513)
- PDF export filename null-safe (#526)
- Toast queuing instead of replacing (#558)
- Tokenizer supports percentage literals (#548)
New test coverage (15 test files, ~2900 lines):
- diagram-history, edate-leap-year, float-precision, forms-circular-deps
- named-ranges-structural, saved-views-structural, search-replace-ext
- security-batch2, slides-rotation-selection, slides-z-order, snap-guides
- suggesting-overlapping, toggle-block, tokenizer-percent, outline