v1.0.0 — Production-stable
v1.0.0 — Production-stable
First production-stable release. Cuts the 1.x train from the v1.0 windowed-pipelines milestone (#42) and the v1 vision + roadmap RFC (#43).
Highlights since v0.7.0
New analytics pipelines
- Per-session windowed trajectory classifier — pair-keyed on
(prev_uuid, curr_uuid)with a six-valuetransition_kindenum:frustration_spike,resolution,reset,drift,clarification,none. Each text turn produces exactly one row; the session-first turn gets a synthetic pair withprev_uuid IS NULL. Sonnet 4.6 sees up to 16 windows per chunk in one structured-output call; sessions longer than 16 text turns split into anchor-sharing chunks. - Pair-keyed conflicts — rekeyed on
(turn_a_uuid, turn_b_uuid)withconflict_kind ∈ {disagreement, correction, reversal, impasse}andseverity ∈ {low, medium, high}. The legacyempty=truesentinel is gone — sessions with no conflicts produce zero rows. - Friction SQL stamps — regex fast-path (
status_ping,interruption,correction) runs before Sonnet; LLM-only forunmet_expectation/confusion/frustrationwhere session context is required.
Data model
turn_windowSQL view —LAG(uuid) OVER wwith a single named window clause beats the prior correlated-min by ~3:1 onread_jsonviews (every textual reference re-runs schema inference; LAG collapses to one FROM).- Ingest stamps —
ingest_stamps.parquetcarriesapprox_tokens(tiktoken cl100k × 0.78 Anthropic approximation),simhash64(blake2b 64-bit over lowercased 3-grams), andcanonical_uuid. Embed workers now skip near-duplicate rows viaLEFT JOIN ingest_stampswith acanonical_uuid IS NULL OR canonical_uuid = mt.uuidguard. is_compact_summaryprojection added; attachment-only rows filtered out ofmessages_text.
Plumbing
- 1h prompt cache on every Sonnet 4.6 system block —
cache_control: {"type":"ephemeral","ttl":"1h"}. Per-pipeline cache-stat accumulator (threading.Lock-protected) emits one summary line at INFO per pipeline run. - CLAUDE_SQL_HOME migration — caches move from
~/.claude/to a dedicated parent dir resolved viaXDG_DATA_HOME, macOS Application Support, or~/.claude-sql/. Idempotent legacy-cache move on first connect. analyzestale-connection bugfix —_rebind_vssruns after embed (to bind the newly populated Lance dataset) and between cluster/community stages. Drops VIEW-or-TABLE shape mismatch from register_vss's empty-namespace fallback.- Parallelized trajectory dispatch via
anyio.create_task_group— sessions run concurrently; theCapacityLimiterinsideclassify_oneis the single throttle (no double-acquire at the dispatcher).
Quality gates
- Patch coverage lifted to 91%+ (trajectory_worker 100%, conflicts_worker 100%, cli.py 92%).
- Two CodeQL
py/catch-base-exceptionfindings fixed — narrowBaseException → Exceptionso anyioCancelledErrorpropagates. - CodeQL
py/file-not-closedin a test mkstemp fake fixed by opening the fd per-call inside the closure. - Four CodeQL hygiene rules now documented in
CLAUDE.md.
Breaking changes
- Trajectory parquet schema —
(session_id, prev_uuid, curr_uuid, prev_sentiment, curr_sentiment, delta, is_transition, transition_kind, confidence, classified_at). Legacy per-message shards are detected viapq.ParquetFile.schema_arrowmarker-column probe (uuid+sentiment_delta) and deleted on first run. Thesentiment_arc(sid)macro now joins onmessage_trajectory.curr_uuidand returns(ts, role, curr_sentiment, delta, transition_kind, is_transition, confidence)— callers relying onsentiment_deltamust rebase todelta+curr_sentiment. - Conflicts parquet schema —
(session_id, turn_a_uuid, turn_b_uuid, conflict_kind, severity, agent_position, user_position, confidence, detected_at). Any caller wanting every session in the result set mustLEFT JOIN sessionsand coalesce missing counts to 0 (no empty-sentinel row). Legacy shards carryingconflict_idx/emptycolumns are purged on first run. - Embeddings store location —
~/.claude/embeddings_lance/is canonical; legacy~/.claude/embeddings/part-*.parquetis migrated automatically on first connect and remains for rollback.
Install / upgrade
# end-user path
uv tool upgrade claude-sql
# dev
uv syncKnown follow-ups (v1.1 scope)
- Conflicts prompt calibration — the v1.0 pair-keyed prompt returned 0 pair rows on the live 3,653-session corpus; v1.0 shipped storage-shape only.
- Conflicts pair-scanner (RFC 0002 §4.2) to replace the whole-session prompt with one row per adjacent turn pair.
cluster_worker.run_clustering --dry-runshould no-op cleanly when the Lance dataset is missing.