--- name: coding-trace-collect description: "Collect, count, and extract Claude Code and Codex CLI local histories into normalized coding-trace JSONL files. Use when running collect_llm_traces.py, extract_claude_rounds.py, extract_codex_rounds.py, collect_all_users_sudo.sh, scanning current-user or all-user homes, choosing output paths, using --fresh-extract or --append-dedup, or troubleshooting extraction counts." --- # Coding Trace Collect ## Overview Use this skill to collect local Claude Code and Codex history stores and write normalized round traces. Collection finds source files and counts sessions; extraction converts provider-specific histories into JSONL rows where each line is one LLM invocation. ## First Steps 1. Work from the coding-trace repo root, identified by `pyproject.toml`, `README.md`, and `scripts/collect_llm_traces.py`. 2. Run every Python entry point through `uv run python ...`. 3. Decide scan scope before running commands: - Current user: default behavior. - All users under `/home`: use `--all-user`, or the sudo wrapper when unreadable homes are expected. Use `--home-root PATH` for nonstandard home roots. 4. Decide write behavior: - Default extraction appends deduped rows. - The sudo wrapper's default dated output is a fresh snapshot of currently readable sessions. - For a corpus refresh, merge fresh dated host snapshots after `trace/collections/current/merged.private.jsonl`; this both refreshes normalizer fields and retains history whose raw sessions have been cleaned up. - Use an explicit cumulative `--output` without `--fresh-extract` only when intentionally maintaining one append-only file. 5. Do not publish private outputs until `$coding-trace-sanitize` has been applied. 6. After sanitization, use `$coding-trace-analyze` for artifact and validator dispatchers. Collection should not own plotting outputs or timing-fit CSVs. ## Main Collection Commands Count current-user Claude and Codex history without extraction: ```bash uv run python scripts/collect_llm_traces.py ``` Extract a combined current-user trace: ```bash uv run python scripts/collect_llm_traces.py --extract-rounds ``` Write to a specific file and start fresh. This is the recommended current-user command only when intentionally creating a new, non-cumulative dataset: ```bash uv run python scripts/collect_llm_traces.py --extract-rounds trace/llm_round_trace.jsonl --fresh-extract ``` Scan all homes under `/home` without sudo: ```bash uv run python scripts/collect_llm_traces.py --all-user --extract-rounds ``` Use the sudo wrapper for a fresh, named all-user snapshot while preserving final file ownership. Reuse one `collection_id` on every host: ```bash collection_id="20260724-100b" scripts/collect_all_users_sudo.sh \ --collection-id "$collection_id" \ --fresh-extract ``` The wrapper writes `trace/collections//hosts/llm_round_trace_v2...all_users.jsonl` and a sibling `.collection_report.json`. With `--sanitize`, it also writes a sibling `.public.jsonl`. It prints an overview summary by default; add `--no-summary` for quiet batch runs. Add `--quiet-progress` only to suppress collector progress messages. To combine older and newer private normalized traces while letting newer normalizer fields win on overlap: ```bash uv run python scripts/merge_round_traces.py \ trace/collections/current/merged.private.jsonl \ "trace/collections/${collection_id}/hosts/"*.all_users.jsonl \ -o "trace/collections/${collection_id}/merged.private.jsonl" ``` For a private-to-public current-user flow: ```bash collection_id="20260724-100b" uv run python scripts/collect_llm_traces.py \ --extract-rounds "trace/collections/${collection_id}/merged.private.jsonl" \ --fresh-extract uv run python scripts/sanitize_round_trace.py \ "trace/collections/${collection_id}/merged.private.jsonl" \ -o "trace/collections/${collection_id}/merged.public.jsonl" ``` ## Timing Fit CSV The long-form timing-segment CSV is now owned by the timing-fit artifact, not the collection pipeline. `artifacts/run_all.py --db ` builds it automatically before timing analyses. Do not precompute it during normal collection. To build it directly for a timing-only manual run: ```bash uv run python artifacts/llm_generation/timing_fit/collect_timing_fit_trace.py \ --db trace/collections/current/merged.public.duckdb \ -o artifacts/llm_generation/timing_fit/timing_fit_trace.csv ``` The output has one timing segment per row. Claude segments use message-level output accounting; Codex can also emit reasoning-split segments when reasoning markers and exact reasoning-token counts are available. ## Output Paths Important output names: - Current-user combined trace: `trace/llm_round_trace.jsonl`. - Current-user Claude-only trace: `trace/claude_round_trace.jsonl`. - Current-user Codex-only trace: `trace/codex_round_trace.jsonl`. - Sudo-wrapper all-user trace: `trace/collections//hosts/llm_round_trace_v2...all_users.jsonl`. - Sudo-wrapper report: the sibling `.collection_report.json`. - Sudo-wrapper sanitized output with `--sanitize`: the sibling `.public.jsonl`. - Selected historical collection: `trace/collections/current`. - Timing-fit artifact CSV: `artifacts/llm_generation/timing_fit/timing_fit_trace.csv`. Use `--trace-dir DIR` to change the default extraction directory for omitted output paths. Passing an explicit path to `--extract-rounds`, `--extract-claude-rounds`, or `--extract-codex-rounds` overrides both the built-in default and `--trace-dir`. ## Provider-Specific Extraction Use direct extractors when the user already has a provider source directory: ```bash uv run python scripts/extract_claude_rounds.py ~/.claude/projects/PROJECT_DIR -o trace/claude_round_trace.jsonl --append-dedup ``` ```bash uv run python scripts/extract_codex_rounds.py ~/.codex/sessions -o trace/codex_round_trace.jsonl --append-dedup ``` Prefer `collect_llm_traces.py` for normal use because it scans both providers, handles `.claude.back`, tracks skipped paths, and combines extraction stats. ## Important Options - `--json`: emit a machine-readable collection report. - `--no-claude-back`: skip `.claude.back/projects`. - `--quiet-host-progress`: collector option that suppresses progress messages during host scanning and extraction. - `--quiet-progress`: sudo-wrapper option that passes the collector quiet mode. - `--collection-id`: safe collection slug used in both the collection directory and file names; prefer a UTC-date prefix such as `20260724-100b`. - `--no-summary`: sudo-wrapper option that skips the post-collection overview summary. - `--no-sudo`: sudo-wrapper option that runs all-user collection without sudo. - `--extract-project-filter TEXT`: only extract Claude projects whose directory name contains `TEXT`; repeat the option for multiple filters. - `--fresh-extract`: remove selected extraction outputs before writing. - `--append-dedup`: direct extractor option that appends only unseen `trace_key` rows. ## Validation After Collection After extraction, check basic shape before analysis: ```bash uv run python artifacts/trace_facts/overview_summary/analyze.py -i trace/collections/current/merged.private.jsonl ``` For JSON output: ```bash uv run python artifacts/trace_facts/overview_summary/analyze.py -i trace/collections/current/merged.private.jsonl --json ``` If outputs are unexpectedly small, inspect the collection report for `skipped_paths`, source counts, `candidate_rounds`, `written_rounds`, and `skipped_duplicate_rounds`.