Skip to content

unpingable/atproto-stats

Repository files navigation

bsky-noise

Local-only ATProto/Bsky follow noise analyzer.

Why

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

Setup

python -m venv .venv
source .venv/bin/activate
pip install -e .

Authenticate

# 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.

Sync

bsky_noise sync --window 30 --window 90

sync 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-run

Verbose sync (log request status + backoff hints):

bsky_noise sync --window 7 --concurrency 1 --verbose

Use the public AppView (read-only) to reduce PDS load:

bsky_noise sync --window 7 --use-appview

Degraded mode (slower, more retries, higher timeouts):

bsky_noise sync --window 7 --degraded --concurrency 2 --verbose

Auto-degraded (switches to degraded behavior after 429/5xx/timeouts):

bsky_noise sync --window 7 --auto-degraded --verbose

Candidates (Orbit Discovery)

Build an orbit candidate pool from followers you do not currently follow:

bsky_noise candidates refresh

Score candidates (interaction-first default):

bsky_noise candidates score --mode interaction --sample 75 --daily-budget 200

Pick k shortlist candidates and print text:

bsky_noise candidates shortlist --mode interaction --k 4

Render shortlist in selected text format:

bsky_noise candidates render-shortlist --mode interaction --k 4 --format pollblue

Compute

Materialize derived summary JSON from local data (cron-safe):

bsky_noise compute --window 7 --compare-prior --summary-output output/summary.json

compute also materializes per-day aggregates used for burst/spike diagnostics.

Make Shortcuts

make test
make sync7
make compute7
make report7
make candidates
make smoke

Report

bsky_noise report

Action-focused report options:

bsky_noise report --window 7 --compare-prior --what-if-mute 5 --what-if-mute 10

Export CSV and include a watchlist section:

bsky_noise report --window 7 --compare-prior --export-csv output/report.csv --watchlist watchlist.txt

watchlist.txt format (one DID or handle per line, # comments allowed):

# handles or dids
someaccount.bsky.social
did:plc:xxxxxxxxxxxxxxxxxxxxxxx

Outputs:

  • output/summary.json
  • output/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 receipt
  • degraded: retries/rate-limits/timeouts observed
  • partial: missing/empty receipt signals

Docker

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 /output

Set 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 -

Notes

  • Classification rules:
    • Repost if feed item includes reason of type app.bsky.feed.reasonRepost.
    • Reply if post record has a reply field.
    • Otherwise post.
  • Quote posts are treated as posts (unless they are replies).
  • Uses SQLite in ~/.config/bsky_noise/bsky_noise.db (override with BSKY_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 with BSKY_LOCK_PATH).

Project Docs

License

Licensed under either:

at your option.

Non-Goals

  • No follow/unfollow/mute/block automation.
  • No posting automation.
  • No account action engine.

About

ATProto/Bsky follow noise analyzer.

Resources

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT

Contributing

Stars

Watchers

Forks

Contributors

Languages