aorta

What leaves the machine

When llm_provider is openai or litellm, every prompt AORTA builds is sent to a third party. Those prompts are not just your question: they carry retrieved chunks, tool output, and — because the assistant indexes your own sweep results — the contents of your matrix.json and env.json.

Each of those is individually reasonable and together they are an exfiltration path. So outbound LLM text is rewritten by default, and chat says so the first time it changes anything. Only the LLM message list — see the embedding caveat below.

What is redacted

Filesystem paths and IP addresses. That is the whole list.

Rewritten Not rewritten
Absolute filesystem paths API keys, tokens, passwords
IPv4 addresses Hostnames and cluster names
IPv6 addresses Customer, project or ticket identifiers
  Usernames, e-mail addresses, employee IDs
  GPU serial numbers, node IDs, MAC addresses
  Source code and its comments

The rewriters are the same ones aorta bundle uses to make a diagnostic bundle shareable — one implementation, one place to keep correct — applied here to the message list on its way out.

Read that table again before you rely on it

The limitation is worth stating plainly, because a user who trusts an overstated claim is worse off than one who knows the boundary:

If your threat model needs more than that, use llm_provider = "vllm" against a model you host — and keep embedding_provider = "local", which is the default. A local LLM alone does not mean nothing leaves the machine: with embedding_provider = "remote", indexing sends the corpus text (including your rendered run artifacts) to the embeddings API, and every retrieval sends the query. Neither call goes through the chat-message redactor described here. Together, those two settings are what make the claim hold.

The notice

On the first outbound request of a session that actually changed something, chat prints one line:

aorta chat: redacted 3 filesystem paths and 1 IPv4 address from the outbound request.
Disable with --no-redact, or 'redact = false' in ~/.config/aorta/chat.toml.

Three deliberate properties:

It appears once per session, and only when a redaction actually happened — a session whose prompts contained no paths is not told about a rewrite that never occurred.

In the web UI

stderr is the server’s console under aorta chat ui, which is not a place the person typing can see, so the notice is also delivered into the browser session that caused it — once, after the answer it applies to.

“Once per session” is therefore per browser session, not per server process. The state lives on a NoticeState the Chainlit handler owns and binds around each turn (redaction.use_notice_state), so one user’s redaction cannot consume another user’s disclosure. The CLI front doors are one session per process and use the process-wide state without binding anything.

The welcome message states the scope before you type, since the per-request notice necessarily arrives after you have already sent something.

Turning it off

aorta chat --no-redact ask "..."     # one invocation
# ~/.config/aorta/chat.toml
redact = false                        # permanently

The flag is tri-state on purpose: omitting it means “no opinion”, so a profile setting redact = false stays in force rather than being silently re-enabled by the default.

Turning it off is a reasonable choice when the model is local, or when the paths matter to the answer — “why did this fail” questions sometimes hinge on the exact directory layout, and a rewritten path can make the model’s reasoning worse. It is a bad choice against a metered public endpoint on a customer node.