Files
ai-agent/scripts/schema-baseline.json
Gabriel Vidal 71572a63fc feat(ai-agent): transcript schema-drift checker + parser canary
Claude Code's on-disk JSONL transcript format is internal and undocumented,
so a CLI update can silently break backend/conversations.py. Add
scripts/schema-drift.py as the early-warning system: it diffs a structural
footprint (key paths + content-block types, no values) of recent
~/.claude/projects transcripts against a committed baseline, and runs the
real parser over the same files cross-checking its summary against raw
record counts (usage turns, tokens, models, timestamps). New CC versions
are INFO-only; new schema paths or a failed invariant exit 1.

Baseline generated from the 300 newest transcripts (cc 2.1.206-207);
verified the check trips on a simulated usage-key rename.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 22:07:04 +02:00

263 lines
9.5 KiB
JSON

{
"note": "structural footprint of Claude Code transcript JSONL \u2014 key paths & block types only, no content",
"ccVersions": [
"2.1.206",
"2.1.207"
],
"paths": [
"ai-title.aiTitle",
"ai-title.sessionId",
"ai-title.type",
"assistant.agentId",
"assistant.attributionAgent",
"assistant.attributionPlugin",
"assistant.attributionSkill",
"assistant.cwd",
"assistant.entrypoint",
"assistant.gitBranch",
"assistant.isApiErrorMessage",
"assistant.isSidechain",
"assistant.message",
"assistant.message.container",
"assistant.message.content",
"assistant.message.content[fallback]",
"assistant.message.content[fallback].from",
"assistant.message.content[fallback].from.model",
"assistant.message.content[fallback].to",
"assistant.message.content[fallback].to.model",
"assistant.message.content[text]",
"assistant.message.content[text].text",
"assistant.message.content[thinking]",
"assistant.message.content[thinking].signature",
"assistant.message.content[thinking].thinking",
"assistant.message.content[tool_use]",
"assistant.message.content[tool_use].caller",
"assistant.message.content[tool_use].caller.type",
"assistant.message.content[tool_use].id",
"assistant.message.content[tool_use].input",
"assistant.message.content[tool_use].name",
"assistant.message.context_management",
"assistant.message.diagnostics",
"assistant.message.diagnostics.cache_miss_reason",
"assistant.message.diagnostics.cache_miss_reason.cache_missed_input_tokens",
"assistant.message.diagnostics.cache_miss_reason.type",
"assistant.message.id",
"assistant.message.model",
"assistant.message.role",
"assistant.message.stop_details",
"assistant.message.stop_reason",
"assistant.message.stop_sequence",
"assistant.message.type",
"assistant.message.usage",
"assistant.message.usage.cache_creation",
"assistant.message.usage.cache_creation.ephemeral_1h_input_tokens",
"assistant.message.usage.cache_creation.ephemeral_5m_input_tokens",
"assistant.message.usage.cache_creation_input_tokens",
"assistant.message.usage.cache_read_input_tokens",
"assistant.message.usage.inference_geo",
"assistant.message.usage.input_tokens",
"assistant.message.usage.iterations",
"assistant.message.usage.output_tokens",
"assistant.message.usage.server_tool_use",
"assistant.message.usage.server_tool_use.web_fetch_requests",
"assistant.message.usage.server_tool_use.web_search_requests",
"assistant.message.usage.service_tier",
"assistant.message.usage.speed",
"assistant.parentUuid",
"assistant.requestId",
"assistant.sessionId",
"assistant.session_id",
"assistant.slug",
"assistant.timestamp",
"assistant.type",
"assistant.userType",
"assistant.uuid",
"assistant.version",
"attachment.agentId",
"attachment.attachment",
"attachment.cwd",
"attachment.entrypoint",
"attachment.gitBranch",
"attachment.isSidechain",
"attachment.parentUuid",
"attachment.sessionId",
"attachment.session_id",
"attachment.slug",
"attachment.timestamp",
"attachment.type",
"attachment.userType",
"attachment.uuid",
"attachment.version",
"file-history-snapshot.isSnapshotUpdate",
"file-history-snapshot.messageId",
"file-history-snapshot.snapshot",
"file-history-snapshot.snapshot.messageId",
"file-history-snapshot.snapshot.timestamp",
"file-history-snapshot.snapshot.trackedFileBackups",
"file-history-snapshot.snapshot.trackedFileBackups.../homelab-drawer-followup/services/ai-agent/frontend/src/business/composer/components/SpawnBox.tsx",
"file-history-snapshot.snapshot.trackedFileBackups.../homelab-drawer-followup/services/ai-agent/frontend/src/business/composer/components/SpawnBox.tsx.backupFileName",
"file-history-snapshot.snapshot.trackedFileBackups.../homelab-drawer-followup/services/ai-agent/frontend/src/business/composer/components/SpawnBox.tsx.backupTime",
"file-history-snapshot.snapshot.trackedFileBackups.../homelab-drawer-followup/services/ai-agent/frontend/src/business/composer/components/SpawnBox.tsx.version",
"file-history-snapshot.snapshot.trackedFileBackups.../homelab-drawer-followup/services/ai-agent/frontend/src/business/conversations/pages/ConversationHome.tsx",
"file-history-snapshot.snapshot.trackedFileBackups.../homelab-drawer-followup/services/ai-agent/frontend/src/business/conversations/pages/ConversationHome.tsx.backupFileName",
"file-history-snapshot.snapshot.trackedFileBackups.../homelab-drawer-followup/services/ai-agent/frontend/src/business/conversations/pages/ConversationHome.tsx.backupTime",
"file-history-snapshot.snapshot.trackedFileBackups.../homelab-drawer-followup/services/ai-agent/frontend/src/business/conversations/pages/ConversationHome.tsx.version",
"file-history-snapshot.type",
"last-prompt.lastPrompt",
"last-prompt.leafUuid",
"last-prompt.sessionId",
"last-prompt.type",
"mode.mode",
"mode.sessionId",
"mode.type",
"permission-mode.permissionMode",
"permission-mode.sessionId",
"permission-mode.type",
"queue-operation.content",
"queue-operation.operation",
"queue-operation.sessionId",
"queue-operation.timestamp",
"queue-operation.type",
"relocated.relocatedCwd",
"relocated.sessionId",
"relocated.type",
"result.agentId",
"result.key",
"result.result",
"result.result.angles",
"result.result.angles[].label",
"result.result.angles[].query",
"result.result.angles[].rationale",
"result.result.caveats",
"result.result.claims",
"result.result.claims[].claim",
"result.result.claims[].importance",
"result.result.claims[].quote",
"result.result.confidence",
"result.result.counterSource",
"result.result.evidence",
"result.result.findings",
"result.result.findings[].claim",
"result.result.findings[].confidence",
"result.result.findings[].evidence",
"result.result.findings[].sources",
"result.result.publishDate",
"result.result.question",
"result.result.refuted",
"result.result.results",
"result.result.results[].relevance",
"result.result.results[].snippet",
"result.result.results[].title",
"result.result.results[].url",
"result.result.sourceQuality",
"result.result.summary",
"result.type",
"started.agentId",
"started.key",
"started.type",
"system.apiRefusalCategory",
"system.apiRefusalExplanation",
"system.compactMetadata",
"system.compactMetadata.cumulativeDroppedTokens",
"system.compactMetadata.durationMs",
"system.compactMetadata.postTokens",
"system.compactMetadata.preCompactDiscoveredTools",
"system.compactMetadata.preTokens",
"system.compactMetadata.preservedMessages",
"system.compactMetadata.preservedMessages.allUuids",
"system.compactMetadata.preservedMessages.anchorUuid",
"system.compactMetadata.preservedMessages.uuids",
"system.compactMetadata.preservedSegment",
"system.compactMetadata.preservedSegment.anchorUuid",
"system.compactMetadata.preservedSegment.headUuid",
"system.compactMetadata.preservedSegment.tailUuid",
"system.compactMetadata.trigger",
"system.content",
"system.cwd",
"system.direction",
"system.durationMs",
"system.entrypoint",
"system.fallbackModel",
"system.gitBranch",
"system.isMeta",
"system.isSidechain",
"system.level",
"system.logicalParentUuid",
"system.messageCount",
"system.originalModel",
"system.parentUuid",
"system.refusedUserMessageUuid",
"system.requestId",
"system.retractedMessageUuids",
"system.sessionId",
"system.slug",
"system.subtype",
"system.timestamp",
"system.trigger",
"system.type",
"system.userType",
"system.uuid",
"system.version",
"user.agentId",
"user.cwd",
"user.entrypoint",
"user.gitBranch",
"user.isCompactSummary",
"user.isMeta",
"user.isSidechain",
"user.isVisibleInTranscriptOnly",
"user.message",
"user.message.content",
"user.message.content[document]",
"user.message.content[document].source",
"user.message.content[document].source.data",
"user.message.content[document].source.media_type",
"user.message.content[document].source.type",
"user.message.content[text]",
"user.message.content[text].text",
"user.message.content[tool_result]",
"user.message.content[tool_result].content",
"user.message.content[tool_result].content[image]",
"user.message.content[tool_result].content[image].source",
"user.message.content[tool_result].content[image].source.data",
"user.message.content[tool_result].content[image].source.media_type",
"user.message.content[tool_result].content[image].source.type",
"user.message.content[tool_result].content[text]",
"user.message.content[tool_result].content[text].text",
"user.message.content[tool_result].content[tool_reference]",
"user.message.content[tool_result].content[tool_reference].tool_name",
"user.message.content[tool_result].is_error",
"user.message.content[tool_result].tool_use_id",
"user.message.role",
"user.origin",
"user.origin.kind",
"user.parentUuid",
"user.permissionMode",
"user.promptId",
"user.promptSource",
"user.sessionId",
"user.session_id",
"user.slug",
"user.sourceToolAssistantUUID",
"user.sourceToolUseID",
"user.timestamp",
"user.toolDenialKind",
"user.toolEndsTurn",
"user.toolUseResult",
"user.type",
"user.userType",
"user.uuid",
"user.version",
"worktree-state.sessionId",
"worktree-state.type",
"worktree-state.worktreeSession",
"worktree-state.worktreeSession.enteredExisting",
"worktree-state.worktreeSession.originalCwd",
"worktree-state.worktreeSession.preEnterOriginalCwd",
"worktree-state.worktreeSession.sessionId",
"worktree-state.worktreeSession.worktreeBranch",
"worktree-state.worktreeSession.worktreeName",
"worktree-state.worktreeSession.worktreePath"
]
}