What HypAware records, and how to control it
HypAware records AI activity on your host. This page explains what is captured, where it goes, and how to control it. If your team is rolling HypAware out, read this page before you enroll.
What gets recorded
Each capture source you enable during hyp setup records into the local
query cache under ~/.hyp (HYP_HOME):
| Source | What lands in the cache |
|---|---|
claude |
Claude Code prompts, responses, tool calls and results, system prompts, tool definitions, and working directory where available |
claude-desktop |
Claude Desktop conversations imported from local transcripts on macOS |
codex |
Codex CLI and Desktop conversations imported from their shared local session files |
codex-cloud |
Codex Cloud coding chats read from OpenAI's service with the ChatGPT login Codex keeps on your host (HypAware keeps no copy of it): user and assistant text, command calls and their outputs, and MCP calls and results; no reasoning content |
chatgpt-work |
ChatGPT Work web and mobile conversations, read the same way as codex-cloud; they can include everyday conversations that are not about coding. Off unless you choose it |
cursor |
Cursor editor and CLI conversations, including file contents and command output seen by its tools; explicitly connected Cloud VMs also record API text and supplied tool/edit observations |
opencode |
OpenCode CLI and Desktop conversations from its managed plugin and history exports |
pi |
Pi conversations from its managed extension and local session files |
droid |
Factory Droid local CLI transcripts, including prompts, responses, tool arguments and results, and working directory; no billed token usage or cost |
grok |
Grok Build local sessions, including prompts, responses, reasoning summaries, tool arguments and results, and working directory |
openclaw |
OpenClaw conversations from gateway traffic and local transcripts |
hermes |
Hermes Agent conversations read from its local state database |
goose |
Goose CLI and Desktop conversations read from its local session database, including tool calls and results, token usage, and working directory |
crush |
Crush conversations read from each project's local database, including tool calls and results and the project directory; no token usage. The files table, which holds copies of file contents, is never read |
mastracode |
Mastra Code conversations read from its local mastra.db, including tool calls and results and the project directory; no per-turn token usage or cost. Only the threads and messages tables are read; settings.json, auth.json, mastra-vectors.db and the observability store are never read |
antigravity, antigravity-desktop |
Antigravity CLI and Desktop conversations read from their local summary databases and transcripts, including model thinking, tool calls and results, and working directory |
copilot |
VS Code Copilot completed spans from its local databases, for sessions with a verified local working directory |
nanoclaw |
NanoClaw Claude transcripts read from an explicitly configured local installation |
langgraph |
LangGraph model, tool, and graph callbacks from your application, with its working directory and Git context |
ollama |
Ollama CLI and SDK chat and generate requests sent through the local capture route: system, user, and assistant text and the new response's token usage. Image bytes are omitted, and an exchange with thinking or tool calls is not saved |
raw-anthropic, raw-openai |
API requests and responses routed through the local gateway |
otel |
OpenTelemetry logs, traces, and metrics sent to the local OTLP listener |
github |
Structural repository activity such as issue, pull request, commit, file, review, and comment metadata; content remains on GitHub |
linear |
Structural issue metadata for configured teams (identifier, team, state, and Linear ids of the creator and assignee) and GitHub pull request links attached to those issues; titles, descriptions, and comments remain in Linear |
Cursor Cloud is separately
opted in with hyp cursor-cloud connect inside the VM. Its local grant binds
one agent and repository, and holds no API key. The runtime key is sent only to
Cursor's fixed API origin for conversation reads; captured rows follow the
existing recording and export policy. Disconnect revokes new capture and
preserves previously captured data.
Conversation capture includes message content, not just metadata. Depending on what the client exposes, records can also include system prompts, tool arguments and results, working directories, and Git metadata. The available fields differ by client and capture method.
Rows age out according to local retention settings. Retention does not delete original client transcripts or copies already exported.
The raw-body spool
With Claude Code attached, Claude Code writes each raw request and response
body into ~/.hyp/spool/claude-bodies, a directory HypAware creates
owner-only (0700). It is a transit area, not storage: HypAware reads a file
only for the few fields its event stream leaves out (the system prompt, the
tool list, message ordering, untruncated tool arguments) and deletes the file
as soon as it has them. The same content is already in Claude Code's own
transcripts under ~/.claude/projects.
Spool cleanup works as follows:
- A session you ignored, by
.hypignore, by a host-local marking, or withhyp session ignore, has its bodies deleted unread, not skipped. - The default cap is 512 MB, configured as
telemetry.spool_max_bytesin the@hypaware/claudeplugin's config. The listener and Claude hooks enforce it by deleting the oldest files first. It is periodic cleanup, not a filesystem quota: files can accumulate between checks, and cleanup requires one of those processes to run. Deleted bodies cannot supply missing capture detail. hyp privacy purgeempties it, whatever else you asked that purge to delete, andhyp detach claudeempties it on the way out.
Proxy mode and certificate cleanup
Claude Code uses OTEL capture by default. An explicitly configured proxy routes HTTPS through the local gateway. The gateway decrypts AI provider hosts named by the configured capture adapters; other hosts are tunneled without decryption. Only supported provider API requests are recorded.
The proxy's local certificate authority (CA) is stored under
~/.hyp/hypaware/tls. It is restricted to supported provider hosts and excludes
IP addresses. Current attach operations use client-scoped trust. An installation
that previously used Claude proxy capture may still have a CA trusted in the
macOS login keychain, a NODE_USE_SYSTEM_CA launchd environment variable, and
~/Library/LaunchAgents/com.hyperparam.hypaware.node-system-ca.plist. Those
settings affect other programs using that account's trust or environment.
Inspect these artifacts with hyp status --verbose. hyp detach claude --purge
and hyp daemon uninstall remove the CA, its keychain trust, the launchd
variable, and the login agent. Plain hyp detach claude leaves the CA and
keychain trust; it clears the variable and agent only when the attach marker
still identifies a proxy attach.
Where it goes
- Local only: recordings stay in the local cache, plus any local exports you configured.
- HypAware Cloud (after choosing Sync to the cloud in setup,
hyp remote login, orhyp join): recorded rows are synced to HypAware Cloud, including conversation content. The controls below decide which rows that covers.
HypAware Cloud operators can read synced data across every org, and each such read is recorded in that org's audit trail. For support, they can also view a member's dashboard as that member sees it, read-only and for at most an hour at a time. Each such session is recorded in that org's audit trail under the operator's name, with the reason they gave.
Enrollment also enables product telemetry for the organization unless you saved a preference. It is separate from session recordings.
The three usage classes
Every directory subtree resolves to one class. Starting at the session's
working directory, HypAware uses the nearest ancestor .hypignore file and
the most-specific matching host-local marking. It then takes the most
restrictive result across those sources: ignore, then local-only, then
sync. This is not a merge of every ancestor file.
| Class | Recorded locally | Synced to HypAware Cloud |
|---|---|---|
sync |
yes | yes (the default) |
local-only |
yes | never |
ignore |
never | never |
local-only rows stay fully queryable on your own host; they are
withheld at the export seam, so no sink or remote query can see them.
Marking directories
There are two authoring surfaces for the same classes:
A committable
.hypignoredotfile marks a subtreeignoreand travels with the repo, so it covers every clone:Terminalhyp privacy ignore # write a .hypignore at the repo root (or cwd) hyp privacy ignore <path> # ignore a specific subtree hyp privacy unignore # remove it, re-enabling recordingAn empty or comment-only
.hypignorealso meansignore.A host-local store (
hyp privacy) records the class privately on this host, never as a file in the repo. Use it when the marking itself is sensitive (a dotfile in a hidden directory is a breadcrumb pointing at exactly the thing you are hiding), or when the path is not a repo:Terminalhyp privacy set <path> ignore # never recorded, no dotfile hyp privacy set <path> local-only # recorded, never synced hyp privacy set <path> sync # explicitly synced (not asked again) hyp privacy show [path] # which class governs, and why hyp privacy list # every host-local entry hyp privacy unset <path> [class] # back to the implicit default
On a host connected to HypAware Cloud, folders you have not marked sync without asking. You can instead be asked, once per new folder, how to handle it, at the moment you open a session there:
hyp privacy folders ask # ask once per new folder
hyp privacy folders sync # back to syncing without asking (the default)
hyp privacy folders # report which is in forceThis gates the question only. In either setting, folders you already
marked keep their class, .hypignore files are unaffected, and nothing
already local-only or ignored starts syncing. The setting is host-local
and reversible, hyp setup asks for it in its own step (unattended:
hyp setup --new-folders ask|sync), and hyp status names it on an enrolled
host.
Three caveats apply to both surfaces:
Class resolution needs a working directory. The client sources
(Claude Code, Claude Desktop, Codex, Cursor, OpenCode, Pi, Droid, OpenClaw,
Goose, Crush, Mastra Code, Copilot, LangGraph) supply one. NanoClaw uses the host groups/<folder>
workspace. Antigravity takes it from the conversation's workspace; a
conversation with no workspace has no scope to match and is recorded
unconditionally. Hermes supplies the real one for an interactive session it
recorded a cwd for, and scopes a messaging-channel session (Telegram, Discord, Slack,
WhatsApp, Signal, email) under a derived ~/.hermes/channels/<source> path
instead; an interactive Hermes session with no recorded cwd has no scope to
match and is recorded unconditionally. The raw-anthropic / raw-openai
proxy, OTEL, and Ollama sources never supply one, so directory markings are a no-op
for them. Codex Cloud and ChatGPT Work chats carry a path on OpenAI's machine,
not yours, so local markings and .hypignore never classify them either;
hyp session ignore and export settings still apply.
Control a whole client's sharing
Keep a locally configured client's recordings on this host:
hyp privacy client codex local-only
hyp privacy client codex syncUnattended setup takes the same choice as --local-only-client codex or
--sync-client codex, each repeatable; omitted, the current choice stays.
Organization-managed clients cannot be changed with this local control. Use
directory markings for project-level exclusions.
Returning a client to sync affects future exports; previously withheld history
requires a separate, confirmed hyp sync --history codex. Completing team setup
can clear client-level local-only choices; review the setup prompts.
Pausing a single session
Run hyp session ignore inside a Claude Code or Codex session to resolve its
ID automatically. If it cannot establish the ID, the command refuses to guess.
For another supported recorder, pass an explicitly verified session ID as
shown in the session reference.
The command sends the exclusion to local recorder control routes for the
gateway, Claude telemetry, OpenCode, Pi, Droid, Grok Build, and Cursor when they
are running. Goose, Crush, and Mastra Code have no control route; they read the
saved exclusion on their next poll. A Crush session is ignored by its HypAware
session ID, crush- followed by the Crush session ID, and a Mastra Code thread
by mastracode- followed by its thread ID. On an install that records only
Goose, Crush, or Mastra Code the command saves nothing, so mark the session's
working directory with hyp privacy ignore <dir> instead. The Claude listener
deletes ignored sessions' spooled bodies unread. Use hyp session unignore to
resume and hyp session status to check the result.
Gateway, Claude, OpenCode, Pi, Droid, Grok Build, Goose, Crush, and Mastra Code
exclusions are saved under <HYP_HOME>/hypaware/session-ignores/ and survive
restarts. Cursor exclusions are currently in memory only and must be
reapplied after a recorder restart. OpenClaw and Hermes do not support this
session control; use directory markings or disable their capture integrations.
Claude (including Desktop transcripts), Codex, OpenCode, Pi, Droid, Grok Build, Goose, Crush, and Mastra Code backfill honor saved exclusions, including manual imports in a separate process. Saving must succeed before a persistent recorder reports success. If its exclusion store is unreadable or corrupt, capture and transcript imports pause while AI requests still forward. Commands and source status report the error. Repair the saved state and restart HypAware before relying on capture again.
A resumed session keeps its ID. A fork creates a new ID and needs its own
exclusion, except on Grok Build, where a fork or subagent inherits its parent's.
For attached Claude Desktop Code sessions, the managed SessionStart hook
supplies the ID to later Bash commands. Hosts without hooks or CLAUDE_ENV_FILE
require an explicitly verified ID; a matching directory or recent transcript is
insufficient.
Ignoring does not delete earlier records, original client transcripts, or
exported copies. Unignoring makes the entire transcript eligible for import,
including turns written while ignored. Use hyp privacy purge --session <id>
to delete previously captured rows.
Deleting what was already recorded
hyp privacy purge permanently deletes rows from this host's local cache:
hyp privacy purge <path> # rows whose cwd is at or under the path
hyp privacy purge --session <id> # one session's rows, here and on your servers
hyp privacy purge --ignored # every row whose directory now resolves to ignore
hyp privacy purge --all # everything, wholesaleIt prompts on a TTY; pass --yes for non-interactive use.
hyp privacy purge --session <id> --remote <target> # this host and one server
hyp privacy purge --session <id> --local-only # this host onlyDeleting on a server uses your login, and needs you to be the session's owner or an organization admin. If a server cannot be reached or refuses, the command exits nonzero; run it again to finish. Copies quoted into a published report are not removed, and the underlying files are reclaimed by later maintenance, not at the moment of the purge.
The path, --ignored, and --all forms are local only: they never contact a
sink or a server, and never delete copies already exported or synced.
Every form of it also empties the raw-body spool described above, including the targeted ones: a spooled body has not been read yet, so nothing about it says which directory or session it belongs to, and leaving it would let the next batch write back rows you just deleted.
Local file permissions
HypAware creates its local storage readable only by your user: directories
0700 and recorded content (the cache spool, cached data, local exports, the
daemon log) 0600, whatever your umask. On an existing install, each start tightens
HYP_HOME, its hypaware directory, and a cache root kept elsewhere to 0700,
which keeps other users out of the older files below them without rewriting
any of them.
It only tightens a directory it can tell is its own. A custom HYP_HOME or
cache location that holds other files, or that another user owns, is left as
it is, and HypAware logs a storage.root_not_secured warning and keeps
running; files written there before this release keep their old modes. Parent directories are never changed.
On Windows, where POSIX modes do not apply, each start sets the same roots to an access list naming only your account, SYSTEM, and Administrators, and everything HypAware creates under them inherits it. Permissions a root picked up from its parent folder are removed, but a permission someone granted by hand on the root itself is kept, so a folder shared on purpose stays shared: HypAware sets the grants for those three accounts and leaves other explicit grants alone. The same care applies: a shared or foreign directory is left as found with the warning above. Files that already existed under a custom location outside your user profile keep their old access until they are rewritten; the default location under your profile was already covered by the profile's own access rules.
Redaction when content is recorded
The built-in rules below also run before a row is written to the local cache, so recognized credentials and sensitive file-tool contents are masked in the cache itself and in every local query, not only in exports. This is on by default and has no switch to turn it off. It covers every capture source that writes the cache, live capture and transcript backfill alike, including Claude Code telemetry events and OpenTelemetry logs, traces and metrics. It runs again on content a capture adds while settling a row, including when compaction settles a row again.
Some differences from export redaction:
- Custom patterns apply to exports only. The local cache masks the built-ins alone.
- A file read is masked when its call names a sensitive file, including a call recorded in an earlier batch. A read whose call HypAware never saw is kept locally; exports still mask it.
- A row too large for the traversal budget below is still recorded instead of failing. Each column is checked on its own. A column still too large gets only the text patterns: file paths and credential key names inside it are not recognized, and a nested value that is not text is dropped.
- Rows recorded before this change keep their content, and so do rows still
waiting to be written when you upgrade. To remove them, use
hyp privacy purge. - The raw-body spool and the LangGraph outbox are written by other programs, so their files are not masked. HypAware masks what it records from them.
Automatic export redaction
Cloud forwarding and file exports mask recognizable credentials and known sensitive file-tool contents, whether or not the content was masked when it was recorded. Existing directory and session withholding applies first. Configure additional regex patterns for your organization's secret formats.
Built-ins recognize common AI and GitHub keys, AWS access-key IDs, Slack tokens,
Google API keys (AIza...), Stripe live secret keys (sk_live_...), JWTs with
or without a Bearer prefix, bearer tokens, credential-bearing database URLs,
private keys, named credential fields, and plaintext password/API-key
assignments. They also mask file-tool
payloads for .env variants, private-key files, common credential stores and
shell configuration/history. Template files such as .env.example do not
trigger full-file masking, though credential patterns still apply.
A heuristic also masks unknown random tokens: a standalone run of 32 to 128
letters, digits, - and _ that mixes uppercase, lowercase and digits and is
as varied as a randomly generated key. It leaves commit SHAs, UUIDs and other
hex alone, along with ordinary code identifiers, paths and URLs, provider IDs
such as chatcmpl-... or toolu_..., standard base64 that is padded with
=, touches a + or /, or sits inside a PEM block, and digests or keys labelled
h1:, SHA256:, sha-256= or ssh-ed25519. It has limits both ways.
Random-looking public values can be masked: long identifiers packed with
acronyms and digits, document or video IDs, base58 addresses, nonces, and
lines of wrapped base64 outside a PEM block. It misses secrets shorter than 32
or longer than 128 characters, hex-only or single-case secrets, secrets
embedded in a path or URL, most secrets in standard base64 (they usually
contain + or /), and about 3% of random 32-character tokens. It is on by
default, like the other built-ins, with no switch to turn it off.
File masking uses recorded tool arguments and call/result links. A named file read whose path cannot be established within the current export scan has its output masked conservatively. This can remove ordinary read output, especially when its call was exported on an earlier tick. Arbitrary shell commands are not parsed to infer which files they read.
Masking also scans nested attributes and raw-frame string values. It preserves top-level row identities, directory attribution, timestamps, and numeric usage. Object keys and binary values are not scanned; encoded data and image content are not decoded. Uncommon secret formats may remain unless a custom pattern covers them. Automatic masking does not replace directory exclusions or privacy review.
Custom patterns run in an isolated worker with one row at a time and a one-second matching deadline. Exceeding that deadline or the per-row traversal budget fails export instead of sending an unscanned row. The budget is depth 64, 100000 visited values and 16 MiB of UTF-16 string bytes per row. Adding a rule affects subsequent exports; it does not recall earlier copies.
Review before the first Cloud sync
Before sharing recordings, review captured directories with the
hypaware-privacy skill in Claude Code or Codex. It checks this host's local
cache, samples recordings, and proposes directory markings and deletions for
your confirmation. A review cannot guarantee it will find every secret.
Redaction covers recognized patterns; other local content stays as recorded.
You can run the review at any time, even without Cloud enrollment.
hyp privacy show
hyp privacy listRun the hypaware-privacy skill: review what this host has recorded, sample it, and propose which folders to mark local-only or ignore before anything syncs. Do not delete anything without asking me.For the enrollment hold, deadline, and unattended behavior, see the first-sync review.
For disconnecting a host while retaining its local recordings, see Cloud and teams.
The daemon's own telemetry
HypAware's operational diagnostics are separate from product telemetry:
- With
HYP_DEV_TELEMETRY=1, logs, spans, and metrics are written locally under~/.hyp/hypaware/dev-telemetry/. - Without that setting, an inherited
OTEL_EXPORTER_OTLP_ENDPOINTsends those diagnostics to the configured endpoint. - With neither setting, those diagnostic providers do not record or export data.
These diagnostics use component, operation, and status attributes. They are designed to exclude credentials and raw prompt content. Service output logs are separate; see data paths.
Product telemetry
Product telemetry reports how HypAware itself is running. It is enabled for an
enrolled organization unless you saved an off or local preference. An
already-enrolled host starts reporting on its next CLI run or daemon start
after an upgrade, without a new prompt. Standalone installations default to off.
Check the effective state and destination:
hyp telemetry statusUse HypAware to tell me whether product telemetry is on, where it goes, and show me the next batch it would send.Organization telemetry goes to the HypAware server this host is enrolled with, using its existing enrollment. The CLI does not send telemetry anywhere else. The server also copies the HypAware version, OS family, and configured client names to PostHog for product analytics, where they are kept until Hyperparam deletes them.
Control and preview
hyp telemetry off
hyp telemetry enable local
hyp telemetry preview
hyp telemetry enable organizationoff saves your preference, including across re-enrollment, and removes queued
batches. It cannot recall batches the server already accepted. If saving fails,
the command exits nonzero and reports that telemetry remains enabled.
local keeps a preview queue without sending it. organization enables sending
and requires exactly one eligible enrolled central sink with an HTTPS
destination. Changing the mode clears older pending batches. preview prints
the exact next batch, or null if none is queued.
Restart a running daemon after enabling collection. It notices disabling and
enrollment changes within 30 seconds. hyp status also reports telemetry state.
What is collected
| Data | Examples |
|---|---|
| Command outcomes | A command name from a fixed list, success or failure, duration, and selected setup steps; custom commands appear as other |
| Installation and process details | HypAware version, OS, architecture, Node major version, configured integrations, and generated installation/process identifiers |
| Daemon health | Lifecycle events, memory and CPU summaries, and counts of rows captured, written, and exported |
| Setup milestones | That this installation captured its first row, and that it ran its first successful query. Each is sent once; changing the telemetry mode or re-enrolling can send it again |
| Query usage | For a hyp query command or an MCP query tool: up to four dataset names from a fixed list (others appear as other), whether the query ran locally or on a remote, the row count as a range (0, 1-10, 11-100, 101-1000, or more than 1000), and whether it came from a terminal, an MCP client, or an agent's shell |
| MCP tool calls | A tool name from a fixed list (others appear as other), success or failure, an error code from a fixed list, and duration |
Query usage and MCP tool calls are sent only to a server that reports it accepts them; an older server receives the other rows without them. An agent's shell is recognized by the presence of environment variables that known agents set; their values are not read or sent.
Conversations, prompts, responses, argument values, SQL, file paths, credentials, and free-text error messages are excluded. Coverage is partial: a killed process may never report a completion, and missing measurements do not mean zero activity.
Storage and delivery
The queue holds at most 160 batches of 32 KiB each, up to 5 MiB. It lives under
~/.hyp/hypaware/product-telemetry/. New records are dropped when it is full.
Batches expire after seven days when a collector or sender runs; an inactive
installation cannot clean up on a timer. A sudden power loss may lose queued data.
The daemon attempts one batch every 30 seconds. Without a daemon, a CLI command may send an earlier batch while it runs. Command exit does not wait for delivery, so a final batch may remain queued until HypAware runs again.
Network failures retry with backoff. A 401 first triggers a credential refresh; continued 401 or a 403 pauses delivery for an hour. A server without compatible telemetry support also pauses delivery. Permanent payload rejections (400, 409, 413, 415, or 422) discard the rejected batch. The receiving server must have product reporting enabled.