not a toggle. not a setting. not negotiable.
Most observability tools start with "we collect everything; you can opt out." Pulse starts with the inverse: we collect what's safe by default, and the dangerous things never enter the system in the first place.
Below is the exact list of what's stored, what isn't, and where each guarantee is enforced. If anything below ever stops being true, that's a bug — open an issue at ashlrai/ashlr-pulse.
✕ what Pulse never stores
- ✕prompts — the text you sent to the LLM
- ✕completions — the text the LLM sent back
- ✕user code · file contents · diffs — no hunks, no patches, no source
- ✕stdout / stderr — the agent's tool outputs aren't shipped
- ✕screenshots / window captures — we don't observe your screen
- ✕keystrokes / per-key telemetry — no input layer instrumentation
- ✕AFK / idle / typing-rhythm metrics — no presence surveillance
- ✕commit bodies · PR descriptions · review comment text — GitHub data is metadata only
✓ what Pulse does store
- ✓timestamp · session id · source · model — structural metadata about each event
- ✓token counts (in / out / cache read / cache write) — for cost and volume reporting
- ✓tool call counts + tool names — what kinds of tools were invoked, never their arguments or output
- ✓repo name + git branch + project hash (sha256) — the cwd is hashed before it leaves the machine
- ✓language — for stack-mix reporting
- ✓commit SHA · PR number · PR state · diff line counts — GitHub events as enums + integers
- ✓commit subject (first line, ≤200 chars) — the only freeform string we record from GitHub — used solely for the activity feed
- ✓tokens_saved (when emitted by ashlr-plugin) — how much was avoided via the plugin's caching layer
✓ how peer-share keeps the floor
Peer-share grants are per-peer, per-scope, per-granularity, per-field. When you share with a cofounder, you pick which columns they see. The never-store list isn't on the menu — those columns don't exist on activity_event, so they can't be in any grant's fields[] array even if a malicious client requests them.
Default is private. Sharing is explicit, asymmetric, and revocable. Revoking is a UPDATE on peer_share.revoked_at — the next dashboard render and the next viewer query won't surface that grant.
✓ encryption + secrets
GitHub access tokens are encrypted at rest with AES-256-GCM via lib/token-crypto.ts. Personal Access Tokens (used by the Rust agent + ashlr-plugin) are stored as SHA-256 hashes — we cannot reproduce the plaintext after creation; you see it exactly once at mint time.
All HTTP traffic is TLS. Cookies are HttpOnly + SameSite=Lax. We never log request bodies — they may carry OTel payloads which are metadata-only by design but the principle of least logging still applies.
✓ open source · self-hostable
The core is MIT-licensed at github.com/ashlrai/ashlr-pulse. You can run Pulse against your own Postgres + Supabase project. The hosted version at pulse.ashlr.ai is the same source, deployed on Railway. Choose the trust model that fits.