Data Model: CLI 2.x Readiness Sprint

Feature: 039-cli-2x-readiness Date: 2026-02-12

Entities

Event (existing — spec_kitty_events.models.Event)

Immutable event envelope for distributed conflict detection.

FieldTypeConstraintsDescription
event_idstr26 chars, ULID formatUnique event identifier
event_typestrmin 1 chare.g., 'WPStatusChanged', 'MissionStarted'
aggregate_idstrmin 1 charEntity being modified (WP ID, mission ID)
payloadDict[str, Any]-Event-specific data
timestampdatetimeISO 8601Wall-clock time (not used for ordering)
node_idstrmin 1 charEmitting node identifier
lamport_clockint>= 0Logical clock for causal ordering
causation_idOptional[str]26 chars if presentParent event ID
project_uuiduuid.UUID-Project this event belongs to
project_slugOptional[str]-Human-readable project identifier
correlation_idstr26 chars, ULIDGroups events in same execution
schema_versionstrsemverEnvelope version (default "1.0.0")
data_tierint0-4Progressive sharing tier

QueueEntry (existing — sync/queue.py SQLite)

Persisted event in the offline SQLite queue.

FieldTypeConstraintsDescription
idintAUTO_INCREMENTQueue entry ID
datatextJSONSerialized event envelope
retry_countint>= 0, default 0Number of failed sync attempts
created_attextISO 8601When event was queued
last_attempt_attextISO 8601, nullableLast sync attempt timestamp
statustextpending/failed/syncedCurrent queue entry status

StatusTransitionPayload (existing — spec_kitty_events.status)

Payload for WPStatusChanged events.

FieldTypeConstraintsDescription
feature_slugstr-Feature identifier
wp_idstr-Work package ID
from_laneOptional[Lane]7-lane enumPrevious lane (None for initial)
to_laneLane7-lane enumTarget lane
actorstr-Who performed the transition
forcebool-Whether transition was forced
reasonOptional[str]Required if force=TrueForce justification
execution_modeExecutionModeWORKTREE/DIRECT_REPOHow the transition was executed
review_refOptional[str]-Git ref for review
evidenceOptional[DoneEvidence]Required if to_lane=DONECompletion evidence

Lane (existing — spec_kitty_events.status.Lane)

7-lane canonical status model.

Value4-Lane Sync MappingTerminal?
PLANNEDplannedNo
CLAIMEDdoingNo
IN_PROGRESSdoingNo
FOR_REVIEWfor_reviewNo
DONEdoneYes
BLOCKEDdoingNo
CANCELEDdoneYes

Alias: doingIN_PROGRESS (resolved by LANE_ALIASES)

Credentials (existing — sync/auth.py)

TOML file at ~/.spec-kitty/credentials.

SectionFieldTypeDescription
tokensaccessstrJWT access token
tokensrefreshstrJWT refresh token
expiriesaccessstrAccess token expiry (ISO 8601)
expiriesrefreshstrRefresh token expiry (ISO 8601)
userusernamestrAuthenticated username
userteam_slugOptional[str]Team identifier
serverurlstrSaaS server base URL

State Transitions

Queue Entry Lifecycle

[created] → pending → (sync attempt) → synced (removed from queue)
                    → (sync attempt) → failed (retry_count++)
                                      → (max retries) → dead_letter (stays in queue)

Event Sync Flow

Status transition (move-task)
    → emit_status_transition() [emitter.py]
        → emit_wp_status_changed() [7→4 lane mapping]
            → queue event (SQLite) [queue.py]
                → batch send (HTTP POST) [batch.py]
                    → per-event result processing
                        → success: remove from queue
                        → duplicate: remove from queue
                        → rejected: increment retry_count
                        → 400 error: surface details

New Entities (this sprint)

BatchResult (new — to be added to batch.py)

Per-event result from batch response processing.

FieldTypeDescription
event_idstrEvent that was processed
statusstr"success", "duplicate", "rejected"
errorOptional[str]Error message if rejected
error_categoryOptional[str]Grouped category: schema_mismatch, auth_expired, server_error, unknown

QueueStats (new — to be added to queue.py)

Aggregate queue statistics for health display.

FieldTypeDescription
total_pendingintCount of pending events
total_failedintCount of failed events
oldest_event_ageOptional[timedelta]Age of oldest pending event
retry_distributionDict[str, int]Histogram: retry bucket → count
top_event_typesList[Tuple[str, int]]Most common event types in queue

DiagnoseResult (new — to be added to diagnose.py)

Result of local event validation.

FieldTypeDescription
event_idstrEvent that was validated
validboolWhether event passes schema validation
errorsList[str]Specific validation error messages
event_typestrType of the event