Local-only ATProto/Bsky follow noise analyzer.
bsky-noise is built to answer one practical question:
- which followed accounts dominate your feed volume right now
- how that changed vs the prior period
- what volume reduction you get by muting top-N noisy accounts
python -m venv .venv
source .venv/bin/activate
pip install -e .# prompt (recommended)
bsky_noise auth --handle you.bsky.social
# or via env var (handle from BSKY_HANDLE or BSKY_USERNAME)
BSKY_HANDLE=you.bsky.social bsky_noise auth
# or env var (avoid CLI args)
BSKY_APP_PASSWORD='xxxx-xxxx-xxxx-xxxx' bsky_noise auth --handle you.bsky.social
# or stdin (avoid shell history)
printf '%s' 'xxxx-xxxx-xxxx-xxxx' | bsky_noise auth --handle you.bsky.social --app-password -If you prefer a .env, use .env.example as a template (keep .env uncommitted). The CLI will read .env from the current working directory.
bsky_noise sync --window 30 --window 90sync always includes your own account feed so the report can show a personal activity panel.
Dry-run to estimate request budget:
bsky_noise sync --window 7 --dry-runVerbose sync (log request status + backoff hints):
bsky_noise sync --window 7 --concurrency 1 --verboseUse the public AppView (read-only) to reduce PDS load:
bsky_noise sync --window 7 --use-appviewDegraded mode (slower, more retries, higher timeouts):
bsky_noise sync --window 7 --degraded --concurrency 2 --verboseAuto-degraded (switches to degraded behavior after 429/5xx/timeouts):
bsky_noise sync --window 7 --auto-degraded --verboseBuild an orbit candidate pool from followers you do not currently follow:
bsky_noise candidates refreshScore candidates (interaction-first default):
bsky_noise candidates score --mode interaction --sample 75 --daily-budget 200Pick k shortlist candidates and print text:
bsky_noise candidates shortlist --mode interaction --k 4Render shortlist in selected text format:
bsky_noise candidates render-shortlist --mode interaction --k 4 --format pollblueMaterialize derived summary JSON from local data (cron-safe):
bsky_noise compute --window 7 --compare-prior --summary-output output/summary.jsoncompute also materializes per-day aggregates used for burst/spike diagnostics.
make test
make sync7
make compute7
make report7
make candidates
make smokebsky_noise reportAction-focused report options:
bsky_noise report --window 7 --compare-prior --what-if-mute 5 --what-if-mute 10Export CSV and include a watchlist section:
bsky_noise report --window 7 --compare-prior --export-csv output/report.csv --watchlist watchlist.txtwatchlist.txt format (one DID or handle per line, # comments allowed):
# handles or dids
someaccount.bsky.social
did:plc:xxxxxxxxxxxxxxxxxxxxxxx
Outputs:
output/summary.jsonoutput/index.html
index.html includes:
- main feed-noise triage views
- a "My Account" panel with your own rates, streaks, and recent daily totals
Report health banner status:
good: clean run receiptdegraded: retries/rate-limits/timeouts observedpartial: missing/empty receipt signals
Build and run via compose:
docker compose run --rm bsky-noise auth --handle you.bsky.social
docker compose run --rm bsky-noise sync --window 7 --dry-run
docker compose run --rm bsky-noise sync --window 30 --window 90
docker compose run --rm bsky-noise report --output /outputSet BSKY_APP_PASSWORD in your shell or pass via stdin. For example:
printf '%s' 'xxxx-xxxx-xxxx-xxxx' | docker compose run --rm bsky-noise auth --handle you.bsky.social --app-password -- Classification rules:
- Repost if feed item includes
reasonof typeapp.bsky.feed.reasonRepost. - Reply if post record has a
replyfield. - Otherwise post.
- Repost if feed item includes
- Quote posts are treated as posts (unless they are replies).
- Uses SQLite in
~/.config/bsky_noise/bsky_noise.db(override withBSKY_DB_PATH). - If you set
XDG_CONFIG_HOME, config lives at$XDG_CONFIG_HOME/bsky_noise/. - Overlap lock file defaults to
$(dirname BSKY_DB_PATH)/run.lock(override withBSKY_LOCK_PATH).
Licensed under either:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.
- No follow/unfollow/mute/block automation.
- No posting automation.
- No account action engine.