# Agent Transcript Sync

Provon can project persisted Claude Code, Codex, and Pi sessions into canonical OpenTelemetry spans.
Use this path when a coding agent already writes a local transcript and adding live SDK
instrumentation is unnecessary or impossible.

```text
local transcript -> detect and parse -> sanitize -> OTel spans -> POST /v1/traces
```

Transcript sync reads files from the local machine. The server does not scan developer
workstations.

## Supported Sources

| Source      | Typical directory       |
| ----------- | ----------------------- |
| Claude Code | `~/.claude/projects/`   |
| Codex       | `~/.codex/sessions/`    |
| Pi          | `~/.pi/agent/sessions/` |

Detection uses file content and known format signatures, not only the directory name. A parent
directory can therefore contain more than one supported source.

The adapter preserves:

- session and conversation identity;
- user, assistant, reasoning, and summary events;
- tool calls and tool results;
- model and token usage when present;
- timestamps, source locations, working directory, and agent version;
- warnings for malformed or incomplete source records.

## Run From The Repository

Build the CLI:

```bash
pnpm --filter @provon/cli build
```

Set the target project:

```bash
export PROVON_BASE_URL="http://127.0.0.1:3000"
export PROVON_API_KEY="your_project_api_key"
export PROVON_PROJECT_ID="your_project_id"
```

Run one backfill pass:

```bash
node cli/dist/bin.js sync ~/.claude/projects --once
```

When `@provon/cli` is installed as a package, the equivalent command is:

```bash
provon sync ~/.claude/projects --once
```

The API key needs `telemetry:ingest`.

## Diagnose Without Upload

Run the built-in diagnostic Rules directly against a transcript file or directory:

```bash
provon diagnose ~/.claude/projects/example/session.jsonl
provon diagnose ~/.codex/sessions --deterministic-only
```

This path does not require an API key or persist Findings. When semantic adjudication is required,
the calling Agent uses its current model and returns a hash-bound structured response. See
[Trace diagnosis with CLI](./trace-diagnosis.md).

## Preview Before Upload

Use a dry run to verify detection, parsing, warnings, and projected payload size without uploading
or changing sync state:

```bash
provon sync ~/.codex/sessions --once --dry-run --print-sample
```

The JSON result reports:

- detected sources;
- scanned, changed, skipped, and uploaded file counts;
- trace and conversation IDs;
- event and payload counts;
- parse warnings and per-file failures;
- the local state-file path.

Inspect the sample for private content before the first real upload.

## Tool Output Policy

Tool output often contains the strongest diagnostic evidence and the most sensitive data. Select a
mode explicitly:

| Mode        | Behavior                                                         |
| ----------- | ---------------------------------------------------------------- |
| `truncated` | Default. Retain tool results with bounded strings                |
| `none`      | Remove tool-result text and structured result values             |
| `full`      | Retain larger tool results, still subject to sanitization limits |

```bash
provon sync ~/.pi/agent/sessions --once --include-tool-output truncated
```

`none` reduces evidence for Rules that depend on failed command output, negative tool results, or
verification. `full` increases payload size and privacy risk.

## Sanitization

Before projection, the adapters:

- replace values under common secret-bearing keys such as API keys, authorization, cookies,
  passwords, private keys, secrets, and tokens;
- redact common provider keys, GitHub tokens, AWS access keys, and Bearer tokens found in strings;
- bound string length, array items, object keys, and nesting depth.

This is best-effort sanitization, not a data-loss-prevention boundary. Review source content and use
`--include-tool-output none` when the transcript can contain data that must never leave the
workstation.

## Continuous Sync

Omit `--once` to watch for changes:

```bash
provon sync ~/.claude/projects
```

The default watcher rescans every 30 seconds and waits 1 second for writes to settle. Configure
these values when the source writes large or slow transcript updates:

```bash
provon sync ~/.claude/projects \
  --poll-interval 60000 \
  --settle-ms 2000 \
  --max-payload-bytes 8388608
```

Provon stores a local content hash per file. Unchanged files are skipped. Changed files are
reprojected with stable trace and span IDs derived from the source session, allowing uploads to be
retried without inventing a new execution identity.

## Verify

After sync:

1. Open **Traces** and search for the reported trace ID.
2. Confirm that the root span identifies the coding-agent session.
3. Inspect message, tool-call, and tool-result ordering.
4. Open **Conversations** and confirm the reported conversation ID.
5. Review sync warnings before relying on the trace for diagnosis.

## Related Docs

- [Tracing overview](./tracing.md)
- [Tracing quickstart](./tracing-quickstart.md)
- [Trace model and instrumentation](./tracing-model.md)
- [Diagnosis-ready tracing](./tracing-best-practices.md)
- [Multi-agent and distributed tracing](./tracing-multi-agent.md)
- [Explore traces](./trace-explorer.md)
- [Tracing CLI](./tracing-cli.md)
- [Trace diagnosis with CLI](./trace-diagnosis.md)
- [Production tracing](./tracing-production.md)
