PullPulse
Legal

What we store, for how long, and who else sees it.

This page names real database tables and real retention windows rather than describing them in the abstract, because a privacy policy you cannot check against the system is not worth reading. PullPulse holds review metadata: who opened what, who is waiting on it, and what it touched. It does not hold your source code.

Last updated 30 August 2026.

What we store

categorywhat it iswhere
Slack workspace and user idsWorkspace id and name, enterprise grid id, the bot user id, the id of whoever installed it, and the Slack user ids of members who linked a GitHub login — plus their timezone and any snooze they set.slack_installs, identity_links
Sealed credentialsThe Slack bot token and, if you configure one, your model provider API key. Both are stored only as AES-256-GCM ciphertext. MCP tokens are stored as a SHA-256 hash and never as the token itself.slack_installs, workspace_settings, mcp_tokens
GitHub installation and repository metadataInstallation id, the account it belongs to, the API root, and per repository: full name, default branch, whether it is private, your .pullpulse.yml and the CODEOWNERS file we read to work out who knows the code.github_installs, repos
Pull request titles and metadataTitle, description, URL, author login and whether that author is an agent, state, reviewers, check results, head commit sha, line and file counts, the computed risk score, and the model-written brief where one was generated.pull_requests
Slack message bookkeepingChannel ids and Slack message timestamps for the messages and threads PullPulse owns, so it can update them instead of reposting. Message text is not stored; it is rendered from the metadata above.pr_messages, pr_threads
Notification historyA ledger of who was mentioned when, which is what the per-person noise budget is computed from, plus the reminders already sent so escalation never repeats itself.notifications, reminders
Webhook payload archiveThe raw GitHub webhook body, exactly as delivered, so a failed delivery can be replayed instead of lost. These bodies contain private repository content.R2 object storage, plus an index row in deliveries
Billing recordsYour plan and status, the Stripe customer, subscription and price identifiers, period end dates, and a monthly count of model calls. Card details never reach PullPulse.subscriptions, usage_counters
Feedback and search indexThumbs up or down on AI output with the Slack user who gave it, and vector embeddings of pull request text used to find similar past changes.ai_feedback, Cloudflare Vectorize
Short-lived cacheGitHub installation tokens, Slack user lookups and single-use OAuth nonces, each with its own expiry measured in minutes.Cloudflare KV

Diff content is never persisted and never logged. It exists in memory while a pull request is being enriched, and in the prompt sent to the model provider for the features that need one. Nothing writes it to a database or to a log line.

Card details never reach us. Checkout and the billing portal are hosted by Stripe; we store only the identifiers Stripe gives us for your customer and subscription.

How long we keep it

Who else processes it

How it is protected

Deletion

Uninstalling the app from Slack revokes the stored credentials immediately and stops all processing for that workspace: queued events for a revoked workspace are dropped rather than delivered. The rows survive the uninstall so that reinstalling restores your routing, identities and history rather than starting from nothing — and so that uninstalling and reinstalling cannot mint a fresh trial.

Ask us to delete the workspace and we delete it: every table is keyed on the workspace id with cascading deletes behind it, so removal is complete rather than best-effort, and the archived webhook payloads age out on the 30-day window above.

Contact

For access, correction or deletion requests, message PullPulse in Slack from an installed workspace and a human will answer.