> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prbe.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Keep folders out of Probe

> A gitignore-style .probe.config sets what Probe may read and record for each path, from any session, wherever it started.

A `.probe.config` file sets how much Probe may touch the paths under its folder. Put one in any folder: it covers that folder and everything below it, in the same syntax as a `.gitignore`. It works whichever folder your coding agent was started in.

```text ~/code/client-x/.probe.config theme={null}
# nothing in this repo is read or recorded
*
```

## Levels

Every line gives the paths it matches a level:

| Level | Written as | What Probe does |
| - | - | - |
| `off` | a plain line, or `<pattern> @probe off` | Never reads the path and records nothing about it. |
| `read` | `<pattern> @probe read` | The Probe daemon may see your agent's work on it, as context. Nothing about it is recorded. |
| `hash` | `<pattern> @probe hash` | Runs over it are recorded, but each file only by its **identity**: path, SHA-256 (a fingerprint over 1 GiB), size and row count. Never its bytes, a preview, an upload or its text. The daemon treats it as `off`. |
| `on` | `!pattern`, or `<pattern> @probe on` | Recorded as usual. |

`@probe <level>` on a line of its own sets the level of every line after it, so written first it is the file's default:

```text .probe.config theme={null}
@probe read
notebooks/
experiments/
notebooks/private/ @probe off
notebooks/README.md @probe on
```

> [!NOTE]
>
> `read` and `off` both stop **recording**: no run is opened there, and no artifact, note or daemon record is made about those paths. Only the daemon tells them apart: with `read` it still sees the work, so it understands the session; with `off` it never does. Your agent's own searches of your team's history still work, and session transcripts are still uploaded.

### `hash`: lineage for data Probe must not read

Use `hash` for data whose contents must stay on your machines but whose history you still want: patient records, customer data, anything licensed. Steps over it still become runs, and each file a step reads or writes is recorded as a hash and a row count, so the record shows that one step read `raw.jsonl` (30,000 rows) and wrote `clean.jsonl` (29,156 rows) without Probe ever seeing a record (`probe run inputs` lists a run's reads).

Probe does not link runs by matching those hashes. A run's link to the dataset or checkpoint it used comes from a use that your agent or the SDK records, naming a fixed version (`probe dataset use dataset:<name>@<N> --run <run>`, or `run.use_dataset` in the SDK).

```text data/.probe.config theme={null}
@probe hash
*
```

* A step that is not a Python script (`head`, `jq`, `cat | shuf`) names its files so they are hashed too: `probe exec --input raw.jsonl --output clean.jsonl -- sh -c "..."`.
* `probe exec` keeps no console log when its folder, or any path it names, is `hash`, `read` or `off`: the step may print records.
* A file under 64 bytes is recorded with its path and size only, no hash. A hash reveals a file's contents only to someone who can already guess them exactly; for a short, predictable file that is easy, so Probe does not send one.
* Uploads (`probe dataset add --upload`, `log_dataset(upload=True)`) of a `hash` path are refused. A checkpoint saved in a `hash` folder is recorded as a reference (path, hash, size, step), never uploaded.
* One path has one level, so `read` and `hash` do not combine.

## Common setups

**One repo out**

In the repo's root:

```text .probe.config theme={null}
*
```

**Only some repos in**

In the folder that holds your repos:

```text ~/code/.probe.config theme={null}
/*
!/repo-a/
!/repo-b/
```

> [!WARNING]
>
> Use `/*`, not `*`. As in git, `*` matches at every depth, so `*` then `!/repo-a/` still excludes every file **inside** repo-a.

**Some paths out**

```text .probe.config theme={null}
data/
secrets/
*.ckpt
```

**Look, don't record**

The daemon may use the code as context, but records nothing about it:

```text .probe.config theme={null}
* @probe read
```

**Machine-wide**

`~/.probe.config` applies to everything under your home folder.

## How a path is decided

**1. Walk up from the path**

Every `.probe.config` from the path up to `/` counts, including files above a repository's root. A folder without one inherits its parents' rules.

**2. The last matching line wins**

A later line beats an earlier one, and a deeper file beats a shallower one. `/probe on` cannot override a level; edit the file instead.

**3. An off folder is closed**

As in git, nothing inside a folder at `off` is looked at, its own `.probe.config` included, and no line turns anything inside it back on. To keep one file, close the contents instead of the folder:

```text .probe.config theme={null}
secret/*
secret/important.txt @probe on
```

A folder at `read` or `on` stays open: what is inside takes the folder's level unless a line matches it directly. A deeper `.probe.config` may narrow a `read` folder to `off`, but never turns it back `on`.

**4. No match: the session decides**

Otherwise the session's `/probe on`, `read` or `off` decides, as before. A level only ever narrows what the session allows.

To see a path's level and the line that set it:

```bash theme={null}
probe ignore check data/rows.jsonl
```

## Files above where the agent started

A `.probe.config` in the folder the agent started in, or below it, always applies. One **above** that folder is yours to follow or set aside for each session: the agent asks you once, the first time Probe comes up, and follows the file until you answer.

## What is enforced where

| | |
| - | - |
| `probe` CLI | A write whose working directory or a path it names is `read` or `off` is refused. `probe exec` runs the command without opening a run. At `hash`, `probe exec` opens the run and records the files' identities, with no console log. |
| Python SDK | `probe.init()` in a `read` or `off` folder (or from such a script) opens no run and says so; code, output and read capture skip those paths; `log_artifact` on one records nothing. At `hash`, the run opens and reads and writes are recorded by identity only; nothing about the file's contents is sent. |
| Coding agent | Told at session start which paths `.probe.config` blocks Probe from recording; may create or edit a `.probe.config` when you ask or when it judges a path should not be recorded, and tells you each change. |
| Probe daemon | Drops the agent's work done in an `off` folder, naming an `off` file, or searching a folder that holds one (`rg`, `grep -r`, `find`, `git diff`), and its own commands never read one. Sees a `read` path's work tagged; any write naming it is refused. |

> [!NOTE]
>
> The daemon works from what the agent's commands say. A program that opens an `off` file without its command naming it (a training script reading `data/`) is outside this, as is text you or the agent type into the chat. Session transcripts still upload whole.

> [!WARNING]
>
> A `.probe.config` that exists but cannot be read excludes everything under its folder. `@probe` levels need CLI 0.231.0 and plugin 0.127.0 or later: older versions read `x @probe read` (and `x @probe off`) as a pattern that matches nothing, so they **record** those paths. Plain lines work from CLI 0.227.0 and plugin 0.125.0, so write `off` as a plain line. `@probe hash` needs CLI 0.253.0 or later: older versions read it as `off`, so they record nothing there (the safe direction). Update with `probe wizard --action update --yes`.

## Replacing folder defaults

`probe session default --folder` and the `.probe/config.json` files it wrote are retired. An old one set to `off` or `read` still keeps its folder out of Probe in coding-agent sessions, the only place it ever applied. `probe doctor` lists them, and `probe doctor --fix` turns each into a `.probe.config`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.