Why I built it
Saving useful posts had turned into passive accumulation. I wanted a system that would help me revisit ideas while they were still relevant to the things I was building and thinking about.
How it works
- A Playwright scraper saves bookmarks into SQLite.
- An enrichment step adds deterministic metadata and optional LLM intent classification.
- A weekly digest groups the useful items into a briefing, clustered sections, a chronological appendix, and a reflection prompt.
- A small orchestration wrapper makes the pipeline repeatable enough to schedule.
Different model stages are chosen for different jobs: inexpensive classification for volume, stronger synthesis for the weekly brief, and a smaller creative step for the reflection question.
Implementation detail
The pipeline is split into CLI stages so each part can be run, retried, or scheduled separately:
fetch_bookmarks.py -> scrape bookmarks into SQLite
enrich_bookmarks.py -> add metadata and LLM intent labels
send_weekly_digest.py -> generate and send the weekly brief
run_pipeline.py -> orchestrate recurring runs
The orchestration wrapper uses a file lock so scheduled jobs do not overlap:
with path.open("w") as lock_file:
fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
try:
yield
finally:
fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)
Reliability details
- SQLite stores the original bookmark alongside enrichment status, fallbacks, and digest history.
- A file lock prevents overlapping scheduled runs from racing each other.
- Digest history makes it possible to resurface older posts without repeatedly recycling the same items.
- Media previews are restricted to expected X image hosts.
- A dry-run mode renders the digest locally before sending it.
Prompt design
The digest prompt is opinionated on purpose. It asks for a personal intelligence briefing, not a neutral summary. The useful output connects saved posts to current projects, repeated authors, and the collector-versus-builder tension in the bookmark data.
The model policy is also split by cost and quality:
Intent classification: gpt-4o-mini
Weekly briefing: gpt-5, fallback gpt-5-mini
Reflection question: gpt-5-mini, fallback gpt-4o-mini
What matters to me
This is less about scraping than building a better information diet. The pipeline is useful when it turns a saved link into an action, a connection, or a question worth following.