Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Emitting the contract is the supported way to integrate a new system. The adapte
- [Watch a run tree](#watch-a-run-tree)
- [Improvement engine](#improvement-engine)
- [Session index](#session-index)
- [Session bundle](#session-bundle)
- [Session bundle](#session-bundle) · [Two views](#two-views-two-consumers)
- [Policy-mining evidence](#policy-mining-evidence)
- [Upload to the Intelligence Platform](#upload-to-the-intelligence-platform)
- [Trace analysts](#trace-analysts)
Expand Down Expand Up @@ -245,6 +245,7 @@ traces analyze --otlp results/sessions --out report.md
traces convert --harness claude-code --last 1 --otlp-out spans.jsonl # OTLP only
traces index --all --since 24h --out session-index.json
traces bundle --harness claude-code --session <id|path> --out bundle-dir # one session's durable evidence dir
traces bundle-view bundle-dir --view evidence-only --out writer-dir # same session, without its own words
traces inspect session-index.json --out inspection-report.md
traces evidence --harness codex --last 20 --out policy-evidence.jsonl
traces evidence --harness codex-exec --session /tmp/codex.jsonl --cwd "$PWD" --out policy-evidence.jsonl
Expand Down Expand Up @@ -472,11 +473,38 @@ The bundle directory:
- `derived/` — `session-index.json`, the deterministic `report.md`, `evidence.jsonl`, and the OTLP span artifact
- `ledger/` — the repo's `.evolve` slices for the session window: `experiments.jsonl` and `skill-runs.jsonl` rows inside the padded span window, `current.json` / `scorecard.json` / `progress.md` copied whole, the latest flat `handoff-*.md`, and reflections dated inside the window
- `repo/git-log.txt` — commits in the session window from the session's cwd
- `manifest.json` — SHA-256 + byte count per file, provenance (session id, harness, cwd, transcript hash, session window), every absent artifact with its reason, per-slice row counts, and the bundle's known limits
- `manifest.json` — `view`, SHA-256 + byte count per file, provenance (session id, harness, cwd, transcript hash, session window), every absent artifact with its reason, per-slice row counts, and the bundle's known limits

A missing transcript fails the assembly loudly.
Every optional input that is absent (no subagents, no `.evolve`, no git repo) is recorded in `manifest.absent` with the probed path — a fact, not an error.

### Two views, two consumers

A bundle has two kinds of reader, and they need opposite things.

- An **auditor** cites the session and needs every source byte. That is the FULL view — what `traces bundle` writes, `manifest.view: "full"`.
- A **writer** must reach its own conclusion about the session, so it must not be able to read the conclusion that session already reached. That is the EVIDENCE-ONLY view, `manifest.view: "evidence-only"`.

The full bundle cannot serve the writer. Its transcript holds every word the session wrote, including the shell call that authored an earlier report, so a check that looks for the report FILE passes while the report CONTENT is right there. Projecting is the fix, not grepping:

```bash
traces bundle --harness claude-code --session <id|path> --out bundle-dir
traces bundle-view bundle-dir --view evidence-only --out writer-dir
```

The evidence-only view carries an explicit allow-list — `derived/session-index.json`, `derived/evidence.jsonl`, and the structured `ledger/` records (`current.json`, `scorecard.json`, `skill-runs.jsonl`). Everything else is excluded **by name** in `manifest.excluded`, with its SHA-256 and one of four rules:

| rule | what it covers |
|---|---|
| `session-source` | `session/` — the transcript and every subagent transcript |
| `session-text-derived` | `derived/report.md` (quotes the first prompt line and evidence excerpts) and `derived/trace.otlp.jsonl` (spans carry the full prompt and response text) |
| `authored-prose` | `ledger/progress.md`, `ledger/handoff-*.md`, `ledger/reflections/`, `ledger/experiments.jsonl` free-text, `repo/git-log.txt` |
| `not-allow-listed` | any other path, including one a later version of `traces` adds — the view can only narrow by accident, never widen |

The allow-list is the structure. A content check is the proof it is right: before anything is written, every candidate is compared against every excluded file for shared 8-word runs of prose, with identifiers (paths, URLs, hashes) and this package's own constant strings scrubbed from both sides first. A shared run in a repo ledger file drops that file with `rule: "content-signature"` and the match count; a shared run in an artifact `traces` derives is a defect in the derivation and no view is written at all. `manifest.projection.leakCheck` records the width, the sources compared, and the result — always `matches: 0`, because a match means no view exists.

A projected view also carries the full bundle's `manifest.json` hash, so an auditor can prove which record it came from. Projecting a view of a view is refused.

## Policy-mining evidence

`traces` does **not** emit benchmark campaign cells. It emits normalized coding-agent session evidence that another system can mine.
Expand Down
27 changes: 19 additions & 8 deletions skills/inspect-agent-traces/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ traces analyze --otlp results/sessions --out .traces/all.md # a directory of e
Use `--harness` only for coding agents whose on-disk format we do not control.
Those adapters are the legacy edge, not the way to integrate a system you own.

A directory is a run directory: it holds the span export beside raw event, stream and
SDK logs that are also `*.jsonl`. Only the OTLP files are read, and the rest are listed
with what they actually hold. An `otlp/` subdirectory, when the producer made one, is
read on its own.
A run directory holds the span export beside raw event, stream and SDK logs that are
also `*.jsonl`. Only the OTLP files are read; the rest are listed with what they hold.
An `otlp/` subdirectory, when present, is read on its own.

Any section headed `inputs incomplete`, or carrying an `Inputs incomplete` line above
its table, is computed from a field the trace does not carry everywhere. Report those
Expand Down Expand Up @@ -73,20 +72,32 @@ traces improve --harness codex --current --latest-turn --workflow \
`improve` writes findings, evidence, a report, and spans.
It does not edit an agent, repository, memory store, or knowledge base.

Write one session's durable evidence directory when a later reader must cite the session:
Write one session's durable evidence directory for a later reader:

```bash
traces bundle --harness claude-code --session <id-or-path> --out .traces/bundle
```

`bundle` copies the transcript, the derived report and spans, the `.evolve` ledger rows inside the session window, and a `manifest.json` with a SHA-256 per file.
It spends no model call.
Use it when the live stores can rotate before the reader arrives.
A missing transcript stops the assembly.
An absent optional input is recorded in `manifest.absent` with the probed path.

The bundle holds the whole session transcript.
Do not give a bundle to a writer that must not see an earlier conclusion, because the transcript holds the text of every file the session wrote.
## Pick the view for the reader

That bundle is the FULL view (`manifest.view: "full"`), and it holds the whole session transcript.
Never give it to a writer that must not see an earlier conclusion: the transcript holds the text of every file the session wrote, so a check for the earlier report FILE passes while its CONTENT is still readable.

Project the writer's copy instead:

```bash
traces bundle-view .traces/bundle --view evidence-only --out .traces/writer
```

That view carries `derived/session-index.json`, `derived/evidence.jsonl`, and the structured `ledger/` records.
It excludes the transcripts, the report, the spans, and every prose ledger file by name, with rules and hashes in `manifest.excluded`.
Before writing, it compares each carried file against each excluded file for shared 8-word runs of prose, and drops any file that repeats one.
`manifest.view` names which copy you hold.

## Report

Expand Down
Loading
Loading