Trace lifecycle
This is the current operational path for a trace from local collection to reviewable SellTraces data.1. Local discovery
The CLI looks for supported transcript locations and source kinds. Discovery does not upload transcript content. Current source adapters include Claude Code projects, Cursor SQLite state, Codex sessions, Gemini CLI, OpenCode, and the local trace index.2. Scan and normalize
scanLocation() and scanChangedPath() parse source-specific files or SQLite rows into normalized trace objects through the shared ingest package.
This is the first structural mutation: local source files become trace objects with source, source id, messages, timestamps, client/provider data, environment metadata, and optional fields such as title or summary.
3. Local upload plan
Every CLI upload path builds an upload plan before any HTTP request:4. Web ingest request
POST /api/ingest authenticates the user, validates JSON or ZIP upload shape, recounts CLI JSON message tokens, writes the upload payload to blob storage, inserts an ingest_jobs row, and returns 202.
Heavy parse, scrub, score, and write work happens outside the web request.
5. Worker claim and parse
The ingest worker claims queued jobs with row locking, updates status toparsing, loads the raw upload blob, parses ZIP exports or decodes JSON traces, then marks the job ingesting.
Job statuses:
6. Server pipeline
For each trace, the server pipeline:- Normalizes the trace again.
- Computes an
original_hashfrom normalized role/content text unless supplied. - Runs server-side scrub.
- Inserts a
pii_rejectionsrow and stops if scrub rejects the trace. - Scores quality and uniqueness.
- Estimates value.
- Checks for existing duplicates by
(user_id, source, source_id)ororiginal_hash. - Inserts a new
tracesrow and message rows for new traces. - Writes per-trace raw and derived blobs.
7. Duplicate handling
Duplicate uploads do not create new trace rows. The pipeline may refresh nullable metadata on the canonical trace, such as model, summary, environment, timing, task type, or quality metadata. It does not rewrite existing message rows or per-trace blobs during that metadata refresh.8. Dashboard review
Dashboard include/exclude actions updatetraces.sell_excluded for unsold traces. Once a trace has a sale_traces row, include/exclude mutations are rejected because the trace has already sold.
Trace downloads stream the derived scrubbed blob and do not mutate the trace.
9. Sale and payout state
Sales attach traces throughsale_traces. Payouts attach user payment state through payouts.
Once sold, a trace remains part of that sale record even if later dashboard filters or review state change elsewhere.