Webchat Runtime Truth Migration Playbook

Migrate and validate per-turn runtime truth with conversation current-runtime semantics.

Sections

Terminology & Glossary
📖 Documentation
Navigation
54 sectionsv0.1
📄 Webchat Runtime Truth Migration Playbook — glaze help webchat-runtime-truth-migration-playbook
webchat-runtime-truth-migration-playbook

Webchat Runtime Truth Migration Playbook

Migrate and validate per-turn runtime truth with conversation current-runtime semantics.

Topicwebchatmigrationpersistencesqlitedebuggingweb-chat

Purpose

This playbook explains the runtime-semantics cutover:

  • turn rows are authoritative (turns.runtime_key, turns.inference_id),
  • conversation rows expose only current pointer semantics (resolved_runtime_key in debug APIs).

Use this when upgrading existing SQLite stores or validating runtime-switch correctness.

Semantic Model

Two fields now represent different truths:

  • per-turn truth: turns.runtime_key and turns.inference_id.
  • conversation pointer: /api/debug/conversations and /api/debug/conversations/:id return resolved_runtime_key.

Do not treat conversation current runtime as full turn history.

API Contract Changes

Conversation debug payloads:

  • old key: current_runtime_key
  • new key: resolved_runtime_key

Turn debug payloads:

  • /api/debug/turns items include runtime_key and inference_id.
  • /api/debug/turn/:conv/:session/:turn phase items include runtime_key and inference_id.

Migration and Validation SQL

Inspect schema columns:

PRAGMA table_info(turns);

Expected additive columns:

  • runtime_key TEXT NOT NULL DEFAULT ''
  • inference_id TEXT NOT NULL DEFAULT ''

Check indexes:

SELECT name, sql
FROM sqlite_master
WHERE type = 'index'
  AND tbl_name = 'turns'
  AND name IN ('turns_by_conv_runtime_updated', 'turns_by_conv_inference_updated');

Validate runtime history for one conversation:

SELECT turn_id, runtime_key, inference_id, updated_at_ms
FROM turns
WHERE conv_id = 'your-conv-id'
ORDER BY updated_at_ms ASC, turn_id ASC;

Detect rows that still have empty backfill values:

SELECT COUNT(*) AS missing_runtime_or_inference
FROM turns
WHERE COALESCE(runtime_key, '') = ''
   OR COALESCE(inference_id, '') = '';

Inspect candidate metadata for manual recovery:

SELECT conv_id, session_id, turn_id, turn_metadata_json
FROM turns
WHERE COALESCE(runtime_key, '') = ''
   OR COALESCE(inference_id, '') = ''
LIMIT 50;

Troubleshooting Incomplete Backfill

Backfill is best-effort and uses turn metadata keys. Some old rows may remain empty when metadata was missing or non-canonical.

Recommended response:

  1. keep empty string sentinel for unknown historical rows,
  2. avoid fabricating runtime history from conversation-level latest pointer,
  3. use post-cutover rows for reliable runtime/inference analytics.

Release Notes Template

Use this snippet in release notes:

Runtime persistence semantics changed:
- per-turn runtime/inference are now first-class and queryable in turns.db,
- conversation debug APIs now expose resolved_runtime_key (latest pointer only),
- consumers must not infer historical runtime from conversation-level fields.

See Also