@tangle-network/traces 0.21.1 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -270,7 +270,6 @@ not the way to integrate a system you own — for that, [emit the contract](#int
270
270
  | `qwen` (`qwen-code`) | `~/.qwen/projects/<cwd>/chats/*.jsonl` | fixture |
271
271
  | `amp` | `~/.local/share/amp/threads/T-*.json` | fixture |
272
272
  | `github-copilot` (`copilot`) | `~/.copilot/session-state/<id>/events.jsonl` | fixture |
273
- | `forge` (`forgecode`) | `/dump` JSON exports | fixture |
274
273
 
275
274
  Every adapter captures the conversation stored in one session file: the **user's prompt** and the **assistant's response** text, plus tool calls/results and token usage.
276
275
  Claude Code, Codex, current OpenCode, Pi, Kimi, and Factory read native records through [`@tangle-network/harness-sessions`](https://github.com/tangle-network/agent-sdk/tree/main/packages/harness-sessions); traces adds conversation and workflow spans over its model and tool calls. Historical OpenCode JSON sessions remain readable through the older adapter because their IDs do not overlap the SQLite store. Kimi's wire log has no served-model field, so its model remains unknown rather than being guessed.
@@ -282,7 +281,6 @@ The Claude transcript proves turns and tool calls, but does not prove loop itera
282
281
  Codex stores each worker in a separate session file; add `--workflow` to resolve the connected coordinator and worker files.
283
282
  `github-copilot` is the one exception: its log format carries no user prompt.
284
283
  Factory stores token totals in `.settings.json`, not per turn.
285
- Forge reads `/dump` JSON exports; live SQLite remains unsupported.
286
284
  ACP-only bridges may not persist a local transcript.
287
285
 
288
286
  ## CLI reference
@@ -297,6 +295,7 @@ traces investigate --all --last 10 --out report.md # explicit investigation ali
297
295
  traces improve --all --last 10 --dir .traces/improvement
298
296
  traces ask --harness codex --session <id> --question "Which commands failed?"
299
297
  traces facts --harness codex --session <id> # the deterministic facts sheet, $0
298
+ traces facts --all --since 2026-10-14 --until 2026-10-15 # every session with a record that day, that day's turns
300
299
  traces skills --since 30d # skill use across every local session, incremental, $0
301
300
  traces diff run-a.otlp.jsonl run-b.otlp.jsonl # where two runs of one task first diverge
302
301
  traces mcp --otlp spans.otlp.jsonl # read-only trace tools for an MCP client
@@ -349,7 +348,8 @@ See [Replay verification](./docs/replay-verify.md) for setup, semantics, and hon
349
348
  | `--workflow` | Expand selected files through stable parent and child session IDs |
350
349
  | `--max-workflow-sessions <n>` | Stop workflow expansion before parsing more than `n` files; default `100` |
351
350
  | `--cwd <dir>` | Filter by working directory |
352
- | `--since <t>` | `upload`: window, `30m`/`2h`/`7d` or ISO (default 24h); `analyze`: ISO cutoff |
351
+ | `--since <t>` | `30m`/`2h`/`7d` before now, or an ISO date. Commands that select sessions read those modified at or after it; `upload`: its window (default 24h); `facts`: opens a time window — see [Session facts](#session-facts) |
352
+ | `--until <t>` | `facts`: closes the time window (exclusive), same forms as `--since` |
353
353
  | `--out <path>` | Write the report to a file |
354
354
  | `--dir <path>` | `improve`: write the full artifact pack to this directory; `ask`: write `answers.json` + `report.md` there |
355
355
  | `--otlp <file\|dir>` | **READ** OTLP-JSONL from any system, skipping the adapters; a directory reads the OTLP files under it (only `otlp/` when the producer made one) and names the JSONL that is not OTLP. `validate`, `check`, `analyze`, `investigate`, `improve`, `ask`, `stream` |
@@ -592,11 +592,14 @@ The same facts sheet includes observed tool outcomes, captured input/output byte
592
592
  volumes, call-to-result intervals, compaction boundaries and available context
593
593
  sizes, spawn intervals, and existing skill invocation/document-read evidence.
594
594
  Each measurement carries coverage; absent telemetry remains unknown.
595
- `facts --no-content` withholds conversation, command, changed-file and assignment
596
- text while retaining measurement metadata. This is a local metadata view, not a
595
+ `facts --no-content` withholds conversation (including each turn's `answered` text),
596
+ command, changed-file, working-directory and assignment text while retaining
597
+ measurement metadata. This is a local metadata view, not a
597
598
  share-safety certificate.
598
599
 
599
600
  SDK consumers use `buildSessionFactsReport(spans, { includeContent: false })`.
601
+ Pass `window: { since, until }` (ISO bounds) for the windowed report `facts --since/--until` prints, and use
602
+ `createSessionFactsReportBuilder(options)` (`add(spans)`, `addUnread(...)`, `build()`) to build it one session at a time.
600
603
  Cache by `measurementVersion` and `sourceDigest`; `evidenceThrough` is the latest
601
604
  recorded endpoint, not current liveness. Computing the sheet parses the supplied
602
605
  spans; returning a stored sheet needs no model call or trace scan. Semantic
@@ -610,8 +613,17 @@ No model call, no engine, no budget — it costs $0 and always returns the same
610
613
  traces facts --harness codex --session <id> # JSON on stdout
611
614
  traces facts --harness codex --last 5 --format text # the short readable form
612
615
  traces facts --otlp spans.otlp.jsonl --out facts.json
616
+ traces facts --harness claude-code --since 7d # every session with a record in the last week
617
+ traces facts --all --since 2026-10-14 --until 2026-10-15 # one day, across every harness
613
618
  ```
614
619
 
620
+ `--since <t>` and `--until <t>` open a half-open time window `[since, until)`; each takes `30m`/`2h`/`7d` before now or an ISO date, and either may be left open.
621
+ With a window, `facts` selects **every** session with a record that starts or ends inside it, not only the newest (`--last <n>` still caps it to the newest `n` per harness, and `--session` or `--otlp` still name the input).
622
+ Sessions are read one at a time, and a session file last modified before `since` is not read, because it cannot hold a later record.
623
+ Within a selected session, `humanTurns`, `excludedTurns` and `turnsByActor` keep only turns that started inside the window, so a one-day run counts only that day's turns; every other fact covers the whole session.
624
+ The report's `selection` states the window, both rules, the sessions read whose records all fell outside it (`outsideWindow`), and every session that could not be read (`unreadSessions`, each with its reason).
625
+ A report built without a window has `selection: null`.
626
+
615
627
  | Fact | What it is |
616
628
  |---|---|
617
629
  | `toolCalls` | TOOL spans **this session's agent** actually invoked. Synthesized lifecycle spans are excluded and counted in `synthesizedToolSpans`, so the total is not high by the number of subagents; calls a spawned subagent made are excluded and counted in `subagentToolSpans` |
@@ -619,7 +631,8 @@ traces facts --otlp spans.otlp.jsonl --out facts.json
619
631
  | `subagentToolSpans` | TOOL spans excluded because a subagent, not this agent, made the call. Zero on a trace that carries no subagent records |
620
632
  | `subagents` | every subagent-spawning call with the task name the adapter recorded |
621
633
  | `pullRequests` | the pull requests the commands created and merged, each named by number or head branch, with the command span and how the identity was joined. Scanned the way a shell reads the script, so a `gh pr create` inside a heredoc body is not a command that ran |
622
- | `humanTurns` | `user.prompt` turns a person typed into this session, in order, with the timestamp. Inherited fork or compaction history, harness-injected blocks, and a second record of the same turn are excluded — each listed in `excludedTurns` with its reason and span ids, never silently dropped. `turnsByActor` shows every turn by actor so the filter is checkable |
634
+ | `cwd` | the working directory the harness recorded for the session (`traces.session.cwd` on the root span): Claude Code's first record `cwd`, Codex's `session_meta` cwd, Pi's session header, OpenCode's session directory (the older JSON store: its messages' `path.cwd`), Factory's `session_start`. Never decoded from a directory name or inferred from paths; `null` with the reason when the source names none or its adapter does not read one |
635
+ | `humanTurns` | `user.prompt` turns a person typed into this session, in order, with the timestamp. Inherited fork or compaction history, harness-injected blocks, and a second record of the same turn are excluded — each listed in `excludedTurns` with its reason and span ids, never silently dropped. `turnsByActor` shows every turn by actor so the filter is checkable. Each turn's `answered` is the last message this session's own agent wrote before it (not a subagent's, not inherited history), clipped to 1,500 characters with a `… [+N chars]` marker, with its span in `answeredSpanId`; `null` when the agent had written no text yet in the spans read (a `--latest-turn` read starts at the latest task, so its first turn has none) |
623
636
  | `finalMessages` | the last message of the session's own agent, and of each subagent task, kept apart |
624
637
  | `changedFiles` | paths the harness recorded for the changes it applied, plus paths named by patch headers and file-editing tool arguments, with the operation |
625
638
  | `firstRecordAt` / `lastRecordAt` | the earliest span start and latest span end among this session's own records — a subagent that outlives the session does not stretch its window |
@@ -633,7 +646,8 @@ Three rules hold for every field:
633
646
  - **Every fact names its span ids.** `spanIds` lists the spans the value was computed from, so any number here can be opened and checked. The sheet itself is not a span and cannot be cited.
634
647
  - **A fact the spans cannot support is `null` with its reason.** It is never guessed, and never a silent zero. `partial` marks a measured value that is known to be incomplete — a truncated patch, or a list above the entry cap.
635
648
 
636
- `facts` exits non-zero when a selected session cannot be read at all: a session that produced no record spans would otherwise print a sheet of zeros stating, in the sheet's own voice, that the session did nothing.
649
+ Without a window, `facts` exits non-zero when a selected session cannot be read at all: a session that produced no record spans would otherwise print a sheet of zeros stating, in the sheet's own voice, that the session did nothing.
650
+ With a window, a session that cannot be read — the parser failed, or no record could be read — is named in `selection.unreadSessions` with its reason and a warning on stderr, and the run still exits 0 with the sessions it could read; it is never counted as a session with no turns.
637
651
 
638
652
  The same sheet reaches the model-backed analysts as prepared context, before their first model call — see [Trace analysts](docs/trace-analysts.md#session-facts-as-prepared-context).
639
653