CRITICAL fixes:
- Timestamp storage migrated from RFC3339 strings to Unix epoch i64
across all SQLite tables (tracker, store, bookmarks, scheduler).
Fixes ALL time-window queries that were returning wrong results.
HIGH fixes:
- Scheduler fire() now uploads media from file paths (was passing paths as media_ids)
- Schedule fire race condition: atomic pending→firing claim before posting
- Thread exits non-zero when all tweets fail (was returning success with 0 posted)
- Bookmark list uses OAuth 2.0 (was still on OAuth 1.0a, which X rejects)
- Bookmark export writes file BEFORE marking as read (was losing bookmarks on write failure)
- Bookmark export --json no longer mixes markdown with JSON on stdout
- Config set enforces 0600 file permissions on Unix (was 0644, exposing secrets)
- Env var mapping uses __ separator (XMASTER_KEYS__API_KEY works now)
- parse_tweet_id extracts segment after "status" (handles /photo/1 URLs)
MEDIUM fixes:
- PostTracker::open() creates timing_stats table (was crashing on clean install)
SAFETY:
- Skill workflow now requires explicit user approval before posting
- "Draft this" ≠ "Post this" — agent must show text and wait for confirmation
62 tests passing (39 unit + 23 integration).