sessionpipe

Privacy: tiers and rulesets

This document is part of the sessionpipe protocol and is licensed under CC BY 4.0. The words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are used as in RFC 2119. Status: Draft (see VERSIONING.md).

Sessions are personal. A prompt names colleagues, a path names a client, a pasted config carries a key. The protocol's answer is data minimisation by construction: a sink gets a tier, the tier is an allowlist, and two rulesets scrub what remains.

1. Tiers

Tier Name Carries
0 presence Session id, state events (session.*, turn.started, turn.ended, attention.* with only attention_id and kind), timing, machine, cwd, repo, branch, model, title, url, account_id. Enough for "working / needs you / done" and a link to open the session.
1 actions + tool names, call_id, durations, ok/error text, files.changed paths, attention tool and message (redacted, ≤ 200 chars), prompt_chars, subagents, compactions. Enough for an activity feed.
2 conversation + turn.transcript: the person's prompts and the assistant's text, redacted, ≤ 20 000 chars a side. Enough for memory, search, recaps.
3 full + tool input and output (≤ 64 KB each), thinking where the harness exposes it, the native lane's raw lines. Full replay; meant for a receiver you own.

Rules:

2. Rulesets

secrets@1 (always, above tier 0)

Runs on every string an event carries above tier 0, before the event reaches the outbox. It cannot be disabled per sink. It removes the value and keeps the sentence: password: [redacted]. What it matches:

Class Examples
Vendor token shapes ghp_…, github_pat_…, glpat-…, xox[abposre]-…, Slack and Discord webhook URLs, sk-… (OpenAI, Anthropic, DeepSeek, OpenRouter), sk_live_ / rk_test_ (Stripe), whsec_…, AIza…, ya29.…, GOCSPX-…, AWS access key ids, xai-, gsk_, pplx-, hf_, pcsk_, npm_, pypi-, SendGrid, Shopify, DigitalOcean, Linear, Notion, Supabase, Figma, Doppler, Granola, spacesheep ss_, Telegram bot tokens, JWTs, PEM private-key blocks (including one cut off mid-paste).
URL credentials scheme://user:password@host → the password goes, user and host stay.
Authorization headers Bearer, Basic, Token followed by a credential.
Assignments NAME=value, NAME: value, NAME => value where NAME names a secret (DB_PASSWORD, apiKey, client-secret, *_KEY, *token* …) — but not password_hash, tokenizer, max_tokens: 4096. Only a secret name may consume a value, so https: never swallows a ?token= behind it.
Prose "password is Hunter2!", "the token was …", "set the password to …" — only when the value looks generated (letters and digits, or three character classes), so "the password is wrong" stays.

Placeholders are left alone: <your-key>, ${VAR}, process.env.X, string, [redacted], a member path, a call. The rules are linear (bounded repetition, no nested quantifiers); the adversarial vectors pin that a 50 000-space run or password_ × 5000 returns in milliseconds. The ruleset is idempotent.

Vectors: conformance/redaction/secrets.json. The reference implementation is packages/core/src/privacy/secrets.ts; every other copy (a server-side re-check, a CLI) MUST import it or run its vectors.

pii@1 (opt-in, any tier)

A second pass, on by --pii per sink. It reduces identifiers, it does not promise anonymity:

Rule Effect
Email addresses → [email]
Phone numbers (E.164 and common national forms) → [phone]
Home directory paths → ~ (already the rule for session.cwd; here applied inside every string)
session.machine → the first 8 hex characters of its SHA-256
session.account_id dropped

Vectors: conformance/redaction/pii.json.

3. What a sender never reads

An adapter uses a harness's documented hooks API and reads files the person's own harness wrote on the person's own machine (its transcript, its session registry, its config's account id). It never reads a credential file, never calls a vendor API, and never sends a token of the harness's anywhere. ADAPTERS.md states this per harness with the documentation URL.

4. For receivers

This section is guidance, not legal advice.

Session events can be personal data: names in prompts, an account id, paths that name a client or a colleague. If you operate a receiver for anyone but yourself, you are the controller of what it stores.

5. What sessionpipe itself never does