{
  "openapi": "3.1.0",
  "info": {
    "title": "Vedastro",
    "description": "Vedastro \u2014 Vedic astrology platform with Kundli, Dampatya Match, Palmistry, and personalized guidance from traditional Jyotish perspectives",
    "version": "1.0.0"
  },
  "paths": {
    "/health": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Health Check Top Level",
        "description": "Top-level ``/health`` alias for the Docker HEALTHCHECK probe.\n\nThe canonical client surface is ``GET /api/v1/health``; this\nunversioned alias exists so the in-container ``curl -fsS\nhttp://127.0.0.1:8000/health`` probe has a stable URL that does\nnot move when the API version is bumped. The response envelope\nis identical to the versioned route.",
        "operationId": "health_check_top_level_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/health": {
      "get": {
        "tags": [
          "System",
          "System"
        ],
        "summary": "Health Check",
        "description": "Health check endpoint (versioned: ``/api/v1/health``).",
        "operationId": "health_check_api_v1_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/personas": {
      "get": {
        "tags": [
          "Personas",
          "Personas"
        ],
        "summary": "List Personas",
        "description": "List all available AI personas.",
        "operationId": "list_personas_api_v1_personas_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/PersonaResponse"
                  },
                  "type": "array",
                  "title": "Response List Personas Api V1 Personas Get"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/personas/{persona_type}": {
      "get": {
        "tags": [
          "Personas",
          "Personas"
        ],
        "summary": "Get Persona Info",
        "description": "Get information about a specific persona.",
        "operationId": "get_persona_info_api_v1_personas__persona_type__get",
        "parameters": [
          {
            "name": "persona_type",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/PersonaType"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PersonaResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/personas/recommend": {
      "post": {
        "tags": [
          "Personas",
          "Personas"
        ],
        "summary": "Recommend Persona",
        "description": "Recommend a persona based on user query.",
        "operationId": "recommend_persona_api_v1_personas_recommend_post",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 10,
              "title": "Query"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Response Recommend Persona Api V1 Personas Recommend Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/chat": {
      "post": {
        "tags": [
          "Chat",
          "Chat"
        ],
        "summary": "Chat",
        "description": "Send a message to an AI astrologer persona.\n\nThe persona will respond based on its archetype and any stored\nuser context from memory.",
        "operationId": "chat_api_v1_chat_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/kundli/generate": {
      "post": {
        "tags": [
          "Kundli",
          "Kundli"
        ],
        "summary": "Generate Kundli",
        "description": "Generate a Vedic birth chart (Kundli) with detailed interpretation.\n\nv1 compatibility adapter. The authoritative chart math is delegated\nto the deterministic engine via :class:`VedicAstroService`. This\nroute is preserved so the existing app build continues to work;\nnew clients should prefer ``POST /api/v2/kundli/reports``.",
        "operationId": "generate_kundli_api_v1_kundli_generate_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KundliBirthInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KundliV1Response"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/kundli/compatibility": {
      "post": {
        "tags": [
          "Kundli",
          "Kundli"
        ],
        "summary": "Check Compatibility",
        "description": "Check compatibility between two birth charts (Kundali Milan).",
        "operationId": "check_compatibility_api_v1_kundli_compatibility_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompatibilityRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/horoscope/{rashi}": {
      "get": {
        "tags": [
          "Kundli",
          "Kundli"
        ],
        "summary": "Get Daily Horoscope",
        "description": "Get daily horoscope for a zodiac sign.",
        "operationId": "get_daily_horoscope_api_v1_horoscope__rashi__get",
        "parameters": [
          {
            "name": "rashi",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Rashi"
            }
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "en",
              "title": "Language"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/palmistry/analyze": {
      "post": {
        "tags": [
          "Palmistry",
          "Palmistry"
        ],
        "summary": "Analyze Palm",
        "description": "Analyze a palm image and provide reading.\n\nImage requirements:\n- Format: JPG or PNG\n- Dimensions: 1024x1024 to 2048x2048 (will be adjusted automatically)\n- Max size: 100MB",
        "operationId": "analyze_palm_api_v1_palmistry_analyze_post",
        "parameters": [
          {
            "name": "user_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "User Id"
            }
          },
          {
            "name": "context",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Context"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_analyze_palm_api_v1_palmistry_analyze_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PalmReadingResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/palmistry/quick-check": {
      "post": {
        "tags": [
          "Palmistry",
          "Palmistry"
        ],
        "summary": "Quick Palm Check",
        "description": "Quick check if image contains a valid palm.",
        "operationId": "quick_palm_check_api_v1_palmistry_quick_check_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_quick_palm_check_api_v1_palmistry_quick_check_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/memory/{user_id}/facts": {
      "get": {
        "tags": [
          "Memory",
          "Memory"
        ],
        "summary": "Get User Facts",
        "description": "Get all stored facts for a user.",
        "operationId": "get_user_facts_api_v1_memory__user_id__facts_get",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "User Id"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/memory/facts": {
      "post": {
        "tags": [
          "Memory",
          "Memory"
        ],
        "summary": "Set User Fact",
        "description": "Set or update a user fact.",
        "operationId": "set_user_fact_api_v1_memory_facts_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemoryFactRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/memory/{user_id}/facts/{key}": {
      "delete": {
        "tags": [
          "Memory",
          "Memory"
        ],
        "summary": "Delete User Fact",
        "description": "Delete a specific user fact.",
        "operationId": "delete_user_fact_api_v1_memory__user_id__facts__key__delete",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "User Id"
            }
          },
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Key"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/memory/{user_id}": {
      "delete": {
        "tags": [
          "Memory",
          "Memory"
        ],
        "summary": "Clear User Memory",
        "description": "Clear all memory for a user (GDPR compliance).",
        "operationId": "clear_user_memory_api_v1_memory__user_id__delete",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "User Id"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/memory/{user_id}/context": {
      "get": {
        "tags": [
          "Memory",
          "Memory"
        ],
        "summary": "Get User Context",
        "description": "Get the context that would be provided to the AI for this user.",
        "operationId": "get_user_context_api_v1_memory__user_id__context_get",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "User Id"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/legal": {
      "get": {
        "tags": [
          "Legal",
          "Legal"
        ],
        "summary": "Get All Legal",
        "description": "Get all legal documents (disclaimer, terms, privacy).",
        "operationId": "get_all_legal_api_v1_legal_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/legal/disclaimer": {
      "get": {
        "tags": [
          "Legal",
          "Legal"
        ],
        "summary": "Get Disclaimer",
        "description": "Get the service disclaimer.",
        "operationId": "get_disclaimer_api_v1_legal_disclaimer_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/legal/terms": {
      "get": {
        "tags": [
          "Legal",
          "Legal"
        ],
        "summary": "Get Terms",
        "description": "Get the terms of service.",
        "operationId": "get_terms_api_v1_legal_terms_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/legal/privacy": {
      "get": {
        "tags": [
          "Legal",
          "Legal"
        ],
        "summary": "Get Privacy",
        "description": "Get the privacy policy.",
        "operationId": "get_privacy_api_v1_legal_privacy_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/legal/acknowledgment": {
      "get": {
        "tags": [
          "Legal",
          "Legal"
        ],
        "summary": "Get Acknowledgment",
        "description": "Get the acknowledgment text for user consent.",
        "operationId": "get_acknowledgment_api_v1_legal_acknowledgment_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/sarvajna/chat": {
      "post": {
        "tags": [
          "Sarvajna",
          "Sarvajna"
        ],
        "summary": "Sarvajna Chat",
        "description": "Drive a Sarvajna Prakriti Index assessment conversation.\n\nAccepts user messages and returns Sarvajna's structured replies.\nThe assessment is conducted fully through conversation \u2014 questions,\nbatch summaries, follow-ups, and final archetype synthesis.",
        "operationId": "sarvajna_chat_api_v1_sarvajna_chat_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SarvajnaRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SarvajnaResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/sarvajna/opening": {
      "get": {
        "tags": [
          "Sarvajna",
          "Sarvajna"
        ],
        "summary": "Sarvajna Opening",
        "description": "Return the Sarvajna opening/greeting message.",
        "operationId": "sarvajna_opening_api_v1_sarvajna_opening_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/sarvajna/questions": {
      "get": {
        "tags": [
          "Sarvajna",
          "Sarvajna"
        ],
        "summary": "Sarvajna Questions",
        "description": "Return the Sarvajna question bank and mode limits.",
        "operationId": "sarvajna_questions_api_v1_sarvajna_questions_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v2/account/session": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Create Session",
        "operationId": "create_session_api_v2_account_session_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSessionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/firebase/session": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Create Firebase Session",
        "operationId": "create_firebase_session_api_v2_account_firebase_session_post",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FirebaseSessionExchangeRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/me": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Get Current Account",
        "operationId": "get_current_account_api_v2_account_me_get",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountProfileResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/profile": {
      "patch": {
        "tags": [
          "Account"
        ],
        "summary": "Update Profile",
        "operationId": "update_profile_api_v2_account_profile_patch",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfileUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountProfileResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/redeem-code": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Redeem Unlock Code",
        "operationId": "redeem_unlock_code_api_v2_account_redeem_code_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RedeemUnlockCodeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountProfileResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/consent": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Update Consent",
        "operationId": "update_consent_api_v2_account_consent_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConsentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountProfileResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/waitlist": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Update Waitlist",
        "operationId": "update_waitlist_api_v2_account_waitlist_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WaitlistUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountProfileResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/google/oauth/init": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Google Oauth Init",
        "description": "Redirect to Google's OAuth consent screen for server-side sign-in.",
        "operationId": "google_oauth_init_api_v2_account_google_oauth_init_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v2/account/google/oauth/callback": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Google Oauth Callback",
        "description": "Handle the Google OAuth callback, create a session, redirect to frontend.",
        "operationId": "google_oauth_callback_api_v2_account_google_oauth_callback_get",
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Code"
            }
          },
          {
            "name": "error",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Error"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/google/session/exchange": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Exchange Google Session Code",
        "description": "Exchange a one-time Google OAuth code for the session token.\n\nThe Google OAuth callback redirects with a one-time code in the\nURL fragment (``#google_session_code=...``). The frontend reads\nthe code and POSTs it here to receive the session token in the\nresponse body. The code is single-use and expires after 60\nseconds, so a code leaked via browser history or referrer is\nuseless after the first exchange or after the TTL.",
        "operationId": "exchange_google_session_code_api_v2_account_google_session_exchange_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GoogleSessionExchangeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GoogleSessionExchangeResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/export": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Export Account Data",
        "description": "Return a JSON export of all data currently retained for the user.\n\nThe export does not reset retention timers; expired or deleted data is\nexcluded. Token hashes and other sensitive session material are not\nincluded.",
        "operationId": "export_account_data_api_v2_account_export_get",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account": {
      "delete": {
        "tags": [
          "Account"
        ],
        "summary": "Delete Account",
        "operationId": "delete_account_api_v2_account_delete",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteAccountResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/logout": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Logout",
        "description": "Revoke the caller's current session.\n\nAllows a user to explicitly sign out, invalidating the session\ntoken server-side so it cannot be reused even if the client-side\ncopy is compromised.",
        "operationId": "logout_api_v2_account_logout_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoutResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/sessions/revoke-all": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Revoke All Sessions",
        "description": "Revoke all active sessions for the caller's account.\n\nUseful when a user suspects their account is compromised on\nanother device \u2014 this signs out every active session, including\nthe current one.",
        "operationId": "revoke_all_sessions_api_v2_account_sessions_revoke_all_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokeAllSessionsResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/checkout/start": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Checkout Start",
        "description": "Start a paid checkout session.\n\nWhen Dodo Payments is configured (via env), this returns a checkout URL\nthe frontend redirects to. When it is unavailable, it returns a typed 503\nso the frontend can show a clear retry state.",
        "operationId": "checkout_start_api_v2_account_checkout_start_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckoutStartRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutStartResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/checkout/return": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Checkout Return",
        "description": "Handle the return from a paid checkout redirect.\n\nThe frontend calls this after the user returns from the provider.\nThis endpoint does NOT grant access from the redirect alone \u2014 it\ncalls ``/account/me`` (via the session store) to sync the\nentitlement from the server-side source of truth.\n\nIf the entitlement is not active yet (provider webhook has not\narrived), the frontend should show a \"payment received, access\nis syncing\" state and retry.",
        "operationId": "checkout_return_api_v2_account_checkout_return_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckoutReturnRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutReturnResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/checkout/webhook": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Checkout Webhook",
        "description": "Server-to-server webhook from the payment provider.\n\nThis is the authority for granting/revoking access. A real\nprovider integration would verify the webhook signature before\nprocessing. This endpoint grants full access via\n``grant_access_from_checkout`` which records the payment details\nand updates the entitlement fields.\n\nThe ``session_token`` field is used to resolve the user when\navailable (e.g. from checkout metadata). When only ``user_id`` is\nknown, the admin ``grant_full_access(user_id=...)`` path is used.",
        "operationId": "checkout_webhook_api_v2_account_checkout_webhook_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckoutWebhookPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutReturnResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/checkout/dodo/webhook": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Dodo Checkout Webhook",
        "description": "Receive and process a verified Dodo Payments webhook delivery.",
        "operationId": "dodo_checkout_webhook_api_v2_account_checkout_dodo_webhook_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DodoWebhookResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/payment/status": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Payment Status",
        "description": "Return the current payment/subscription state.\n\nThe frontend uses this after a checkout return to show a syncing\nstate until the entitlement is confirmed by the server.",
        "operationId": "payment_status_api_v2_account_payment_status_get",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentStatusResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/billing/portal": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Billing Portal",
        "description": "Create a short-lived Dodo portal link for the signed-in customer.",
        "operationId": "billing_portal_api_v2_account_billing_portal_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BillingPortalRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingPortalResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/billing/history": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Billing History",
        "description": "Return recent payment states and direct Dodo invoice links.",
        "operationId": "billing_history_api_v2_account_billing_history_get",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingHistoryResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/billing/auto-renew": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Billing Auto Renew",
        "description": "Toggle renewal for the signed-in user's own Dodo subscription.",
        "operationId": "billing_auto_renew_api_v2_account_billing_auto_renew_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutoRenewRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DodoSubscriptionResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/billing/plan/preview": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Billing Plan Preview",
        "description": "Preview a next-renewal plan change without modifying the subscription.",
        "operationId": "billing_plan_preview_api_v2_account_billing_plan_preview_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlanChangeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanChangePreviewResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/account/billing/plan": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Billing Plan Change",
        "description": "Schedule a plan change for the signed-in user's next renewal.",
        "operationId": "billing_plan_change_api_v2_account_billing_plan_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlanChangeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DodoSubscriptionResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Account"
        ],
        "summary": "Billing Plan Change Cancel",
        "description": "Cancel the signed-in user's scheduled plan change.",
        "operationId": "billing_plan_change_cancel_api_v2_account_billing_plan_delete",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DodoSubscriptionResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/admin/health/dependencies": {
      "get": {
        "tags": [
          "Admin v2"
        ],
        "summary": "Read the deterministic engine dependency health baseline (v2).",
        "description": "Returns the admin baseline for the deterministic Kundli engine path, including skyfield availability, ephemeris file presence, and the load-probe result, plus stable engine identity strings. The aggregate ``overall_status`` rolls these up to ``ready`` / ``degraded`` / ``unavailable``.",
        "operationId": "read_admin_dependency_health_api_v2_admin_health_dependencies_get",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Admin baseline for the deterministic engine dependency stack.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminBaselineResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/admin/quality/golden-charts": {
      "get": {
        "tags": [
          "Admin v2"
        ],
        "summary": "Read the golden-regression fixture coverage baseline (v2).",
        "description": "Returns the admin baseline for the golden truth/report fixtures, including SHA-256 content identifiers, presence flags, a cross-fixture consistency check on the engine-relevant fields, and the engine version pinned inside the truth fixture. The same overall dependency status is also surfaced so the operator can interpret a degraded fixture read in context.",
        "operationId": "read_admin_golden_quality_api_v2_admin_quality_golden_charts_get",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Admin baseline for the golden-regression fixture coverage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminBaselineResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/admin/accounts": {
      "get": {
        "tags": [
          "Admin v2"
        ],
        "summary": "Search user accounts and usage for trial/full-access administration.",
        "operationId": "search_admin_accounts_api_v2_admin_accounts_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 120,
              "default": "",
              "title": "Q"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminUserAccessListResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/admin/accounts/{user_id}/grant-full-access": {
      "post": {
        "tags": [
          "Admin v2"
        ],
        "summary": "Grant one month of full access directly to a user account.",
        "operationId": "grant_admin_full_access_api_v2_admin_accounts__user_id__grant_full_access_post",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "User Id"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GrantFullAccessRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminUserAccessResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/admin/accounts/{user_id}/billing": {
      "get": {
        "tags": [
          "Admin v2"
        ],
        "summary": "Read the authoritative Dodo subscription and invoice history for an account.",
        "operationId": "read_admin_billing_account_api_v2_admin_accounts__user_id__billing_get",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "User Id"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminBillingAccountResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/admin/accounts/{user_id}/billing/refund": {
      "post": {
        "tags": [
          "Admin v2"
        ],
        "summary": "Initiate an idempotent full or partial Dodo refund.",
        "operationId": "refund_admin_payment_api_v2_admin_accounts__user_id__billing_refund_post",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "User Id"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 12,
              "maxLength": 200,
              "title": "Idempotency-Key"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminRefundRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminBillingOperationResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/admin/accounts/{user_id}/billing/renewal": {
      "post": {
        "tags": [
          "Admin v2"
        ],
        "summary": "Cancel immediately, cancel at period end, or restore renewal in Dodo.",
        "operationId": "change_admin_subscription_renewal_api_v2_admin_accounts__user_id__billing_renewal_post",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "User Id"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 12,
              "maxLength": 200,
              "title": "Idempotency-Key"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminRenewalRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminBillingOperationResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/admin/billing/delivery-status": {
      "get": {
        "tags": [
          "Admin v2"
        ],
        "summary": "Check welcome-mail and PostHog delivery readiness.",
        "operationId": "read_billing_delivery_status_api_v2_admin_billing_delivery_status_get",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminBillingDeliveryStatusResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/admin/unlock-codes": {
      "post": {
        "tags": [
          "Admin v2"
        ],
        "summary": "Generate a manual full-access unlock code.",
        "operationId": "create_admin_unlock_code_api_v2_admin_unlock_codes_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UnlockCodeCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnlockCodeCreateResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/admin/waitlist": {
      "get": {
        "tags": [
          "Admin v2"
        ],
        "summary": "List users who joined the private-preview waitlist.",
        "operationId": "list_admin_waitlist_api_v2_admin_waitlist_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminWaitlistResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/dimensions": {
      "get": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Get the backend-owned behavioral dimension rubric.",
        "description": "Return the full dimension registry.\n\nThe registry is a closed rubric: generated scenarios and scoring\nuse only these keys and option traits. The UI can fetch it to\ndisplay concern rationale, but should not let users add custom\ndimensions or traits.",
        "operationId": "get_dimensions_api_v2_behavioral_assessment_dimensions_get",
        "responses": {
          "200": {
            "description": "Closed rubric of dimensions and allowed traits.",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/BehavioralDimension"
                  },
                  "type": "array",
                  "title": "Response Get Dimensions Api V2 Behavioral Assessment Dimensions Get"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/suggestions": {
      "post": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Get suggested concerns and a coverage map.",
        "description": "Return curated concern chips and a dimension coverage map.\n\nPublic endpoint: no chart computation is required, so it can drive\nonboarding UI immediately.",
        "operationId": "get_suggestions_api_v2_behavioral_assessment_suggestions_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BehavioralSuggestionsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Concern chips and recommended scenario count.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralSuggestionsResponse"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/preview": {
      "post": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Generate a pre-scenario custom analysis.",
        "description": "Generate a custom analysis before the scenarios are shown.\n\nPublic endpoint. The analysis is grounded in the selected concerns and\nthe available chart/compatibility signals. When the LLM is unavailable\na deterministic fallback analysis is returned so the UI can proceed.",
        "operationId": "generate_preview_api_v2_behavioral_assessment_preview_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BehavioralPreviewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Custom analysis grounded in concerns and chart/compatibility signals.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralPreviewResponse"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/preview/save": {
      "post": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Save a pre-scenario custom analysis for chat reuse.",
        "description": "Persist a pre-scenario custom analysis so it can be reused in chat.",
        "operationId": "save_preview_api_v2_behavioral_assessment_preview_save_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BehavioralSavePreviewRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved preview.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralPreviewResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/scenarios": {
      "post": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Generate SJT-style behavioral scenarios.",
        "description": "Generate reusable SJT-style scenarios.\n\nThe endpoint is public for generation, but fails closed: it returns only a\nfresh, complete, fully validated set. Provider or validation failures are\nreported as 503 and no curated fallback is substituted.",
        "operationId": "generate_scenarios_api_v2_behavioral_assessment_scenarios_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BehavioralScenariosRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "A fresh, fully validated scenario set.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralScenariosResponse"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/scenarios/async": {
      "post": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Start async scenario generation. Returns a job_id for polling.",
        "description": "Start scenario generation as a background job.\n\nReturns immediately with a ``job_id``. Poll\n``GET /scenarios/jobs/{job_id}`` every 2-3 seconds until\n``status`` is ``completed`` or ``failed``.",
        "operationId": "generate_scenarios_async_api_v2_behavioral_assessment_scenarios_async_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BehavioralScenariosRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioJobStatusResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/scenarios/jobs/{job_id}": {
      "get": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Poll the status of an async scenario generation job.",
        "description": "Return the current status of a scenario generation job.\n\nWhen ``status`` is ``completed``, ``result`` contains the full\n``BehavioralScenariosResponse``. When ``status`` is ``failed``,\n``error`` contains a human-readable message.",
        "operationId": "get_scenario_job_status_api_v2_behavioral_assessment_scenarios_jobs__job_id__get",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioJobStatusResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/score": {
      "post": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Score a completed scenario run into dimension summaries.",
        "description": "Score a completed scenario run.\n\nDeterministic scoring is public and is the request default. The optional\nprovider-generated action plan processes questionnaire evidence and is\ntherefore available only to an authenticated, consented account. The\nfrontend can then optionally persist the result via ``POST /profiles``.",
        "operationId": "score_run_api_v2_behavioral_assessment_score_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BehavioralScoreRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dimension scores, reliability markers, and chat context summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralScoreResponse"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/sessions": {
      "post": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Save or update a behavioral assessment session.",
        "operationId": "save_session_api_v2_behavioral_assessment_sessions_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BehavioralSaveSessionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralAssessmentSession"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "List saved behavioral assessment sessions.",
        "operationId": "list_sessions_api_v2_behavioral_assessment_sessions_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralSessionListResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/sessions/{session_id}": {
      "get": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Get a saved behavioral assessment session.",
        "operationId": "get_session_api_v2_behavioral_assessment_sessions__session_id__get",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Session Id"
            }
          },
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralAssessmentSession"
                }
              }
            }
          },
          "404": {
            "description": "Session not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Delete a saved behavioral assessment session.",
        "operationId": "delete_session_api_v2_behavioral_assessment_sessions__session_id__delete",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Session Id"
            }
          },
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Response Delete Session Api V2 Behavioral Assessment Sessions  Session Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/profiles": {
      "post": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Save or update a behavioral profile summary.",
        "operationId": "save_profile_api_v2_behavioral_assessment_profiles_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BehavioralSaveProfileRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BehavioralProfileSummary"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Get the current user's behavioral profile summary.",
        "operationId": "get_profile_api_v2_behavioral_assessment_profiles_get",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/BehavioralProfileSummary"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "title": "Response Get Profile Api V2 Behavioral Assessment Profiles Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Delete the current user's behavioral profile summary.",
        "operationId": "delete_profile_api_v2_behavioral_assessment_profiles_delete",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Response Delete Profile Api V2 Behavioral Assessment Profiles Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/behavioral-assessment/compatibility-dimensions": {
      "get": {
        "tags": [
          "Behavioral Assessment v2"
        ],
        "summary": "Get the research-calibrated compatibility decision rubric.",
        "operationId": "get_research_dimensions_api_v2_behavioral_assessment_compatibility_dimensions_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/BehavioralDimension"
                  },
                  "type": "array",
                  "title": "Response Get Research Dimensions Api V2 Behavioral Assessment Compatibility Dimensions Get"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility/scenarios": {
      "post": {
        "tags": [
          "Compatibility v2"
        ],
        "summary": "Generate Indian-context scenarios for the couple.",
        "operationId": "create_compatibility_scenarios_api_v2_compatibility_scenarios_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompatibilityScenariosRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityScenariosResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility/reports": {
      "post": {
        "tags": [
          "Compatibility v2"
        ],
        "summary": "Generate the authoritative two-person compatibility report (v2).",
        "description": "Returns the versioned compatibility engine truth payload for two full birth inputs. The deterministic engine produces two :class:`KundliTruth` payloads (one per person) and a single :class:`CompatibilityTruth` payload. The interpretation slot is intentionally ``unavailable`` in M004 S01; the LLM narrative layer is a future slice. ``degradation_reasons`` and the ``interpretation_status`` field surface the engine's honest confidence in the computed truth.",
        "operationId": "create_compatibility_report_api_v2_compatibility_reports_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompatibilityReportWithAnswersRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Authoritative compatibility report payload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityReportResponse-Input"
                }
              }
            }
          },
          "422": {
            "description": "Invalid birth input. Either Pydantic validation rejected the request body, or the deterministic engine rejected one of the two birth inputs as malformed. See ErrorResponse.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Deterministic engine dependency unavailable (missing skyfield, missing ephemeris, corrupt ephemeris). See ErrorResponse.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility/artifacts": {
      "post": {
        "tags": [
          "Compatibility v2"
        ],
        "summary": "Persist a generated compatibility reading as a new artifact.",
        "description": "Stores the supplied :class:`CompatibilityReportResponse` through the existing chat-history store. Returns the persisted envelope with a stable ``artifact_id``, the persistence ``created_at`` timestamp, the mirrored interpretation status / degradation reasons / red flags, and a short ``summary`` preview block for thread rendering.",
        "operationId": "save_compatibility_artifact_api_v2_compatibility_artifacts_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompatibilityArtifactSaveRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Artifact persisted. The response carries the typed envelope plus the new ``artifact_id``.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityArtifactResponse-Input"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request body. See :class:`CompatibilityHistoryErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityHistoryErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Persistence backend unavailable. See :class:`CompatibilityHistoryErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityHistoryErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Compatibility v2"
        ],
        "summary": "List the calling user's compatibility history.",
        "description": "Returns the user's persisted compatibility artifacts, newest first, scoped to ``user_id`` and optionally filtered by ``session_id``. The list omits the full report payload; a client opens the full report through a follow-up read by ``artifact_id``.",
        "operationId": "list_compatibility_artifacts_api_v2_compatibility_artifacts_get",
        "parameters": [
          {
            "name": "user_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "description": "Owning user id. Required so the list is scoped.",
              "title": "User Id"
            },
            "description": "Owning user id. Required so the list is scoped."
          },
          {
            "name": "session_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional session id filter. When set, the list is filtered to artifacts bound to that session.",
              "title": "Session Id"
            },
            "description": "Optional session id filter. When set, the list is filtered to artifacts bound to that session."
          }
        ],
        "responses": {
          "200": {
            "description": "List response. The list is user-scoped and may be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityArtifactListResponse-Input"
                }
              }
            }
          },
          "422": {
            "description": "Missing or empty user id. See :class:`CompatibilityHistoryErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityHistoryErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Persistence backend unavailable. See :class:`CompatibilityHistoryErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityHistoryErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility/artifacts/{artifact_id}": {
      "get": {
        "tags": [
          "Compatibility v2"
        ],
        "summary": "Reopen a persisted compatibility reading by id.",
        "description": "Returns the typed envelope for ``artifact_id``, scoped to the calling user. A caller cannot read another user's compatibility history: a request for a non-existent or cross-user ``artifact_id`` returns the same typed 404 envelope so the wire shape does not leak artifact existence across user boundaries. The reopen yields the same ``report`` fields byte-comparable to a freshly generated :class:`CompatibilityReportResponse`.",
        "operationId": "get_compatibility_artifact_api_v2_compatibility_artifacts__artifact_id__get",
        "parameters": [
          {
            "name": "artifact_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artifact Id"
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "description": "Owning user id. Required so the read is scoped.",
              "title": "User Id"
            },
            "description": "Owning user id. Required so the read is scoped."
          }
        ],
        "responses": {
          "200": {
            "description": "Artifact found. The response carries the full envelope with the deterministic report payload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityArtifactResponse-Input"
                }
              }
            }
          },
          "404": {
            "description": "Artifact does not exist for the user. See :class:`CompatibilityHistoryErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityHistoryErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Missing or empty user id. See :class:`CompatibilityHistoryErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityHistoryErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Persistence backend unavailable. See :class:`CompatibilityHistoryErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityHistoryErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility/invites": {
      "post": {
        "tags": [
          "Compatibility v2",
          "compatibility"
        ],
        "summary": "Create Partner Invite",
        "description": "Create a one-time partner invite link.\n\nRequires an authenticated session. The invite is owned by the\nauthenticated user. The partner can open the link without login,\nanswer the same scenarios the owner saw, and submit.\nOne successful submission per token.",
        "operationId": "create_partner_invite_api_v2_compatibility_invites_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerInviteCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteResponse"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteErrorResponse"
                }
              }
            },
            "description": "Unprocessable Content"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteErrorResponse"
                }
              }
            },
            "description": "Service Unavailable"
          }
        }
      },
      "get": {
        "tags": [
          "Compatibility v2",
          "compatibility"
        ],
        "summary": "List Partner Invites",
        "description": "List all invites created by the authenticated user.",
        "operationId": "list_partner_invites_api_v2_compatibility_invites_get",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {},
                  "title": "Response List Partner Invites Api V2 Compatibility Invites Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility/invites/{invite_token}": {
      "get": {
        "tags": [
          "Compatibility v2",
          "compatibility"
        ],
        "summary": "Get Partner Invite",
        "description": "Get an invite by token. No auth required \u2014 partners may not have an account.\n\nMarks the invite as 'opened' on first access.",
        "operationId": "get_partner_invite_api_v2_compatibility_invites__invite_token__get",
        "parameters": [
          {
            "name": "invite_token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Invite Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteResponse"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Compatibility v2",
          "compatibility"
        ],
        "summary": "Delete Partner Invite",
        "description": "Delete an invite created by the authenticated user.",
        "operationId": "delete_partner_invite_api_v2_compatibility_invites__invite_token__delete",
        "parameters": [
          {
            "name": "invite_token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Invite Token"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility/invites/{invite_token}/owner-evidence": {
      "put": {
        "tags": [
          "Compatibility v2",
          "compatibility"
        ],
        "summary": "Update Partner Invite Owner Evidence",
        "description": "Persist owner-side evidence on an existing invite after completion.",
        "operationId": "update_partner_invite_owner_evidence_api_v2_compatibility_invites__invite_token__owner_evidence_put",
        "parameters": [
          {
            "name": "invite_token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Invite Token"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerInviteOwnerEvidenceUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility/invites/{invite_token}/submit": {
      "post": {
        "tags": [
          "Compatibility v2",
          "compatibility"
        ],
        "summary": "Submit Partner Invite Answers",
        "description": "Submit partner answers for an invite. No auth required.\n\nOne successful submission per token. After submission, the\ninvite is marked as 'answered' and cannot be reused.",
        "operationId": "submit_partner_invite_answers_api_v2_compatibility_invites__invite_token__submit_post",
        "parameters": [
          {
            "name": "invite_token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Invite Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerInviteSubmitRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteSubmitResponse"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerInviteErrorResponse"
                }
              }
            },
            "description": "Service Unavailable"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/protocol": {
      "get": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Validation Protocol",
        "operationId": "validation_protocol_api_v2_compatibility_validation_protocol_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Response Validation Protocol Api V2 Compatibility Validation Protocol Get"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/bank": {
      "get": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Validation Bank",
        "operationId": "validation_bank_api_v2_compatibility_validation_bank_get",
        "parameters": [
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Response Validation Bank Api V2 Compatibility Validation Bank Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}": {
      "get": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Get Study",
        "operationId": "get_study_api_v2_compatibility_validation_studies__study_id__get",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudyRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/exports/{dataset}": {
      "get": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Validation Export",
        "operationId": "validation_export_api_v2_compatibility_validation_studies__study_id__exports__dataset__get",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "dataset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Dataset"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Response Validation Export Api V2 Compatibility Validation Studies  Study Id  Exports  Dataset  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies": {
      "post": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Create Study",
        "operationId": "create_study_api_v2_compatibility_validation_studies_post",
        "parameters": [
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StudyCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudyRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/expert-reviews": {
      "post": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Expert Review",
        "operationId": "expert_review_api_v2_compatibility_validation_studies__study_id__expert_reviews_post",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpertReviewSubmission"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/cognitive-interviews": {
      "post": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Cognitive Interview",
        "operationId": "cognitive_interview_api_v2_compatibility_validation_studies__study_id__cognitive_interviews_post",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CognitiveInterviewSubmission"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/pilot-responses": {
      "post": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Pilot Response",
        "operationId": "pilot_response_api_v2_compatibility_validation_studies__study_id__pilot_responses_post",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PilotResponseSubmission"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/dyadic-responses": {
      "post": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Dyadic Response",
        "operationId": "dyadic_response_api_v2_compatibility_validation_studies__study_id__dyadic_responses_post",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DyadicResponseSubmission"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/longitudinal-followups": {
      "post": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Longitudinal Followup",
        "operationId": "longitudinal_followup_api_v2_compatibility_validation_studies__study_id__longitudinal_followups_post",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LongitudinalFollowupSubmission"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/signoffs": {
      "post": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Stage Signoff",
        "operationId": "stage_signoff_api_v2_compatibility_validation_studies__study_id__signoffs_post",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StageSignoffSubmission"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/measurement-models": {
      "post": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Measurement Model",
        "operationId": "measurement_model_api_v2_compatibility_validation_studies__study_id__measurement_models_post",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MeasurementModelSubmission"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/withdrawals": {
      "post": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Withdrawal",
        "operationId": "withdrawal_api_v2_compatibility_validation_studies__study_id__withdrawals_post",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WithdrawalSubmission"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/readiness": {
      "get": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Readiness",
        "operationId": "readiness_api_v2_compatibility_validation_studies__study_id__readiness_get",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadinessReport"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/compatibility-validation/studies/{study_id}/release": {
      "post": {
        "tags": [
          "Compatibility validation research"
        ],
        "summary": "Release",
        "operationId": "release_api_v2_compatibility_validation_studies__study_id__release_post",
        "parameters": [
          {
            "name": "study_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Study Id"
            }
          },
          {
            "name": "signer_token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Signer Token"
            }
          },
          {
            "name": "X-Research-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Research-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventRecord"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/chat/threads": {
      "post": {
        "tags": [
          "Chat threads"
        ],
        "summary": "Create Chat Thread",
        "operationId": "create_chat_thread_api_v2_chat_threads_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatThreadCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatThreadResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Chat threads"
        ],
        "summary": "Get Chat Threads",
        "operationId": "get_chat_threads_api_v2_chat_threads_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 50,
              "minimum": 1,
              "default": 25,
              "title": "Limit"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Cursor"
            }
          },
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatThreadListResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/chat/threads/{thread_id}/messages": {
      "get": {
        "tags": [
          "Chat threads"
        ],
        "summary": "Get Chat Thread Messages",
        "operationId": "get_chat_thread_messages_api_v2_chat_threads__thread_id__messages_get",
        "parameters": [
          {
            "name": "thread_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "title": "Thread Id"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Cursor"
            }
          },
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatThreadMessagesResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/chat/threads/{thread_id}": {
      "patch": {
        "tags": [
          "Chat threads"
        ],
        "summary": "Update Chat Thread",
        "operationId": "update_chat_thread_api_v2_chat_threads__thread_id__patch",
        "parameters": [
          {
            "name": "thread_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "title": "Thread Id"
            }
          },
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatThreadUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatThreadResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Chat threads"
        ],
        "summary": "Delete Chat Thread",
        "operationId": "delete_chat_thread_api_v2_chat_threads__thread_id__delete",
        "parameters": [
          {
            "name": "thread_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "title": "Thread Id"
            }
          },
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/email/check": {
      "post": {
        "tags": [
          "Email Validation"
        ],
        "summary": "Validate email and check for disposable domains",
        "operationId": "check_email_api_v2_email_check_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailCheckRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailCheckResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/kundli/reports": {
      "post": {
        "tags": [
          "Kundli v2"
        ],
        "summary": "Generate the authoritative D1 Kundli report (v2).",
        "description": "Returns the versioned engine truth payload. v2 exposes the full deterministic chart as a typed contract; the engine version in the report metadata identifies the calculation standard and must be used for cache invalidation.",
        "operationId": "create_kundli_report_api_v2_kundli_reports_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KundliBirthInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Authoritative D1 chart payload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KundliReportResponse-Input"
                }
              }
            }
          },
          "422": {
            "description": "Invalid birth input. See ErrorResponse.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Deterministic engine unavailable. See ErrorResponse.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/kundli/report-flow": {
      "post": {
        "tags": [
          "Kundli v2"
        ],
        "summary": "Generate the structured Kundli report flow (v2).",
        "description": "Returns the deterministic chart (passed through verbatim) plus backend-owned trust and disclaimer metadata and an explicit interpretation status. The interpretation layer is best-effort and is gated on the same deterministic engine \u2014 its availability is reported as ``complete`` / ``partial`` / ``unavailable`` so the UI can render a credible report in every state.",
        "operationId": "create_kundli_report_flow_api_v2_kundli_report_flow_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KundliReportFlowRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Structured report flow with chart, trust, disclaimer, and interpretation status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KundliReportFlowResponse-Input"
                }
              }
            }
          },
          "422": {
            "description": "Invalid birth input. See ErrorResponse.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Deterministic engine unavailable. See ErrorResponse.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/modality/numerology": {
      "post": {
        "tags": [
          "Modality"
        ],
        "summary": "Calculate numerology from name and birth date",
        "operationId": "calculate_numerology_api_v2_modality_numerology_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NumerologyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumerologyResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/modality/panchang": {
      "post": {
        "tags": [
          "Modality"
        ],
        "summary": "Calculate Panchang for a given date",
        "operationId": "calculate_panchang_api_v2_modality_panchang_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PanchangRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PanchangResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/modality/muhurat": {
      "post": {
        "tags": [
          "Modality"
        ],
        "summary": "Find auspicious muhurat slots for an activity",
        "operationId": "find_muhurat_api_v2_modality_muhurat_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MuhuratRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MuhuratResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/modality/sade-sati": {
      "post": {
        "tags": [
          "Modality"
        ],
        "summary": "Check Sade Sati status",
        "operationId": "check_sade_sati_api_v2_modality_sade_sati_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SadeSatiRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SadeSatiResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/modality/dosha": {
      "post": {
        "tags": [
          "Modality"
        ],
        "summary": "Check all doshas (Manglik, Kaal Sarp, Pitra)",
        "operationId": "check_doshas_api_v2_modality_dosha_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DoshaRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DoshaResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/modality/varshphal": {
      "post": {
        "tags": [
          "Modality"
        ],
        "summary": "Calculate Varshphal (annual chart) for a target year",
        "operationId": "calculate_varshphal_api_v2_modality_varshphal_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VarshphalRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VarshphalResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/modality/tarot": {
      "post": {
        "tags": [
          "Modality"
        ],
        "summary": "Draw tarot cards with interpretation",
        "operationId": "draw_tarot_api_v2_modality_tarot_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TarotRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TarotResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/modality/rectification/questions": {
      "get": {
        "tags": [
          "Modality"
        ],
        "summary": "Get birth-time rectification questionnaire",
        "operationId": "get_rectification_questions_api_v2_modality_rectification_questions_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Response Get Rectification Questions Api V2 Modality Rectification Questions Get"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/modality/rectification": {
      "post": {
        "tags": [
          "Modality"
        ],
        "summary": "Suggest birth time based on questionnaire answers",
        "operationId": "rectify_birth_time_api_v2_modality_rectification_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RectificationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RectificationResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/modality/horoscope/{rashi}": {
      "get": {
        "tags": [
          "Modality"
        ],
        "summary": "Get horoscope for a rashi (SEO optimized)",
        "operationId": "get_horoscope_api_v2_modality_horoscope__rashi__get",
        "parameters": [
          {
            "name": "rashi",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Rashi"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HoroscopeResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/palmistry/report-flow": {
      "post": {
        "tags": [
          "Palmistry v2"
        ],
        "summary": "Generate the structured Palmistry report flow (v2).",
        "description": "Returns the typed upload assessment plus the structured palm reading report for acceptable inputs, with backend-owned trust and disclaimer metadata. The interpretation layer is best-effort and is reported as ``complete`` / ``partial`` / ``unavailable`` so the UI can render a credible report shell in every state. Weak or rejected uploads return 200 with the ``upload.status`` field set to ``weak`` or ``rejected`` and machine-readable retry guidance.",
        "operationId": "create_palmistry_report_flow_api_v2_palmistry_report_flow_post",
        "parameters": [
          {
            "name": "user_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "User identifier (non-empty).",
              "title": "User Id"
            },
            "description": "User identifier (non-empty)."
          },
          {
            "name": "context",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional context (e.g. user's concerns) forwarded to the vision model.",
              "title": "Context"
            },
            "description": "Optional context (e.g. user's concerns) forwarded to the vision model."
          },
          {
            "name": "preferred_language",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "english",
                "hinglish",
                "hindi"
              ],
              "type": "string",
              "description": "Preferred language for the report interpretation.",
              "default": "english",
              "title": "Preferred Language"
            },
            "description": "Preferred language for the report interpretation."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_create_palmistry_report_flow_api_v2_palmistry_report_flow_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Structured report flow with upload assessment, optional report, trust, disclaimer, and interpretation status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PalmistryReportFlowResponse-Input"
                }
              }
            }
          },
          "422": {
            "description": "Invalid upload. See PalmistryErrorResponse.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PalmistryErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Vision provider rate-limited. See PalmistryErrorResponse.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PalmistryErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Vision provider unavailable. See PalmistryErrorResponse.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PalmistryErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/partner-library/profiles": {
      "post": {
        "tags": [
          "Partner Library v2"
        ],
        "summary": "Save or update a partner profile.",
        "description": "Save or update a partner profile (account-scoped).\n\nWhen ``id`` is omitted a new profile is created. When ``id`` is\npresent the existing profile is updated. The response includes\na ``X-Partner-Duplicate`` header when the save would create a\nduplicate of an existing profile (the save is NOT blocked).",
        "operationId": "save_profile_api_v2_partner_library_profiles_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerProfileSaveRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved profile.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfile"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfileErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfileErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Persistence unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfileErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Partner Library v2"
        ],
        "summary": "List saved partner profiles.",
        "description": "List saved partner profiles for the authenticated user.",
        "operationId": "list_profiles_api_v2_partner_library_profiles_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of profiles.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfileListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfileErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/partner-library/profiles/{profile_id}": {
      "get": {
        "tags": [
          "Partner Library v2"
        ],
        "summary": "Retrieve a saved partner profile.",
        "description": "Retrieve a saved partner profile.",
        "operationId": "get_profile_api_v2_partner_library_profiles__profile_id__get",
        "parameters": [
          {
            "name": "profile_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Profile Id"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved profile.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfile"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfileErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Profile not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfileErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Partner Library v2"
        ],
        "summary": "Delete a saved partner profile.",
        "description": "Delete a saved partner profile.",
        "operationId": "delete_profile_api_v2_partner_library_profiles__profile_id__delete",
        "parameters": [
          {
            "name": "profile_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Profile Id"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "401": {
            "description": "Authentication required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfileErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Profile not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProfileErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/partner-evaluation/synastry": {
      "post": {
        "tags": [
          "Partner Evaluation v2 (research policy)"
        ],
        "summary": "Retired Synastry",
        "operationId": "retired_synastry_api_v2_partner_evaluation_synastry_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SynastryRequest"
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/partner-evaluation/risk-assessment": {
      "post": {
        "tags": [
          "Partner Evaluation v2 (research policy)"
        ],
        "summary": "Retired Risk Assessment",
        "operationId": "retired_risk_assessment_api_v2_partner_evaluation_risk_assessment_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GottmanRiskRequest"
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/partner-evaluation/red-flags": {
      "post": {
        "tags": [
          "Partner Evaluation v2 (research policy)"
        ],
        "summary": "Retired Red Flags",
        "operationId": "retired_red_flags_api_v2_partner_evaluation_red_flags_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RedFlagRequest"
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/partner-evaluation/quality": {
      "post": {
        "tags": [
          "Partner Evaluation v2 (research policy)"
        ],
        "summary": "Retired Quality",
        "operationId": "retired_quality_api_v2_partner_evaluation_quality_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QualityRequest"
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/partner-evaluation/compare": {
      "post": {
        "tags": [
          "Partner Evaluation v2 (research policy)"
        ],
        "summary": "Retired Compare",
        "operationId": "retired_compare_api_v2_partner_evaluation_compare_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerComparisonRequest"
              }
            }
          }
        },
        "responses": {
          "410": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/partner-evaluation/suggest-themes": {
      "post": {
        "tags": [
          "Partner Evaluation v2 (research policy)"
        ],
        "summary": "Research Suggest Themes",
        "description": "Return stage-relevant discussion packs without chart-to-behavior claims.",
        "operationId": "research_suggest_themes_api_v2_partner_evaluation_suggest_themes_post",
        "parameters": [
          {
            "name": "x-session-token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SuggestThemesRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/places/search": {
      "get": {
        "tags": [
          "Places v2"
        ],
        "summary": "Autocomplete a place name and return coordinates + timezone.",
        "description": "Proxies Google Places Autocomplete behind the server. Returns up to 5 typed :class:`PlaceSearchResult` entries; each entry carries the place label, decimal coordinates, an IANA timezone id (when the resolver is available), and the ISO country code. The browser autofill calls this endpoint as the user types.",
        "operationId": "search_places_api_v2_places_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 200,
              "description": "Free-text place name, e.g. ``Lalitpur, UP``. Minimum 3 characters to keep autocomplete useful and avoid burning the per-route rate limit on 1-2 char prefix probes.",
              "title": "Q"
            },
            "description": "Free-text place name, e.g. ``Lalitpur, UP``. Minimum 3 characters to keep autocomplete useful and avoid burning the per-route rate limit on 1-2 char prefix probes."
          }
        ],
        "responses": {
          "200": {
            "description": "Search results (possibly empty).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaceSearchResponse"
                }
              }
            }
          },
          "429": {
            "description": "Per-route rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaceSearchErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Places service is unavailable or misconfigured.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaceSearchErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/readings/artifacts": {
      "post": {
        "tags": [
          "Readings v2"
        ],
        "summary": "Persist a generated Kundli or Palmistry reading as a new artifact.",
        "description": "Stores the supplied :class:`KundliReportFlowResponse` or :class:`PalmistryReportFlowResponse` through the existing chat-history store. The ``kind`` discriminator decides which per-kind payload is expected; the wire shape returns the persisted envelope with a stable ``artifact_id``, the persistence ``created_at`` timestamp, the mirrored interpretation status, and a short summary preview block for thread rendering.",
        "operationId": "save_reading_artifact_api_v2_readings_artifacts_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReadingArtifactSaveRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Artifact persisted. The response carries the typed envelope plus the new ``artifact_id``.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingArtifactResponse-Input"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired, or revoked session. See :class:`ReadingErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request body \u2014 missing kind, kind/payload mismatch, malformed report-flow block, or Pydantic validation rejection. See :class:`ReadingErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Persistence backend unavailable. See :class:`ReadingErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Readings v2"
        ],
        "summary": "List the calling user's reading history.",
        "description": "Returns the user's persisted reading artifacts, newest first, scoped to the calling session's user and optionally filtered by ``session_id`` and/or ``kind``. The list omits the per-kind payload; a client opens the full reading through a follow-up read by ``artifact_id``.",
        "operationId": "list_reading_artifacts_api_v2_readings_artifacts_get",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/ReadingKind"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional kind filter. When set, the list is filtered to artifacts of that kind. When omitted, the list spans every kind the user owns.",
              "title": "Kind"
            },
            "description": "Optional kind filter. When set, the list is filtered to artifacts of that kind. When omitted, the list spans every kind the user owns."
          },
          {
            "name": "session_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional session id filter. When set, the list is filtered to artifacts bound to that session.",
              "title": "Session Id"
            },
            "description": "Optional session id filter. When set, the list is filtered to artifacts bound to that session."
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List response. The list is user-scoped and may be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingArtifactListResponse-Input"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired, or revoked session. See :class:`ReadingErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Persistence backend unavailable. See :class:`ReadingErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/readings/artifacts/{artifact_id}": {
      "get": {
        "tags": [
          "Readings v2"
        ],
        "summary": "Reopen a persisted reading by id.",
        "description": "Returns the typed envelope for ``artifact_id``, scoped to the calling session's user. A caller cannot read another user's reading: a request for a non-existent or cross-user ``artifact_id`` returns the same typed 404 envelope so the wire shape does not leak artifact existence across user boundaries. The reopen yields the same per-kind report-flow fields byte-comparable to a freshly generated report-flow response \u2014 no engine or palmistry service is invoked.",
        "operationId": "get_reading_artifact_api_v2_readings_artifacts__artifact_id__get",
        "parameters": [
          {
            "name": "artifact_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Artifact Id"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Artifact found. The response carries the full envelope with the deterministic per-kind payload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingArtifactResponse-Input"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired, or revoked session. See :class:`ReadingErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Artifact does not exist for the user. See :class:`ReadingErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Persistence backend unavailable. See :class:`ReadingErrorResponse`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadingErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/scenario-builder/generate": {
      "post": {
        "tags": [
          "Scenario Builder v2"
        ],
        "summary": "Generate partner-evaluation questions from a Kundli chart.",
        "description": "Generate partner-evaluation questions from a Kundli chart.\n\nNo auth required for generation \u2014 the user can explore before\nsaving. The response includes a deterministic ``session_id`` that\ncan be used to save and retrieve state later.",
        "operationId": "generate_questions_api_v2_scenario_builder_generate_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScenarioBuilderGenerateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Generated questions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderGenerateResponse-Input"
                }
              }
            }
          },
          "422": {
            "description": "Invalid birth input.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Scenario preparation is temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/scenario-builder/sessions": {
      "post": {
        "tags": [
          "Scenario Builder v2"
        ],
        "summary": "Save or update a scenario builder session.",
        "description": "Save or update a scenario builder session (questions + answers).",
        "operationId": "save_session_api_v2_scenario_builder_sessions_post",
        "parameters": [
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScenarioBuilderSaveRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderSession-Input"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Persistence unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Scenario Builder v2"
        ],
        "summary": "List saved scenario builder sessions.",
        "description": "List saved scenario builder sessions for the authenticated user.",
        "operationId": "list_sessions_api_v2_scenario_builder_sessions_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of sessions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderSessionListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/scenario-builder/sessions/{session_id}": {
      "get": {
        "tags": [
          "Scenario Builder v2"
        ],
        "summary": "Retrieve a saved scenario builder session.",
        "description": "Retrieve a saved scenario builder session.",
        "operationId": "get_session_api_v2_scenario_builder_sessions__session_id__get",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Session Id"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderSession-Input"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Session not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Scenario Builder v2"
        ],
        "summary": "Delete a saved scenario builder session.",
        "description": "Delete a saved scenario builder session.",
        "operationId": "delete_session_api_v2_scenario_builder_sessions__session_id__delete",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Session Id"
            }
          },
          {
            "name": "X-Session-Token",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Session-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "401": {
            "description": "Authentication required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Session not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScenarioBuilderErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AccountProfileResponse": {
        "properties": {
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "display_name": {
            "type": "string",
            "title": "Display Name"
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "email_verified": {
            "type": "boolean",
            "title": "Email Verified",
            "default": false
          },
          "bio": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bio"
          },
          "location": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Location"
          },
          "avatar_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Avatar Url"
          },
          "birth_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Date"
          },
          "birth_time": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Time"
          },
          "birth_place": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Place"
          },
          "birth_latitude": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Latitude"
          },
          "birth_longitude": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Longitude"
          },
          "birth_timezone_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Timezone Id"
          },
          "birth_timezone_offset": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Timezone Offset"
          },
          "consent_version": {
            "type": "string",
            "title": "Consent Version"
          },
          "consent_given": {
            "type": "boolean",
            "title": "Consent Given"
          },
          "consented_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Consented At"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "expires_at": {
            "type": "string",
            "title": "Expires At"
          },
          "access_tier": {
            "type": "string",
            "title": "Access Tier",
            "default": "trial"
          },
          "access_expires_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Expires At"
          },
          "waitlisted": {
            "type": "boolean",
            "title": "Waitlisted",
            "default": false
          },
          "waitlisted_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Waitlisted At"
          },
          "trial_questions_limit": {
            "type": "integer",
            "title": "Trial Questions Limit",
            "default": 3
          },
          "trial_questions_used": {
            "type": "integer",
            "title": "Trial Questions Used",
            "default": 0
          },
          "trial_questions_remaining": {
            "type": "integer",
            "title": "Trial Questions Remaining",
            "default": 3
          },
          "trial_kundli_limit": {
            "type": "integer",
            "title": "Trial Kundli Limit",
            "default": 1
          },
          "trial_kundli_used": {
            "type": "integer",
            "title": "Trial Kundli Used",
            "default": 0
          },
          "trial_kundli_remaining": {
            "type": "integer",
            "title": "Trial Kundli Remaining",
            "default": 1
          },
          "payment_provider": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Provider"
          },
          "payment_customer_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Customer Id"
          },
          "payment_subscription_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Subscription Id"
          },
          "last_payment_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Payment At"
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "display_name",
          "consent_version",
          "consent_given",
          "created_at",
          "expires_at"
        ],
        "title": "AccountProfileResponse"
      },
      "AdminBaselineResponse": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-admin-baseline-1.0.0"
          },
          "generated_at": {
            "type": "string",
            "title": "Generated At",
            "description": "ISO-8601 UTC timestamp at which the backend assembled this baseline. Wall-clock; not part of the byte-comparable contract."
          },
          "overall_status": {
            "$ref": "#/components/schemas/DependencyStatus",
            "description": "Aggregate readiness rolled up from the individual dependency health fields."
          },
          "dependency_health": {
            "$ref": "#/components/schemas/DependencyHealth"
          },
          "golden_quality": {
            "$ref": "#/components/schemas/GoldenFixtureSummary"
          }
        },
        "type": "object",
        "required": [
          "generated_at",
          "overall_status",
          "dependency_health",
          "golden_quality"
        ],
        "title": "AdminBaselineResponse",
        "description": "Read-only professional baseline for the Kundli engine path.\n\nTwo sections:\n\n* ``dependency_health`` \u2014 skyfield availability, ephemeris file\n  presence, and a load-probe result, plus stable engine identity\n  strings. The aggregate ``overall_status`` rolls these up to a\n  single :class:`DependencyStatus`.\n* ``golden_quality`` \u2014 coverage of the two existing golden\n  fixtures, with content-stable identifiers and an explicit list\n  of fields downstream regression tooling must normalize.\n\nThe response is additive: it does not change the user-facing\n:class:`KundliReportResponse` or\n:class:`KundliReportFlowResponse` contracts."
      },
      "AdminBillingAccountResponse": {
        "properties": {
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "display_name": {
            "type": "string",
            "title": "Display Name"
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "payment_provider": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Provider"
          },
          "customer_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Id"
          },
          "subscription_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subscription Id"
          },
          "local_subscription_status": {
            "type": "string",
            "title": "Local Subscription Status"
          },
          "access_tier": {
            "type": "string",
            "title": "Access Tier"
          },
          "access_expires_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Expires At"
          },
          "subscription": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subscription"
          },
          "payments": {
            "items": {
              "type": "object"
            },
            "type": "array",
            "title": "Payments"
          },
          "void_policy": {
            "type": "string",
            "title": "Void Policy"
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "display_name",
          "local_subscription_status",
          "access_tier",
          "void_policy"
        ],
        "title": "AdminBillingAccountResponse"
      },
      "AdminBillingDeliveryStatusResponse": {
        "properties": {
          "welcome_email_configured": {
            "type": "boolean",
            "title": "Welcome Email Configured"
          },
          "posthog_configured": {
            "type": "boolean",
            "title": "Posthog Configured"
          },
          "support_email": {
            "type": "string",
            "title": "Support Email"
          },
          "outbox": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Outbox"
          }
        },
        "type": "object",
        "required": [
          "welcome_email_configured",
          "posthog_configured",
          "support_email",
          "outbox"
        ],
        "title": "AdminBillingDeliveryStatusResponse"
      },
      "AdminBillingOperationResponse": {
        "properties": {
          "operation_id": {
            "type": "string",
            "title": "Operation Id"
          },
          "operation_type": {
            "type": "string",
            "title": "Operation Type"
          },
          "status": {
            "type": "string",
            "title": "Status"
          },
          "provider_operation_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Provider Operation Id"
          },
          "response": {
            "type": "object",
            "title": "Response"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "replayed": {
            "type": "boolean",
            "title": "Replayed",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "operation_id",
          "operation_type",
          "status"
        ],
        "title": "AdminBillingOperationResponse"
      },
      "AdminRefundRequest": {
        "properties": {
          "payment_id": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "title": "Payment Id"
          },
          "amount": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount"
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 5,
            "title": "Reason"
          }
        },
        "type": "object",
        "required": [
          "payment_id",
          "reason"
        ],
        "title": "AdminRefundRequest"
      },
      "AdminRenewalRequest": {
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "period_end",
              "immediate",
              "restore"
            ],
            "title": "Mode"
          },
          "comment": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment"
          }
        },
        "type": "object",
        "required": [
          "mode"
        ],
        "title": "AdminRenewalRequest"
      },
      "AdminUserAccessListResponse": {
        "properties": {
          "users": {
            "items": {
              "$ref": "#/components/schemas/AdminUserAccessResponse"
            },
            "type": "array",
            "title": "Users"
          }
        },
        "type": "object",
        "required": [
          "users"
        ],
        "title": "AdminUserAccessListResponse"
      },
      "AdminUserAccessResponse": {
        "properties": {
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "display_name": {
            "type": "string",
            "title": "Display Name"
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "access_tier": {
            "type": "string",
            "title": "Access Tier"
          },
          "access_expires_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Expires At"
          },
          "payment_provider": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Provider"
          },
          "payment_subscription_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Subscription Id"
          },
          "subscription_status": {
            "type": "string",
            "title": "Subscription Status",
            "default": "inactive"
          },
          "trial_questions_limit": {
            "type": "integer",
            "title": "Trial Questions Limit"
          },
          "trial_questions_used": {
            "type": "integer",
            "title": "Trial Questions Used"
          },
          "trial_questions_remaining": {
            "type": "integer",
            "title": "Trial Questions Remaining"
          },
          "total_tokens_used": {
            "type": "integer",
            "title": "Total Tokens Used"
          },
          "usage_events_count": {
            "type": "integer",
            "title": "Usage Events Count"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "display_name",
          "access_tier",
          "trial_questions_limit",
          "trial_questions_used",
          "trial_questions_remaining",
          "total_tokens_used",
          "usage_events_count",
          "created_at"
        ],
        "title": "AdminUserAccessResponse"
      },
      "AdminWaitlistEntry": {
        "properties": {
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "display_name": {
            "type": "string",
            "title": "Display Name"
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "waitlisted_at": {
            "type": "string",
            "title": "Waitlisted At"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "display_name",
          "waitlisted_at",
          "created_at"
        ],
        "title": "AdminWaitlistEntry"
      },
      "AdminWaitlistResponse": {
        "properties": {
          "entries": {
            "items": {
              "$ref": "#/components/schemas/AdminWaitlistEntry"
            },
            "type": "array",
            "title": "Entries"
          }
        },
        "type": "object",
        "required": [
          "entries"
        ],
        "title": "AdminWaitlistResponse"
      },
      "AnswerSourceSummary": {
        "properties": {
          "partner_answered": {
            "type": "integer",
            "title": "Partner Answered",
            "description": "Answers given by the partner directly.",
            "default": 0
          },
          "owner_observed": {
            "type": "integer",
            "title": "Owner Observed",
            "description": "Answers where the owner observed the behavior.",
            "default": 0
          },
          "owner_guessed": {
            "type": "integer",
            "title": "Owner Guessed",
            "description": "Answers where the owner guessed the partner's behavior.",
            "default": 0
          }
        },
        "type": "object",
        "title": "AnswerSourceSummary",
        "description": "Breakdown of answer provenance for the action plan.\n\nMakes it explicit how many answers came from the partner directly,\nhow many were observed by the owner, and how many were guessed.\nThis prevents the report from treating guesses as verified evidence."
      },
      "AutoRenewRequest": {
        "properties": {
          "enabled": {
            "type": "boolean",
            "title": "Enabled"
          }
        },
        "type": "object",
        "required": [
          "enabled"
        ],
        "title": "AutoRenewRequest"
      },
      "BehavioralActionItem": {
        "properties": {
          "title": {
            "type": "string",
            "title": "Title",
            "description": "Short, plain-language label."
          },
          "why_it_matters": {
            "type": "string",
            "title": "Why It Matters",
            "description": "One sentence on why this matters for relationships.",
            "default": ""
          },
          "suggested_action": {
            "type": "string",
            "title": "Suggested Action",
            "description": "One concrete, practical next action.",
            "default": ""
          },
          "evidence_level": {
            "type": "string",
            "enum": [
              "low",
              "moderate",
              "high"
            ],
            "title": "Evidence Level",
            "description": "How strong the underlying evidence is for this item.",
            "default": "moderate"
          },
          "related_dimensions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Related Dimensions",
            "description": "Dimension keys that informed this item."
          }
        },
        "type": "object",
        "required": [
          "title"
        ],
        "title": "BehavioralActionItem",
        "description": "A single actionable insight derived from the scored profile."
      },
      "BehavioralActionPlan": {
        "properties": {
          "headline": {
            "type": "string",
            "title": "Headline",
            "description": "One plain-language summary of the whole profile.",
            "default": ""
          },
          "decision_takeaway": {
            "type": "string",
            "title": "Decision Takeaway",
            "description": "A specific, non-verdict takeaway naming the next discussion or evidence to explore. It must not tell the user to proceed, marry, separate, or end a relationship.",
            "default": ""
          },
          "top_patterns": {
            "items": {
              "$ref": "#/components/schemas/BehavioralActionItem"
            },
            "type": "array",
            "title": "Top Patterns",
            "description": "2-4 dominant behavioral patterns with evidence strength."
          },
          "strengths_to_use": {
            "items": {
              "$ref": "#/components/schemas/BehavioralActionItem"
            },
            "type": "array",
            "title": "Strengths To Use",
            "description": "Patterns the user can lean on in relationships."
          },
          "friction_risks": {
            "items": {
              "$ref": "#/components/schemas/BehavioralActionItem"
            },
            "type": "array",
            "title": "Friction Risks",
            "description": "Where stress or conflict may show up."
          },
          "next_steps": {
            "items": {
              "$ref": "#/components/schemas/BehavioralActionItem"
            },
            "type": "array",
            "title": "Next Steps",
            "description": "3 practical actions for the near term."
          },
          "partner_conversation_prompts": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Partner Conversation Prompts",
            "description": "3-5 questions to discuss with a partner."
          },
          "partner_prompt_context": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Partner Prompt Context",
            "description": "Parallel list to partner_conversation_prompts. Each entry is a short label explaining what the corresponding prompt tests (e.g. 'Tests family boundary', 'Tests money safety', 'Tests repair style'). Same length as partner_conversation_prompts."
          },
          "chat_starters": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Chat Starters",
            "description": "Suggested opening questions for Sarvajna chat, derived from the action plan so chat is grounded in the user's actual profile instead of generic prompts."
          },
          "when_to_retake": {
            "type": "string",
            "title": "When To Retake",
            "description": "Guidance on when to retake or add more evidence.",
            "default": ""
          },
          "confidence_note": {
            "type": "string",
            "title": "Confidence Note",
            "description": "Short non-diagnostic note on evidence reliability.",
            "default": ""
          },
          "answer_source_summary": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AnswerSourceSummary"
              },
              {
                "type": "null"
              }
            ],
            "description": "Breakdown of answer provenance: how many were answered by the partner, observed by the owner, or guessed."
          },
          "concern_answered": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ConcernAnsweredSummary"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether the user's selected concern was adequately tested by the scenarios."
          },
          "generated_at": {
            "type": "string",
            "title": "Generated At",
            "description": "ISO timestamp of generation.",
            "default": ""
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model",
            "description": "Model identifier used, when LLM-generated."
          },
          "degraded": {
            "type": "boolean",
            "title": "Degraded",
            "description": "True when the LLM failed and a deterministic fallback was used instead.",
            "default": false
          },
          "degradation_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Degradation Reason",
            "description": "Why the fallback was used, when degraded."
          }
        },
        "type": "object",
        "title": "BehavioralActionPlan",
        "description": "Bounded, LLM-generated action plan from the scored behavioral profile.\n\nThe plan is the primary user-facing output of the behavior check\n(evalution.md). It is generated from dimension summaries, bands,\nconfidence, reliability markers, concern tags, and a bounded excerpt of\nscenario answers used only as supporting evidence. When the LLM fails, a\ndeterministic fallback plan is built\nfrom the dimension summaries and ``degraded`` is set to ``True``."
      },
      "BehavioralAssessmentSession": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-behavioral-1.0.0"
          },
          "session_id": {
            "type": "string",
            "title": "Session Id",
            "description": "Stable session id."
          },
          "user_id": {
            "type": "string",
            "title": "User Id",
            "description": "Owning user id."
          },
          "mode": {
            "type": "string",
            "enum": [
              "self",
              "partner_observation",
              "couple",
              "custom_concern",
              "standalone"
            ],
            "title": "Mode",
            "description": "Assessment mode for this session.",
            "default": "self"
          },
          "created_at": {
            "type": "string",
            "title": "Created At",
            "description": "ISO timestamp.",
            "default": ""
          },
          "updated_at": {
            "type": "string",
            "title": "Updated At",
            "description": "ISO timestamp.",
            "default": ""
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/BehavioralScenarioQuestion"
            },
            "type": "array",
            "title": "Questions",
            "description": "Generated scenario questions."
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/BehavioralScenarioAnswer"
            },
            "type": "array",
            "title": "Answers",
            "description": "Recorded answers."
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern",
            "description": "Free-text concern the session addressed."
          },
          "concern_tags": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Concern Tags",
            "description": "Concern tags the session addressed."
          },
          "relationship_stage": {
            "type": "string",
            "enum": [
              "arranged",
              "dating",
              "considering",
              "engaged",
              "married",
              "reconnecting",
              "unsure",
              "prospective"
            ],
            "title": "Relationship Stage",
            "description": "Relationship stage at generation time.",
            "default": "considering"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "description": "Scenario language.",
            "default": "english"
          },
          "profile_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Profile Id",
            "description": "Profile summary id derived from this session, when one was saved."
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "Short preview text for list rendering.",
            "default": ""
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "user_id"
        ],
        "title": "BehavioralAssessmentSession",
        "description": "A persisted behavioral assessment session.\n\nMirrors the scenario_builder session shape: questions + answers +\nrun-defining inputs, persisted as a messages row with role\n``behavioral_assessment_session`` and the session id as the\nmessage ``session_id``."
      },
      "BehavioralDimension": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "Stable dimension key, e.g. 'conflict_repair'."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Human-readable label for reports."
          },
          "construct_family": {
            "type": "string",
            "enum": [
              "attachment",
              "conflict",
              "big_five_proxy",
              "values",
              "culture",
              "lifestyle",
              "gottman",
              "prqc"
            ],
            "title": "Construct Family",
            "description": "Research background construct family."
          },
          "allowed_traits": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Allowed Traits",
            "description": "Closed list of valid option_trait values for this dimension."
          },
          "research_basis": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Research Basis",
            "description": "Source ids and short rationale grounding the dimension in the research basis (R1-R3)."
          },
          "legacy_measurement_target": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Legacy Measurement Target",
            "description": "Legacy scenario_builder measurement_target this dimension maps from, if any. Used for migration parity."
          }
        },
        "type": "object",
        "required": [
          "key",
          "label",
          "construct_family"
        ],
        "title": "BehavioralDimension",
        "description": "One entry in the backend-owned dimension registry.\n\nThe registry is the closed rubric the scenario generator and the\nscoring model share. Generated questions MUST use a\n``dimension_key`` from this registry; option traits MUST be one of\nthe dimension's allowed traits. This keeps the trait vocabulary\nbackend-owned and stable across regenerations."
      },
      "BehavioralErrorResponse": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          }
        },
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "title": "BehavioralErrorResponse",
        "description": "Typed error envelope for the behavioral assessment surface."
      },
      "BehavioralEvidenceBlock": {
        "properties": {
          "behavioral_fit_note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Behavioral Fit Note",
            "description": "Short narrative comparing the user's behavioral tendencies and any observed partner behavior with the astrological compatibility result. Derived from the ``behavioral_chat_context`` supplied by the caller or from scenario answers when no saved profile was provided."
          },
          "relationship_impact": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Relationship Impact",
            "description": "One-paragraph explanation of how the behavioral profile affects this specific match, grounded in the chart result and the action plan. None when no behavioral evidence was supplied."
          },
          "watchouts": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Watchouts",
            "description": "Friction patterns to watch in this match, derived from the action plan's friction_risks and the chart's growth areas. Empty when no behavioral evidence was supplied."
          },
          "joint_practices": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Joint Practices",
            "description": "Practical exercises or habits the couple can try together, derived from the action plan's next_steps and the chart's guidance. Empty when no behavioral evidence was supplied."
          },
          "accuracy_confidence": {
            "type": "string",
            "title": "Accuracy Confidence",
            "description": "Machine-readable confidence label for what evidence the report used. One of: 'charts_only', 'charts_plus_declared', 'charts_plus_behavior', 'charts_plus_behavior_and_scenarios'. The deprecated 'charts_plus_auto_partner_eval' value is accepted only when reading historical saved reports."
          },
          "accuracy_confidence_note": {
            "type": "string",
            "title": "Accuracy Confidence Note",
            "description": "Human-readable note explaining the accuracy confidence. Render verbatim."
          },
          "questions_to_ask_partner": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Questions To Ask Partner",
            "description": "Practical questions the user can ask the partner, informed by scenario results, concern tags, and the behavioral profile. Empty when no evidence was available."
          },
          "evidence_used": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Evidence Used",
            "description": "Short list of the evidence sources that fed this block (e.g. 'saved behavior profile', 'scenario answers', 'declared cultural context'). Helps the user understand what grounded the guidance. Empty when no evidence was supplied."
          },
          "person1_dimension_scores": {
            "anyOf": [
              {
                "items": {
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Person1 Dimension Scores",
            "description": "Deprecated historical chart-simulated scores for person 1. New reports always return None; these values are not validated behavioral evidence."
          },
          "person2_dimension_scores": {
            "anyOf": [
              {
                "items": {
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Person2 Dimension Scores",
            "description": "Deprecated historical chart-simulated scores for person 2. New reports always return None; these values are not validated behavioral evidence."
          },
          "strengths": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Strengths",
            "description": "Behavioral alignment strengths derived from supplied human evidence. Historical chart-simulated entries are deprecated."
          }
        },
        "type": "object",
        "required": [
          "accuracy_confidence",
          "accuracy_confidence_note"
        ],
        "title": "BehavioralEvidenceBlock",
        "description": "Behavioral evidence surfaced alongside a compatibility report.\n\nV2-S08 adds three first-class sections so a renderer can show\nhow self-reported behavior and observed partner behavior relate\nto the chart result, how confident the analysis is, and what\npractical questions the user can ask the partner.\n\nevalution.md Phase 3 extends the block into an actionable\nrelationship-guidance panel. The new fields\n(``relationship_impact``, ``watchouts``, ``joint_practices``,\n``evidence_used``) are populated from the action plan when a\nsaved behavioral profile is supplied, and fall back to\ndeterministic rule-built text otherwise. The block answers\n\"What should we discuss before deciding?\" rather than only\n\"Was behavior included?\".\n\nAll text is modest, non-clinical, and grounded in the evidence\nsupplied by the caller. The backend never fabricates behavioral\nclaims when no evidence was provided."
      },
      "BehavioralPreviewRequest": {
        "properties": {
          "person1": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Person1",
            "description": "Owner birth input or saved profile."
          },
          "person2": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Person2",
            "description": "Optional partner birth input. When present, the preview is grounded in the compatibility matrix."
          },
          "person1_culture": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Person1 Culture"
          },
          "person2_culture": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Person2 Culture"
          },
          "mode": {
            "type": "string",
            "enum": [
              "self",
              "partner_observation",
              "couple",
              "custom_concern",
              "standalone"
            ],
            "title": "Mode",
            "description": "Assessment mode the preview precedes.",
            "default": "custom_concern"
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern",
            "description": "Free-text concern."
          },
          "suggestion_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Suggestion Ids",
            "description": "Selected concern ids from the taxonomy."
          },
          "dimensions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Dimensions",
            "description": "Explicit dimensions selected by the user."
          },
          "relationship_stage": {
            "type": "string",
            "enum": [
              "arranged",
              "dating",
              "considering",
              "engaged",
              "married",
              "reconnecting",
              "unsure",
              "prospective"
            ],
            "title": "Relationship Stage",
            "default": "considering"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "default": "english"
          }
        },
        "type": "object",
        "title": "BehavioralPreviewRequest",
        "description": "Request body to generate a pre-scenario custom analysis.\n\nThe analysis is grounded in the selected concern(s) and the available\nchart/compatibility signals. It is returned before the scenarios are\ngenerated so the user can see why these scenarios matter for them."
      },
      "BehavioralPreviewResponse": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-behavioral-1.0.0"
          },
          "session_id": {
            "type": "string",
            "title": "Session Id",
            "description": "Stable preview session id."
          },
          "analysis": {
            "type": "string",
            "title": "Analysis",
            "description": "Plain-language analysis of why the selected concerns matter given the chart/compatibility signals."
          },
          "signals": {
            "items": {
              "$ref": "#/components/schemas/BehavioralPreviewSignal"
            },
            "type": "array",
            "title": "Signals",
            "description": "Signals that grounded the analysis."
          },
          "degraded": {
            "type": "boolean",
            "title": "Degraded",
            "default": false
          },
          "degradation_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Degradation Reason"
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "analysis"
        ],
        "title": "BehavioralPreviewResponse",
        "description": "Response with a pre-scenario custom analysis."
      },
      "BehavioralPreviewSignal": {
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "chart",
              "compatibility"
            ],
            "title": "Type",
            "description": "Whether this signal comes from a single chart or from the compatibility matrix."
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "Human-readable signal description."
          },
          "source": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Optional source id, e.g. 'moon_sign', 'graha_maitri'."
          }
        },
        "type": "object",
        "required": [
          "type",
          "text"
        ],
        "title": "BehavioralPreviewSignal",
        "description": "One chart or compatibility signal referenced in the preview."
      },
      "BehavioralProfileSummary": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-behavioral-1.0.0"
          },
          "profile_id": {
            "type": "string",
            "title": "Profile Id",
            "description": "Stable profile id (UUID)."
          },
          "user_id": {
            "type": "string",
            "title": "User Id",
            "description": "Owning user id."
          },
          "profile_version": {
            "type": "string",
            "title": "Profile Version",
            "description": "Versioned summary contract.",
            "default": "1.0.0"
          },
          "mode": {
            "type": "string",
            "enum": [
              "self",
              "partner_observation",
              "couple",
              "custom_concern",
              "standalone"
            ],
            "title": "Mode",
            "description": "Assessment mode the profile summarizes.",
            "default": "self"
          },
          "dimension_scores": {
            "items": {
              "$ref": "#/components/schemas/DimensionScore"
            },
            "type": "array",
            "title": "Dimension Scores",
            "description": "Per-dimension score with confidence, sample_count, recency, and contradiction markers."
          },
          "declared_vs_observed": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DeclaredVsObserved"
              },
              {
                "type": "null"
              }
            ],
            "description": "Difference between stated intake fields and SJT behavior."
          },
          "reliability_markers": {
            "$ref": "#/components/schemas/ReliabilityMarkers",
            "description": "Reliability markers (straight-lining, too-fast, socially desirable, low sample)."
          },
          "chat_context_summary": {
            "type": "string",
            "title": "Chat Context Summary",
            "description": "Compact safe text for LLM prompt injection. Contains only summaries, confidence, and recent concern tags \u2014 never raw answers.",
            "default": ""
          },
          "concern_tags": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Concern Tags",
            "description": "Recent concern tags the profile addressed."
          },
          "consent_saved": {
            "type": "boolean",
            "title": "Consent Saved",
            "description": "True when the user consented to save behavioral insights to account memory (P1).",
            "default": false
          },
          "updated_at": {
            "type": "string",
            "title": "Updated At",
            "description": "ISO timestamp of the last update.",
            "default": ""
          },
          "action_plan": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralActionPlan"
              },
              {
                "type": "null"
              }
            ],
            "description": "LLM-generated bounded action plan derived from the scored dimensions. Present when generation succeeded; absent when the LLM was unavailable and the deterministic fallback was intentionally skipped (e.g. empty dimension set)."
          }
        },
        "type": "object",
        "required": [
          "profile_id",
          "user_id"
        ],
        "title": "BehavioralProfileSummary",
        "description": "A compact, consent-aware behavioral profile summary.\n\nThis is the durable contract saved to account memory and injected\ninto compatibility reports and chat context. Raw answer history\nstays in the typed session metadata; only compact summaries reach\nchat (G5, P1)."
      },
      "BehavioralSavePreviewRequest": {
        "properties": {
          "session_id": {
            "type": "string",
            "minLength": 1,
            "title": "Session Id"
          },
          "analysis": {
            "type": "string",
            "maxLength": 8000,
            "title": "Analysis"
          },
          "signals": {
            "items": {
              "$ref": "#/components/schemas/BehavioralPreviewSignal"
            },
            "type": "array",
            "title": "Signals"
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern"
          },
          "concern_tags": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Concern Tags"
          },
          "relationship_stage": {
            "type": "string",
            "enum": [
              "arranged",
              "dating",
              "considering",
              "engaged",
              "married",
              "reconnecting",
              "unsure",
              "prospective"
            ],
            "title": "Relationship Stage",
            "default": "considering"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "default": "english"
          },
          "consent_saved": {
            "type": "boolean",
            "title": "Consent Saved",
            "description": "Server-confirmed account consent for saving this preview. The authenticated route sets this value; clients cannot grant consent.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "analysis"
        ],
        "title": "BehavioralSavePreviewRequest",
        "description": "Request to persist a preview so it can be reused in chat."
      },
      "BehavioralSaveProfileRequest": {
        "properties": {
          "profile_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Profile Id",
            "description": "Profile id. Omit to create a new profile; present to update."
          },
          "mode": {
            "type": "string",
            "enum": [
              "self",
              "partner_observation",
              "couple",
              "custom_concern",
              "standalone"
            ],
            "title": "Mode",
            "default": "self"
          },
          "dimension_scores": {
            "items": {
              "$ref": "#/components/schemas/DimensionScore"
            },
            "type": "array",
            "title": "Dimension Scores"
          },
          "declared_vs_observed": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DeclaredVsObserved"
              },
              {
                "type": "null"
              }
            ]
          },
          "reliability_markers": {
            "$ref": "#/components/schemas/ReliabilityMarkers"
          },
          "chat_context_summary": {
            "type": "string",
            "title": "Chat Context Summary",
            "default": ""
          },
          "concern_tags": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Concern Tags"
          },
          "consent_saved": {
            "type": "boolean",
            "title": "Consent Saved",
            "default": false
          },
          "action_plan": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralActionPlan"
              },
              {
                "type": "null"
              }
            ],
            "description": "Action plan generated at score time to persist with the profile so Account and downstream features can reuse it."
          }
        },
        "type": "object",
        "title": "BehavioralSaveProfileRequest",
        "description": "Request to save or update a behavioral profile summary.\n\nThe profile is derived from one or more sessions by the scoring\nmodel. The route accepts the derived summary so the frontend can\npersist the result of an onboarding or compatibility flow."
      },
      "BehavioralSaveSessionRequest": {
        "properties": {
          "session_id": {
            "type": "string",
            "minLength": 1,
            "title": "Session Id"
          },
          "mode": {
            "type": "string",
            "enum": [
              "self",
              "partner_observation",
              "couple",
              "custom_concern",
              "standalone"
            ],
            "title": "Mode",
            "default": "self"
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/BehavioralScenarioQuestion"
            },
            "type": "array",
            "title": "Questions"
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/BehavioralScenarioAnswer"
            },
            "type": "array",
            "title": "Answers"
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern"
          },
          "concern_tags": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Concern Tags"
          },
          "relationship_stage": {
            "type": "string",
            "enum": [
              "arranged",
              "dating",
              "considering",
              "engaged",
              "married",
              "reconnecting",
              "unsure",
              "prospective"
            ],
            "title": "Relationship Stage",
            "default": "considering"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "default": "english"
          },
          "consent_saved": {
            "type": "boolean",
            "title": "Consent Saved",
            "description": "Whether the user consented to save behavioral insights to account memory (P1).",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "session_id"
        ],
        "title": "BehavioralSaveSessionRequest",
        "description": "Request to save or update a behavioral assessment session."
      },
      "BehavioralScenarioAnswer": {
        "properties": {
          "question_id": {
            "type": "string",
            "title": "Question Id",
            "description": "Scenario id this answer refers to."
          },
          "selected_option": {
            "type": "string",
            "title": "Selected Option",
            "description": "Selected option label (A, B, C, D)."
          },
          "selected_option_text": {
            "type": "string",
            "title": "Selected Option Text",
            "description": "Client snapshot of the selected option for durable reopen. The scoring endpoint replaces it with the registered scenario's canonical option text before use."
          },
          "least_likely_option": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Least Likely Option",
            "description": "Optional second signal; useful for forced-choice scoring."
          },
          "confidence": {
            "type": "integer",
            "maximum": 5.0,
            "minimum": 1.0,
            "title": "Confidence",
            "description": "How sure the user is about this answer, 1-5.",
            "default": 3
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Optional user notes."
          },
          "phase": {
            "type": "string",
            "enum": [
              "self",
              "partner",
              "couple",
              "standalone"
            ],
            "title": "Phase",
            "description": "Assessment phase this answer belongs to.",
            "default": "self"
          },
          "response_source": {
            "type": "string",
            "enum": [
              "human",
              "astro_hypothesis"
            ],
            "title": "Response Source",
            "description": "Who supplied the response. 'human' means a person selected it; 'astro_hypothesis' means software estimated a possible answer from chart signals and it must never be described as reported behavior.",
            "default": "human"
          },
          "observed_or_guessed": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "observed",
                  "guessed",
                  "not_enough_info"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Observed Or Guessed",
            "description": "For partner-observation answers (fixpartner.md \u00a72.3): whether the user has directly seen this behavior ('observed'), is inferring ('guessed'), or does not have enough information ('not_enough_info'). Partner-observation answers must never be treated as verified partner truth."
          },
          "observation_frequency": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "rarely",
                  "sometimes",
                  "often",
                  "always"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Observation Frequency",
            "description": "For partner-observation answers (fixpartner.md \u00a72.3): how often the user has seen this behavior. Used to downweight answers marked 'rarely' or 'guessed'."
          },
          "answered_at": {
            "type": "string",
            "title": "Answered At",
            "description": "ISO timestamp the answer was recorded.",
            "default": ""
          },
          "question_title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Question Title",
            "description": "Optional title of the scenario the answer belongs to. Included when the answer is reused as context for follow-up generation."
          },
          "question_text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Question Text",
            "description": "Optional question text the answer was responding to. Included when the answer is reused as context for follow-up generation."
          }
        },
        "type": "object",
        "required": [
          "question_id",
          "selected_option",
          "selected_option_text"
        ],
        "title": "BehavioralScenarioAnswer",
        "description": "A user's answer to a behavioral scenario question.\n\nThe ``selected_option`` is the label (A/B/C/D).\n``selected_option_text`` is a text snapshot for durable reopen.\n``least_likely_option`` is an optional second signal useful for\nforced-choice scoring. ``confidence`` is the user's self-reported\ncertainty (1-5). ``phase`` mirrors the existing compatibility\nanswer phase so the two flows stay interoperable.\n\n``observed_or_guessed`` and ``observation_frequency`` (fixpartner.md\n\u00a72.3) apply to partner-observation answers so the user can say\nwhether they have actually seen a behavior or are guessing, and\nhow often. Partner-observation answers must never be treated as\nverified partner truth."
      },
      "BehavioralScenarioEvidence": {
        "properties": {
          "chart_signals": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Chart Signals",
            "description": "Chart-signal references associated with the scenario (e.g. 'Mars in 7th house'). They are verified grounding only when the grounding_state says so; on model-authored scenarios they are allow-listed topic-selection receipts."
          },
          "compatibility_matrix_refs": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Compatibility Matrix Refs",
            "description": "Compatibility-matrix references associated with the scenario (e.g. 'layer:temper_and_impulse'). They are verified grounding only when the grounding_state says so; on model-authored scenarios they are allow-listed topic-selection receipts."
          },
          "concern_tags": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Concern Tags",
            "description": "Concern tags the scenario addresses (e.g. 'family_pressure'). Empty when the scenario is not concern-driven."
          },
          "grounding_state": {
            "type": "string",
            "enum": [
              "grounded",
              "partial",
              "absent",
              "narrative_derived"
            ],
            "title": "Grounding State",
            "description": "Closed-literal grounding state. 'narrative_derived' means the references selected topics for model prose and do not verify a chart-derived claim.",
            "default": "absent"
          },
          "grounding_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Grounding Reason",
            "description": "Short machine-readable reason when grounding is partial, absent, or narrative_derived."
          }
        },
        "type": "object",
        "title": "BehavioralScenarioEvidence",
        "description": "Backend-owned provenance block for a single scenario.\n\nDeterministically built scenarios may contain verified chart or matrix\nevidence. For model-authored scenarios, allow-listed ``evidence_refs`` are\ntopic-selection receipts only: they explain which supplied topics shaped\nthe narrative, but never establish chart grounding. Such evidence is\nexplicitly marked ``narrative_derived`` so renderers keep the distinction."
      },
      "BehavioralScenarioOption": {
        "properties": {
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Short label, e.g. 'A', 'B', 'C', 'D'."
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "The option text the user reads."
          },
          "option_trait": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Option Trait",
            "description": "Backend-owned trait this option represents (e.g. 'harmony_deference'). Hidden from the UI; used by the scoring model to interpret the answer."
          },
          "score_vector": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "number"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Score Vector",
            "description": "Backend-owned per-dimension score contribution of this option. Hidden from the UI; used by the scoring model. Keys are dimension keys, values are signed floats."
          },
          "tradeoff": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tradeoff",
            "description": "Short honest cost of this option so no option is an obvious good/bad trap. May be shown to the user."
          }
        },
        "type": "object",
        "required": [
          "label",
          "text"
        ],
        "title": "BehavioralScenarioOption",
        "description": "A single multiple-choice option for a behavioral scenario.\n\n``option_trait`` and ``score_vector`` are backend-owned and hidden\nfrom the UI; they let the scoring model interpret the answer\nwithout relying only on prose. ``tradeoff`` is the honest cost of\nthis option so no option is an obvious good/bad trap (R1)."
      },
      "BehavioralScenarioQuestion": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable deterministic id."
          },
          "logical_question_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Logical Question Id",
            "description": "Stable logical id shared by the owner's scenario and the clean recipient-owned copy used for pairwise compatibility scoring."
          },
          "recipient_source_question_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Recipient Source Question Id",
            "description": "Owner question id mirrored by an invite recipient's copy. Preserved by validation so paired answers can be reconciled."
          },
          "recipient_question_version": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Recipient Question Version",
            "description": "Version of the recipient-owned question-copy contract."
          },
          "mode": {
            "type": "string",
            "enum": [
              "self",
              "partner_observation",
              "couple",
              "custom_concern",
              "standalone"
            ],
            "title": "Mode",
            "description": "Assessment mode this question belongs to."
          },
          "source": {
            "type": "string",
            "enum": [
              "kundli_user",
              "kundli_partner",
              "compatibility_truth",
              "user_concern",
              "onboarding_bank",
              "hybrid"
            ],
            "title": "Source",
            "description": "How the scenario was authored or selected. This provenance label does not by itself establish behavioral or chart grounding.",
            "default": "hybrid"
          },
          "dimension_key": {
            "type": "string",
            "title": "Dimension Key",
            "description": "One BehavioralDimension key from the registry."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "Short scenario title."
          },
          "story": {
            "type": "string",
            "title": "Story",
            "description": "Concrete relationship situation."
          },
          "question": {
            "type": "string",
            "title": "Question",
            "description": "What the user is choosing."
          },
          "options": {
            "items": {
              "$ref": "#/components/schemas/BehavioralScenarioOption"
            },
            "type": "array",
            "maxItems": 4,
            "minItems": 4,
            "title": "Options",
            "description": "Exactly four plausible options, each with a tradeoff. No obvious good/bad trap."
          },
          "evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralScenarioEvidence"
              },
              {
                "type": "null"
              }
            ],
            "description": "Backend-owned provenance block. It may describe verified deterministic grounding, absent grounding, or allow-listed model topic-selection receipts marked narrative_derived."
          },
          "difficulty": {
            "type": "string",
            "enum": [
              "light",
              "medium",
              "sensitive"
            ],
            "title": "Difficulty",
            "description": "Difficulty band. 'sensitive' scenarios touch intimacy, finances, or family pressure.",
            "default": "medium"
          },
          "language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Language",
            "description": "Scenario language.",
            "default": "english"
          },
          "perspective": {
            "type": "string",
            "enum": [
              "self",
              "partner",
              "couple"
            ],
            "title": "Perspective",
            "description": "Which perspective this scenario asks the user to answer from. 'self' = what would YOU do; 'partner' = what do you think YOUR PARTNER would do; 'couple' = how would the TWO OF YOU handle this. In 'couple' mode the LLM is instructed to generate a mix of perspectives \u2014 this field lets the frontend tag each answer with the correct phase and show perspective-aware UI (e.g. 'guessing' controls for partner-perspective questions).",
            "default": "self"
          }
        },
        "type": "object",
        "required": [
          "id",
          "mode",
          "dimension_key",
          "title",
          "story",
          "question",
          "options"
        ],
        "title": "BehavioralScenarioQuestion",
        "description": "A single SJT-style behavioral scenario question.\n\nThe ``id`` is a stable deterministic handle. The ``mode`` declares\nwhether the question collects self behavior, partner observation,\ncouple behavior, or a custom-concern response. The\n``dimension_key`` MUST be one of the registry keys. Options are\nfour plausible choices with tradeoffs (R1) \u2014 no obvious good/bad\ntrap."
      },
      "BehavioralScenariosRequest": {
        "properties": {
          "person1": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Person1",
            "description": "CompatibilityBirthInput; optional when using saved user birth profile."
          },
          "person2": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Person2",
            "description": "CompatibilityBirthInput; optional for self-only onboarding."
          },
          "person1_culture": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Person1 Culture",
            "description": "Optional CulturalContext for person 1."
          },
          "person2_culture": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Person2 Culture",
            "description": "Optional CulturalContext for person 2."
          },
          "current_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Date",
            "description": "Client-side current date (YYYY-MM-DD) used to ground time-sensitive scenario wording."
          },
          "mode": {
            "type": "string",
            "enum": [
              "self",
              "partner_observation",
              "couple",
              "custom_concern",
              "standalone"
            ],
            "title": "Mode",
            "description": "Assessment mode.",
            "default": "self"
          },
          "scenario_count": {
            "type": "integer",
            "maximum": 20.0,
            "minimum": 3.0,
            "title": "Scenario Count",
            "description": "Integer 3-20. Default 6. Enforced server-side with cost caps.",
            "default": 6
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern",
            "description": "Free text concern."
          },
          "suggestion_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Suggestion Ids",
            "description": "Optional chosen suggested concern ids."
          },
          "dimensions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 12,
            "title": "Dimensions",
            "description": "Optional explicit dimension filters. Extra dimensions are deduplicated and capped at 12 during validation."
          },
          "relationship_stage": {
            "type": "string",
            "enum": [
              "arranged",
              "dating",
              "considering",
              "engaged",
              "married",
              "reconnecting",
              "unsure",
              "prospective"
            ],
            "title": "Relationship Stage",
            "description": "Relationship stage.",
            "default": "considering"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "description": "Scenario language.",
            "default": "english"
          },
          "include_existing_profile": {
            "type": "boolean",
            "title": "Include Existing Profile",
            "description": "Use saved BehavioralProfileSummary to avoid repeating dimensions.",
            "default": false
          },
          "exclude_question_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 100,
            "title": "Exclude Question Ids",
            "description": "Question ids from earlier runs that must not be generated again."
          },
          "exclude_question_texts": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 100,
            "title": "Exclude Question Texts",
            "description": "Question/story text from earlier runs that must not be repeated."
          },
          "fallback_first": {
            "type": "boolean",
            "title": "Fallback First",
            "description": "Deprecated compatibility flag. Scenario generation now always waits for MiniMax so generic bank questions are never used.",
            "default": false
          },
          "require_model_authored": {
            "type": "boolean",
            "title": "Require Model Authored",
            "description": "Compatibility field; all returned scenarios are now freshly MiniMax-authored regardless of this value.",
            "default": true
          },
          "previous_answers": {
            "items": {
              "$ref": "#/components/schemas/BehavioralScenarioAnswer"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Previous Answers",
            "description": "Prior SJT answers from an earlier run. The generator should avoid repeating these scenes and build follow-up scenarios that explore the required dimensions from new angles, taking the previous responses into account."
          }
        },
        "type": "object",
        "title": "BehavioralScenariosRequest",
        "description": "Request body to generate behavioral scenarios.\n\n``person1`` / ``person2`` are optional so the endpoint can serve\nself-only onboarding (no partner) as well as couple assessment.\n``scenario_count`` is enforced 3-20 server-side with cost caps. Explicit\ndimensions are normalized to at most ``MAX_SCENARIO_DIMENSIONS`` so a\nstale client cannot turn a valid scenario request into a 422 response."
      },
      "BehavioralScenariosResponse": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-behavioral-1.0.0"
          },
          "session_id": {
            "type": "string",
            "title": "Session Id",
            "description": "Stable session id."
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/BehavioralScenarioQuestion"
            },
            "type": "array",
            "title": "Questions",
            "description": "Generated scenario questions."
          },
          "coverage": {
            "items": {
              "$ref": "#/components/schemas/CoverageMapEntry"
            },
            "type": "array",
            "title": "Coverage",
            "description": "Dimensions covered and why."
          },
          "suggestions": {
            "items": {
              "$ref": "#/components/schemas/SuggestedConcern"
            },
            "type": "array",
            "title": "Suggestions",
            "description": "Follow-up concern chips."
          },
          "degraded": {
            "type": "boolean",
            "title": "Degraded",
            "default": false
          },
          "degradation_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Degradation Reason"
          }
        },
        "type": "object",
        "required": [
          "session_id"
        ],
        "title": "BehavioralScenariosResponse",
        "description": "Response with generated behavioral scenarios.\n\nSuccessful responses are complete MiniMax-authored sets. ``degraded`` and\n``degradation_reason`` remain for backwards-compatible deserialization of\npreviously persisted sessions."
      },
      "BehavioralScoreRequest": {
        "properties": {
          "questions": {
            "items": {
              "$ref": "#/components/schemas/BehavioralScenarioQuestion"
            },
            "type": "array",
            "maxItems": 512,
            "title": "Questions",
            "description": "Previously generated scenario questions for the run being scored. Every non-empty question is verified against the server registry, and question ids must be unique within the request."
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/BehavioralScenarioAnswer"
            },
            "type": "array",
            "maxItems": 1024,
            "title": "Answers",
            "description": "Recorded answers across the assessment rounds being scored. Each question id may appear once per respondent and selected labels must belong to the verified scenario."
          },
          "declared": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object",
                "maxProperties": 32
              },
              {
                "type": "null"
              }
            ],
            "title": "Declared",
            "description": "Optional declared intake fields (e.g. decision_style, family_orientation) for declared-vs-observed comparison (R2)."
          },
          "concern_tags": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Concern Tags",
            "description": "Concern tags the run addressed, folded into the chat context summary."
          },
          "skip_action_plan": {
            "type": "boolean",
            "title": "Skip Action Plan",
            "description": "When true (the safe public default), use deterministic scoring and guidance. Setting false requests an AI-generated action plan and requires an authenticated, consented session.",
            "default": true
          }
        },
        "type": "object",
        "title": "BehavioralScoreRequest",
        "description": "Request body for the scoring endpoint.\n\nThe frontend sends the questions + answers from a completed\nscenario run (and optionally the declared intake fields) so the\nbackend can compute the dimension scores, reliability markers,\ndeclared-vs-observed gaps, and the compact chat context summary\nin one typed call. The result can then be persisted via\n:class:`BehavioralSaveProfileRequest`."
      },
      "BehavioralScoreResponse": {
        "properties": {
          "scoring_version": {
            "type": "string",
            "title": "Scoring Version",
            "description": "Version of the compatibility category map and score rules. Saved responses with an older or missing version must be recalculated.",
            "default": "compatibility-2.2"
          },
          "evidence_provenance": {
            "type": "string",
            "enum": [
              "human_reported",
              "astro_hypothesis",
              "mixed"
            ],
            "title": "Evidence Provenance",
            "description": "Whether the scored choices were selected by a person, estimated from chart signals, or contain both. Astrology-derived hypotheses must not be presented as reported behavior.",
            "default": "human_reported"
          },
          "dimension_scores": {
            "items": {
              "$ref": "#/components/schemas/DimensionScore"
            },
            "type": "array",
            "title": "Dimension Scores",
            "description": "Per-dimension score with confidence, sample_count, and contradiction markers."
          },
          "reliability_markers": {
            "$ref": "#/components/schemas/ReliabilityMarkers",
            "description": "Reliability markers (straight-lining, low sample, etc.)."
          },
          "declared_vs_observed": {
            "$ref": "#/components/schemas/DeclaredVsObserved",
            "description": "Declared vs observed comparison."
          },
          "chat_context_summary": {
            "type": "string",
            "title": "Chat Context Summary",
            "description": "Compact safe text for LLM prompt injection. Contains only summaries, confidence, and recent concern tags \u2014 never raw answers.",
            "default": ""
          },
          "action_plan": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralActionPlan"
              },
              {
                "type": "null"
              }
            ],
            "description": "LLM-generated bounded action plan derived from the scored dimensions. Absent only when generation failed and no deterministic fallback could be built (e.g. empty dimension set)."
          },
          "compatibility_breakdown": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CompatibilityBreakdown"
              },
              {
                "type": "null"
              }
            ],
            "description": "Side-by-side compatibility calculation showing how the overall score was computed from per-category alignment between the owner and partner patterns."
          }
        },
        "type": "object",
        "title": "BehavioralScoreResponse",
        "description": "Response from the scoring endpoint."
      },
      "BehavioralSessionListItem": {
        "properties": {
          "session_id": {
            "type": "string",
            "title": "Session Id"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "updated_at": {
            "type": "string",
            "title": "Updated At"
          },
          "mode": {
            "type": "string",
            "enum": [
              "self",
              "partner_observation",
              "couple",
              "custom_concern",
              "standalone"
            ],
            "title": "Mode"
          },
          "summary": {
            "type": "string",
            "title": "Summary"
          },
          "question_count": {
            "type": "integer",
            "title": "Question Count"
          },
          "answered_count": {
            "type": "integer",
            "title": "Answered Count"
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "created_at",
          "updated_at",
          "mode",
          "summary",
          "question_count",
          "answered_count"
        ],
        "title": "BehavioralSessionListItem",
        "description": "A list item for browsing saved sessions."
      },
      "BehavioralSessionListResponse": {
        "properties": {
          "sessions": {
            "items": {
              "$ref": "#/components/schemas/BehavioralSessionListItem"
            },
            "type": "array",
            "title": "Sessions"
          },
          "total": {
            "type": "integer",
            "title": "Total"
          }
        },
        "type": "object",
        "required": [
          "sessions",
          "total"
        ],
        "title": "BehavioralSessionListResponse",
        "description": "Response listing saved sessions."
      },
      "BehavioralSuggestionsRequest": {
        "properties": {
          "person1": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Person1",
            "description": "Optional birth input or existing account profile. Typed loosely (Any) so the route can accept either a CompatibilityBirthInput dict or a saved-profile reference."
          },
          "person2": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Person2",
            "description": "Optional birth input or saved partner profile."
          },
          "relationship_stage": {
            "type": "string",
            "enum": [
              "arranged",
              "dating",
              "considering",
              "engaged",
              "married",
              "reconnecting",
              "unsure",
              "prospective"
            ],
            "title": "Relationship Stage",
            "description": "Relationship stage.",
            "default": "considering"
          },
          "known_behavioral_profile_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Known Behavioral Profile Id",
            "description": "Optional current user profile id, so suggestions can avoid repeating covered dimensions."
          }
        },
        "type": "object",
        "title": "BehavioralSuggestionsRequest",
        "description": "Request body for the suggestions endpoint."
      },
      "BehavioralSuggestionsResponse": {
        "properties": {
          "suggested_concerns": {
            "items": {
              "$ref": "#/components/schemas/SuggestedConcern"
            },
            "type": "array",
            "title": "Suggested Concerns",
            "description": "Suggested concern chips."
          },
          "recommended_scenario_count": {
            "type": "integer",
            "maximum": 20.0,
            "minimum": 3.0,
            "title": "Recommended Scenario Count",
            "description": "Recommended scenario count (6 quick, 10 balanced, 14 deep).",
            "default": 6
          },
          "coverage_map": {
            "items": {
              "$ref": "#/components/schemas/CoverageMapEntry"
            },
            "type": "array",
            "title": "Coverage Map",
            "description": "Which dimensions are likely important given charts and context."
          }
        },
        "type": "object",
        "title": "BehavioralSuggestionsResponse",
        "description": "Response with suggested concerns and a coverage map."
      },
      "BillingHistoryResponse": {
        "properties": {
          "payments": {
            "items": {
              "$ref": "#/components/schemas/BillingPaymentResponse"
            },
            "type": "array",
            "title": "Payments"
          },
          "support_email": {
            "type": "string",
            "title": "Support Email"
          },
          "invoice_delivery": {
            "type": "string",
            "title": "Invoice Delivery",
            "default": "Dodo Payments emails an invoice after every successful payment."
          }
        },
        "type": "object",
        "required": [
          "payments",
          "support_email"
        ],
        "title": "BillingHistoryResponse"
      },
      "BillingPaymentResponse": {
        "properties": {
          "payment_id": {
            "type": "string",
            "title": "Payment Id"
          },
          "status": {
            "type": "string",
            "title": "Status"
          },
          "total_amount": {
            "type": "integer",
            "title": "Total Amount"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          },
          "invoice_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Url"
          },
          "refund_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Refund Status"
          },
          "subscription_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subscription Id"
          }
        },
        "type": "object",
        "required": [
          "payment_id",
          "status",
          "total_amount",
          "currency"
        ],
        "title": "BillingPaymentResponse"
      },
      "BillingPortalRequest": {
        "properties": {
          "return_url": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Return Url"
          }
        },
        "type": "object",
        "title": "BillingPortalRequest"
      },
      "BillingPortalResponse": {
        "properties": {
          "portal_url": {
            "type": "string",
            "title": "Portal Url"
          }
        },
        "type": "object",
        "required": [
          "portal_url"
        ],
        "title": "BillingPortalResponse"
      },
      "BirthInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100,
            "minLength": 1,
            "title": "Name"
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "DD/MM/YYYY"
          },
          "birth_time": {
            "type": "string",
            "title": "Birth Time",
            "description": "HH:MM (24h)"
          },
          "birth_latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Birth Latitude"
          },
          "birth_longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Birth Longitude"
          },
          "birth_timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -12.0,
            "title": "Birth Timezone Offset"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "name",
          "birth_date",
          "birth_time",
          "birth_latitude",
          "birth_longitude",
          "birth_timezone_offset"
        ],
        "title": "BirthInput"
      },
      "Body_analyze_palm_api_v1_palmistry_analyze_post": {
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_analyze_palm_api_v1_palmistry_analyze_post"
      },
      "Body_create_palmistry_report_flow_api_v2_palmistry_report_flow_post": {
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "title": "File",
            "description": "Palm image upload (JPEG or PNG)."
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_create_palmistry_report_flow_api_v2_palmistry_report_flow_post"
      },
      "Body_quick_palm_check_api_v1_palmistry_quick_check_post": {
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_quick_palm_check_api_v1_palmistry_quick_check_post"
      },
      "CategoryBreakdown": {
        "properties": {
          "category": {
            "type": "string",
            "title": "Category",
            "description": "Friendly category label (e.g. 'Conflict harmony')."
          },
          "you": {
            "$ref": "#/components/schemas/PersonPattern",
            "description": "The owner's pattern for this category."
          },
          "partner": {
            "$ref": "#/components/schemas/PersonPattern",
            "description": "The partner's pattern for this category."
          },
          "alignment": {
            "type": "string",
            "enum": [
              "aligned",
              "complementary",
              "mismatched",
              "unknown"
            ],
            "title": "Alignment",
            "description": "How the two patterns relate.",
            "default": "unknown"
          },
          "alignment_explanation": {
            "type": "string",
            "title": "Alignment Explanation",
            "description": "Plain-language explanation of the alignment.",
            "default": ""
          },
          "score_out_of_10": {
            "type": "integer",
            "maximum": 10.0,
            "minimum": 0.0,
            "title": "Score Out Of 10",
            "description": "Category score on a 0-10 scale.",
            "default": 0
          },
          "weight_percent": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Weight Percent",
            "description": "Weight of this category in the overall score.",
            "default": 25
          },
          "contribution": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contribution",
            "description": "This category's contribution to the overall score. None when the category is unknown and excluded from the total."
          },
          "confidence": {
            "type": "string",
            "enum": [
              "low",
              "moderate",
              "high"
            ],
            "title": "Confidence",
            "description": "Confidence based on total answer count from both sides.",
            "default": "low"
          }
        },
        "type": "object",
        "required": [
          "category"
        ],
        "title": "CategoryBreakdown",
        "description": "Per-category compatibility breakdown with both sides' patterns."
      },
      "ChatHistoryMessage": {
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "user",
              "assistant"
            ],
            "title": "Role"
          },
          "content": {
            "type": "string",
            "maxLength": 10000,
            "minLength": 1,
            "title": "Content"
          }
        },
        "type": "object",
        "required": [
          "role",
          "content"
        ],
        "title": "ChatHistoryMessage"
      },
      "ChatMessage": {
        "properties": {
          "content": {
            "type": "string",
            "maxLength": 10000,
            "minLength": 1,
            "title": "Content"
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          },
          "thread_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Thread Id"
          }
        },
        "type": "object",
        "required": [
          "content"
        ],
        "title": "ChatMessage",
        "description": "Chat message request."
      },
      "ChatPresentation": {
        "properties": {
          "answer": {
            "type": "string",
            "title": "Answer"
          },
          "next_action": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Action"
          },
          "details_markdown": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Details Markdown"
          },
          "method_markdown": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Method Markdown"
          }
        },
        "type": "object",
        "required": [
          "answer"
        ],
        "title": "ChatPresentation",
        "description": "The plain-language layer shown before optional technical detail."
      },
      "ChatRequest": {
        "properties": {
          "message": {
            "$ref": "#/components/schemas/ChatMessage"
          },
          "persona": {
            "$ref": "#/components/schemas/PersonaType",
            "default": "sage"
          },
          "user_id": {
            "type": "string",
            "minLength": 1,
            "title": "User Id"
          },
          "include_context": {
            "type": "boolean",
            "title": "Include Context",
            "default": true
          },
          "history": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChatHistoryMessage"
                },
                "type": "array",
                "maxItems": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "History"
          },
          "kundli_context": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KundliChatContext"
              },
              {
                "type": "null"
              }
            ]
          },
          "compatibility_context": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CompatibilityChatContext"
              },
              {
                "type": "null"
              }
            ]
          },
          "partner_evaluation_context": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PartnerEvaluationChatContext"
              },
              {
                "type": "null"
              }
            ]
          },
          "stream": {
            "type": "boolean",
            "title": "Stream",
            "default": false
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "default": "english"
          },
          "bio": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Bio"
          },
          "thread_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Thread Id"
          },
          "client_message_idempotency_key": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Message Idempotency Key"
          },
          "sarvajna_mode": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "quick",
                  "standard",
                  "deep"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Sarvajna Mode"
          },
          "sarvajna_answers": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "integer",
                  "maximum": 5.0,
                  "minimum": 1.0
                },
                "type": "object",
                "maxProperties": 45
              },
              {
                "type": "null"
              }
            ],
            "title": "Sarvajna Answers"
          },
          "sarvajna_finalize": {
            "type": "boolean",
            "title": "Sarvajna Finalize",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "message",
          "user_id"
        ],
        "title": "ChatRequest",
        "description": "Full chat request with persona selection."
      },
      "ChatResponse": {
        "properties": {
          "response": {
            "type": "string",
            "title": "Response"
          },
          "persona": {
            "type": "string",
            "title": "Persona"
          },
          "session_id": {
            "type": "string",
            "title": "Session Id"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "title": "Timestamp"
          },
          "tokens_used": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tokens Used"
          },
          "usage_charged": {
            "type": "boolean",
            "title": "Usage Charged",
            "default": true
          },
          "thread_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Thread Id"
          },
          "user_message_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Message Id"
          },
          "assistant_message_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Assistant Message Id"
          },
          "presentation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ChatPresentation"
              },
              {
                "type": "null"
              }
            ]
          },
          "sarvajna_result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SarvajnaTrustedResult"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "type": "object",
        "required": [
          "response",
          "persona",
          "session_id"
        ],
        "title": "ChatResponse",
        "description": "Chat response."
      },
      "ChatThreadCreateRequest": {
        "properties": {
          "title": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 160
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          },
          "source_kind": {
            "type": "string",
            "enum": [
              "general",
              "compatibility",
              "kundli",
              "palmistry"
            ],
            "title": "Source Kind",
            "default": "general"
          },
          "client_session_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 160
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Session Id"
          },
          "persona": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Persona"
          }
        },
        "type": "object",
        "title": "ChatThreadCreateRequest"
      },
      "ChatThreadListResponse": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ChatThreadSummary"
            },
            "type": "array",
            "title": "Items"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor"
          }
        },
        "type": "object",
        "required": [
          "items"
        ],
        "title": "ChatThreadListResponse"
      },
      "ChatThreadMessage": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id"
          },
          "role": {
            "type": "string",
            "enum": [
              "user",
              "assistant"
            ],
            "title": "Role"
          },
          "content": {
            "type": "string",
            "title": "Content"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At"
          },
          "presentation": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Presentation"
          }
        },
        "type": "object",
        "required": [
          "id",
          "role",
          "content",
          "created_at"
        ],
        "title": "ChatThreadMessage"
      },
      "ChatThreadMessagesResponse": {
        "properties": {
          "thread_id": {
            "type": "string",
            "format": "uuid",
            "title": "Thread Id"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/ChatThreadMessage"
            },
            "type": "array",
            "title": "Items"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Cursor"
          }
        },
        "type": "object",
        "required": [
          "thread_id",
          "items"
        ],
        "title": "ChatThreadMessagesResponse"
      },
      "ChatThreadResponse": {
        "properties": {
          "thread": {
            "$ref": "#/components/schemas/ChatThreadSummary"
          }
        },
        "type": "object",
        "required": [
          "thread"
        ],
        "title": "ChatThreadResponse"
      },
      "ChatThreadSummary": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id"
          },
          "client_session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Session Id"
          },
          "title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          },
          "last_message_preview": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Message Preview"
          },
          "last_message_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Message At"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At"
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At"
          },
          "persona": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Persona"
          },
          "source_kind": {
            "type": "string",
            "enum": [
              "general",
              "compatibility",
              "kundli",
              "palmistry"
            ],
            "title": "Source Kind"
          }
        },
        "type": "object",
        "required": [
          "id",
          "client_session_id",
          "title",
          "last_message_preview",
          "last_message_at",
          "created_at",
          "updated_at",
          "expires_at",
          "persona",
          "source_kind"
        ],
        "title": "ChatThreadSummary"
      },
      "ChatThreadUpdateRequest": {
        "properties": {
          "title": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 160
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          }
        },
        "type": "object",
        "title": "ChatThreadUpdateRequest"
      },
      "CheckoutReturnRequest": {
        "properties": {
          "checkout_session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Checkout Session Id"
          },
          "provider": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Provider"
          }
        },
        "type": "object",
        "title": "CheckoutReturnRequest"
      },
      "CheckoutReturnResponse": {
        "properties": {
          "access_tier": {
            "type": "string",
            "title": "Access Tier"
          },
          "access_expires_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Expires At"
          },
          "subscription_status": {
            "type": "string",
            "title": "Subscription Status"
          },
          "payment_synced": {
            "type": "boolean",
            "title": "Payment Synced",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "access_tier",
          "subscription_status"
        ],
        "title": "CheckoutReturnResponse"
      },
      "CheckoutStartRequest": {
        "properties": {
          "plan": {
            "type": "string",
            "pattern": "^(monthly|quarterly|semiannual|annual)$",
            "title": "Plan",
            "default": "monthly"
          },
          "return_url": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Return Url"
          }
        },
        "type": "object",
        "title": "CheckoutStartRequest"
      },
      "CheckoutStartResponse": {
        "properties": {
          "checkout_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Checkout Url"
          },
          "checkout_session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Checkout Session Id"
          },
          "provider": {
            "type": "string",
            "title": "Provider",
            "default": "none"
          },
          "requires_redirect": {
            "type": "boolean",
            "title": "Requires Redirect",
            "default": false
          }
        },
        "type": "object",
        "title": "CheckoutStartResponse"
      },
      "CheckoutWebhookPayload": {
        "properties": {
          "provider": {
            "type": "string",
            "pattern": "^(stripe|paypal|manual)$",
            "title": "Provider"
          },
          "customer_id": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "title": "Customer Id"
          },
          "subscription_id": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "title": "Subscription Id"
          },
          "event_type": {
            "type": "string",
            "title": "Event Type",
            "default": "checkout.completed"
          },
          "duration_days": {
            "type": "integer",
            "maximum": 365.0,
            "minimum": 1.0,
            "title": "Duration Days",
            "default": 30
          },
          "user_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Id"
          },
          "session_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Token"
          }
        },
        "type": "object",
        "required": [
          "provider",
          "customer_id",
          "subscription_id"
        ],
        "title": "CheckoutWebhookPayload",
        "description": "Generic webhook payload shape.\n\nA real provider integration (Stripe, etc.) would verify the\nsignature and parse the provider-specific event. This schema\ndefines the minimal fields the entitlement bridge needs."
      },
      "CognitiveInterviewSubmission": {
        "properties": {
          "participant_token": {
            "type": "string",
            "title": "Participant Token"
          },
          "item_id": {
            "type": "string",
            "title": "Item Id"
          },
          "strata": {
            "$ref": "#/components/schemas/ParticipantStrata"
          },
          "consent_version": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Consent Version"
          },
          "paraphrase": {
            "type": "string",
            "maxLength": 3000,
            "minLength": 1,
            "title": "Paraphrase"
          },
          "comprehension_rating": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Comprehension Rating"
          },
          "response_process_rating": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Response Process Rating"
          },
          "option_mapping_rating": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Option Mapping Rating"
          },
          "confusing_terms": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Confusing Terms"
          },
          "social_desirability_concern": {
            "type": "boolean",
            "title": "Social Desirability Concern",
            "default": false
          },
          "recommended_change": {
            "type": "boolean",
            "title": "Recommended Change",
            "default": false
          },
          "interviewer_notes": {
            "type": "string",
            "maxLength": 3000,
            "title": "Interviewer Notes",
            "default": ""
          },
          "duration_ms": {
            "type": "integer",
            "maximum": 7200000.0,
            "minimum": 1000.0,
            "title": "Duration Ms"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "participant_token",
          "item_id",
          "strata",
          "consent_version",
          "paraphrase",
          "comprehension_rating",
          "response_process_rating",
          "option_mapping_rating",
          "duration_ms"
        ],
        "title": "CognitiveInterviewSubmission"
      },
      "CompatibilityArtifact-Input": {
        "properties": {
          "artifact_id": {
            "type": "string",
            "title": "Artifact Id",
            "description": "Stable uuid identifying the persisted artifact."
          },
          "user_id": {
            "type": "string",
            "maxLength": 128,
            "minLength": 1,
            "title": "User Id",
            "description": "Owning user id. Used to scope reads."
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id",
            "description": "Owning session id (chat thread). Optional. When set, the artifact is bound to that session."
          },
          "history_schema_version": {
            "type": "string",
            "title": "History Schema Version",
            "default": "v2-compatibility-history-1.1.0"
          },
          "compatibility_schema_version": {
            "type": "string",
            "title": "Compatibility Schema Version",
            "default": "v2-compatibility-1.0.0"
          },
          "created_at": {
            "type": "string",
            "title": "Created At",
            "description": "ISO-8601 UTC timestamp at which the artifact was persisted. Wall-clock; not part of the byte-comparable contract."
          },
          "summary": {
            "$ref": "#/components/schemas/CompatibilityArtifactSummary"
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/app__schemas__compatibility__InterpretationStatus"
          },
          "degradation_reasons": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Degradation Reasons",
            "description": "Mirrored from the report so thread previews can surface degradation markers without re-deriving."
          },
          "red_flags": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityRedFlagOut"
            },
            "type": "array",
            "title": "Red Flags",
            "description": "Mirrored from the report for previews. Empty list when the report had no red flags."
          },
          "report": {
            "$ref": "#/components/schemas/CompatibilityReport-Input"
          },
          "sections": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SectionedCompatibilityReport-Input"
              },
              {
                "type": "null"
              }
            ],
            "description": "Sectioned trust-first contract mirrored verbatim from the report response. None when the caller did not request sections or the artifact was saved before M006 S03 T01. The block is the canonical shape for trust-first rendering; the flat ``report`` field is preserved for backward-compat callers."
          },
          "behavioral_evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralEvidenceBlock"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional behavioral evidence summary mirrored verbatim from the report response (V2-S08). None when the report was generated without behavioral or scenario evidence, or for artifacts saved before V2-S08."
          },
          "followup": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CompatibilityFollowUpContext-Input"
              },
              {
                "type": "null"
              }
            ],
            "description": "Compatibility follow-up continuity block. None when the caller did not author follow-up continuity or the artifact was saved before M006 S03 T01. When set, carries the stable scenario ids, selected answers, and authored evidence references needed to rebuild the in-session chat handoff."
          }
        },
        "type": "object",
        "required": [
          "artifact_id",
          "user_id",
          "created_at",
          "summary",
          "interpretation_status",
          "report"
        ],
        "title": "CompatibilityArtifact",
        "description": "Persisted envelope for a single compatibility reading.\n\nField set is the deterministic truth plus the persistence\nmetadata needed to reopen the reading without recomputation:\n\n* ``artifact_id`` is a stable uuid so the same stored report\n  can be reopened across sessions and across client reloads.\n* ``user_id`` and ``session_id`` scope the artifact so one\n  account cannot read another account's compatibility history.\n* ``compatibility_schema_version`` is the same string the\n  report wire contract exposes; a reopen of the artifact\n  yields the same report fields byte-comparable to a freshly\n  generated report.\n* ``history_schema_version`` is the persistence-envelope\n  version. Bumped when the envelope shape changes.\n* ``created_at`` is the wall-clock time the artifact was\n  persisted (ISO-8601, UTC, ``Z`` suffix).\n* ``interpretation_status`` is mirrored from the report so\n  thread previews can render the honest availability state\n  without loading the full report.\n* ``degradation_reasons`` is mirrored from the report so\n  thread previews can surface degradation markers.\n* ``red_flags`` is mirrored from the report for the same\n  reason.\n* ``summary`` is a short preview block for thread rendering.\n* ``report`` is the full :class:`CompatibilityReport`. Stored\n  verbatim, no lossy translation. The flat report is the\n  authoritative truth surface; ``compatibility_schema_version``\n  stays byte-comparable to a freshly generated report.\n* ``sections`` is the optional sectioned trust-first contract\n  mirrored verbatim from the report response. None when the\n  caller did not request sections or the artifact was saved\n  before M006 S03 T01. The block is the canonical shape for\n  trust-first rendering; the flat ``report`` field is\n  preserved for backward-compat callers.\n* ``followup`` is the optional compatibility follow-up\n  context block (scenario ids, selected answers, evidence\n  refs, user concern) so a reopened artifact can rebuild\n  the same in-session chat handoff without re-deriving from\n  transient session state. None when the caller did not\n  author follow-up continuity."
      },
      "CompatibilityArtifact-Output": {
        "properties": {
          "artifact_id": {
            "type": "string",
            "title": "Artifact Id",
            "description": "Stable uuid identifying the persisted artifact."
          },
          "user_id": {
            "type": "string",
            "maxLength": 128,
            "minLength": 1,
            "title": "User Id",
            "description": "Owning user id. Used to scope reads."
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id",
            "description": "Owning session id (chat thread). Optional. When set, the artifact is bound to that session."
          },
          "history_schema_version": {
            "type": "string",
            "title": "History Schema Version",
            "default": "v2-compatibility-history-1.1.0"
          },
          "compatibility_schema_version": {
            "type": "string",
            "title": "Compatibility Schema Version",
            "default": "v2-compatibility-1.0.0"
          },
          "created_at": {
            "type": "string",
            "title": "Created At",
            "description": "ISO-8601 UTC timestamp at which the artifact was persisted. Wall-clock; not part of the byte-comparable contract."
          },
          "summary": {
            "$ref": "#/components/schemas/CompatibilityArtifactSummary"
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/app__schemas__compatibility__InterpretationStatus"
          },
          "degradation_reasons": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Degradation Reasons",
            "description": "Mirrored from the report so thread previews can surface degradation markers without re-deriving."
          },
          "red_flags": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityRedFlagOut"
            },
            "type": "array",
            "title": "Red Flags",
            "description": "Mirrored from the report for previews. Empty list when the report had no red flags."
          },
          "report": {
            "$ref": "#/components/schemas/CompatibilityReport-Output"
          },
          "sections": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SectionedCompatibilityReport-Output"
              },
              {
                "type": "null"
              }
            ],
            "description": "Sectioned trust-first contract mirrored verbatim from the report response. None when the caller did not request sections or the artifact was saved before M006 S03 T01. The block is the canonical shape for trust-first rendering; the flat ``report`` field is preserved for backward-compat callers."
          },
          "behavioral_evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralEvidenceBlock"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional behavioral evidence summary mirrored verbatim from the report response (V2-S08). None when the report was generated without behavioral or scenario evidence, or for artifacts saved before V2-S08."
          },
          "followup": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CompatibilityFollowUpContext-Output"
              },
              {
                "type": "null"
              }
            ],
            "description": "Compatibility follow-up continuity block. None when the caller did not author follow-up continuity or the artifact was saved before M006 S03 T01. When set, carries the stable scenario ids, selected answers, and authored evidence references needed to rebuild the in-session chat handoff."
          }
        },
        "type": "object",
        "required": [
          "artifact_id",
          "user_id",
          "created_at",
          "summary",
          "interpretation_status",
          "report"
        ],
        "title": "CompatibilityArtifact",
        "description": "Persisted envelope for a single compatibility reading.\n\nField set is the deterministic truth plus the persistence\nmetadata needed to reopen the reading without recomputation:\n\n* ``artifact_id`` is a stable uuid so the same stored report\n  can be reopened across sessions and across client reloads.\n* ``user_id`` and ``session_id`` scope the artifact so one\n  account cannot read another account's compatibility history.\n* ``compatibility_schema_version`` is the same string the\n  report wire contract exposes; a reopen of the artifact\n  yields the same report fields byte-comparable to a freshly\n  generated report.\n* ``history_schema_version`` is the persistence-envelope\n  version. Bumped when the envelope shape changes.\n* ``created_at`` is the wall-clock time the artifact was\n  persisted (ISO-8601, UTC, ``Z`` suffix).\n* ``interpretation_status`` is mirrored from the report so\n  thread previews can render the honest availability state\n  without loading the full report.\n* ``degradation_reasons`` is mirrored from the report so\n  thread previews can surface degradation markers.\n* ``red_flags`` is mirrored from the report for the same\n  reason.\n* ``summary`` is a short preview block for thread rendering.\n* ``report`` is the full :class:`CompatibilityReport`. Stored\n  verbatim, no lossy translation. The flat report is the\n  authoritative truth surface; ``compatibility_schema_version``\n  stays byte-comparable to a freshly generated report.\n* ``sections`` is the optional sectioned trust-first contract\n  mirrored verbatim from the report response. None when the\n  caller did not request sections or the artifact was saved\n  before M006 S03 T01. The block is the canonical shape for\n  trust-first rendering; the flat ``report`` field is\n  preserved for backward-compat callers.\n* ``followup`` is the optional compatibility follow-up\n  context block (scenario ids, selected answers, evidence\n  refs, user concern) so a reopened artifact can rebuild\n  the same in-session chat handoff without re-deriving from\n  transient session state. None when the caller did not\n  author follow-up continuity."
      },
      "CompatibilityArtifactListItem-Input": {
        "properties": {
          "artifact_id": {
            "type": "string",
            "title": "Artifact Id"
          },
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          },
          "history_schema_version": {
            "type": "string",
            "title": "History Schema Version",
            "default": "v2-compatibility-history-1.1.0"
          },
          "compatibility_schema_version": {
            "type": "string",
            "title": "Compatibility Schema Version",
            "default": "v2-compatibility-1.0.0"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "summary": {
            "$ref": "#/components/schemas/CompatibilityArtifactSummary"
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/app__schemas__compatibility__InterpretationStatus"
          },
          "degradation_reasons": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Degradation Reasons"
          },
          "red_flags": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityRedFlagOut"
            },
            "type": "array",
            "title": "Red Flags"
          },
          "has_sections": {
            "type": "boolean",
            "title": "Has Sections",
            "description": "True when the persisted artifact carries the sectioned contract. False for legacy artifacts saved before M006 S03 T01 or when the caller did not request sections.",
            "default": false
          },
          "has_followup": {
            "type": "boolean",
            "title": "Has Followup",
            "description": "True when the persisted artifact carries the follow-up continuity block. False for legacy artifacts or when the caller did not author follow-up continuity.",
            "default": false
          },
          "has_behavioral_evidence": {
            "type": "boolean",
            "title": "Has Behavioral Evidence",
            "description": "True when the persisted artifact carries a behavioral evidence block (V2-S08). False for legacy artifacts or when the report was generated without behavioral or scenario evidence.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "artifact_id",
          "user_id",
          "created_at",
          "summary",
          "interpretation_status"
        ],
        "title": "CompatibilityArtifactListItem",
        "description": "One entry in a compatibility-history list response.\n\nCarries the preview block, the interpretation status, and the\nidentity fields - but **not** the full report. A client\nopens the full report through a follow-up read by\n``artifact_id``.\n\nThe ``has_sections`` and ``has_followup`` markers are\nlightweight booleans that surface whether the persisted\nartifact carries the sectioned contract and the follow-up\ncontinuity block without bloating the list payload. A\nclient can use them to show a \"reopen with full context\"\naffordance in the thread preview before issuing the\nfollow-up read."
      },
      "CompatibilityArtifactListItem-Output": {
        "properties": {
          "artifact_id": {
            "type": "string",
            "title": "Artifact Id"
          },
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          },
          "history_schema_version": {
            "type": "string",
            "title": "History Schema Version",
            "default": "v2-compatibility-history-1.1.0"
          },
          "compatibility_schema_version": {
            "type": "string",
            "title": "Compatibility Schema Version",
            "default": "v2-compatibility-1.0.0"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "summary": {
            "$ref": "#/components/schemas/CompatibilityArtifactSummary"
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/app__schemas__compatibility__InterpretationStatus"
          },
          "degradation_reasons": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Degradation Reasons"
          },
          "red_flags": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityRedFlagOut"
            },
            "type": "array",
            "title": "Red Flags"
          },
          "has_sections": {
            "type": "boolean",
            "title": "Has Sections",
            "description": "True when the persisted artifact carries the sectioned contract. False for legacy artifacts saved before M006 S03 T01 or when the caller did not request sections.",
            "default": false
          },
          "has_followup": {
            "type": "boolean",
            "title": "Has Followup",
            "description": "True when the persisted artifact carries the follow-up continuity block. False for legacy artifacts or when the caller did not author follow-up continuity.",
            "default": false
          },
          "has_behavioral_evidence": {
            "type": "boolean",
            "title": "Has Behavioral Evidence",
            "description": "True when the persisted artifact carries a behavioral evidence block (V2-S08). False for legacy artifacts or when the report was generated without behavioral or scenario evidence.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "artifact_id",
          "user_id",
          "created_at",
          "summary",
          "interpretation_status"
        ],
        "title": "CompatibilityArtifactListItem",
        "description": "One entry in a compatibility-history list response.\n\nCarries the preview block, the interpretation status, and the\nidentity fields - but **not** the full report. A client\nopens the full report through a follow-up read by\n``artifact_id``.\n\nThe ``has_sections`` and ``has_followup`` markers are\nlightweight booleans that surface whether the persisted\nartifact carries the sectioned contract and the follow-up\ncontinuity block without bloating the list payload. A\nclient can use them to show a \"reopen with full context\"\naffordance in the thread preview before issuing the\nfollow-up read."
      },
      "CompatibilityArtifactListResponse-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-history-1.1.0"
          },
          "artifacts": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityArtifactListItem-Input"
            },
            "type": "array",
            "title": "Artifacts"
          },
          "count": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Count",
            "description": "Number of artifacts returned. Mirrors ``len(artifacts)`` so a client can paginate without trusting the array length under concurrent writes."
          }
        },
        "type": "object",
        "required": [
          "count"
        ],
        "title": "CompatibilityArtifactListResponse",
        "description": "v2 compatibility-history list response wrapper.\n\nNewest artifact first (sorted by ``created_at`` descending at\nthe service boundary). The list is user-scoped: a caller can\nonly see artifacts belonging to the user they authenticate as.\nSession filtering is additive - the list is filtered by\n``session_id`` when the caller provides it."
      },
      "CompatibilityArtifactListResponse-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-history-1.1.0"
          },
          "artifacts": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityArtifactListItem-Output"
            },
            "type": "array",
            "title": "Artifacts"
          },
          "count": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Count",
            "description": "Number of artifacts returned. Mirrors ``len(artifacts)`` so a client can paginate without trusting the array length under concurrent writes."
          }
        },
        "type": "object",
        "required": [
          "count"
        ],
        "title": "CompatibilityArtifactListResponse",
        "description": "v2 compatibility-history list response wrapper.\n\nNewest artifact first (sorted by ``created_at`` descending at\nthe service boundary). The list is user-scoped: a caller can\nonly see artifacts belonging to the user they authenticate as.\nSession filtering is additive - the list is filtered by\n``session_id`` when the caller provides it."
      },
      "CompatibilityArtifactResponse-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-history-1.1.0"
          },
          "artifact": {
            "$ref": "#/components/schemas/CompatibilityArtifact-Input"
          }
        },
        "type": "object",
        "required": [
          "artifact"
        ],
        "title": "CompatibilityArtifactResponse",
        "description": "v2 compatibility-history read response wrapper.\n\nThe ``schema_version`` is the persistence-envelope version. A\nclient should compare the artifact's\n``compatibility_schema_version`` to the report wire version\nbefore reopening to confirm byte-comparability."
      },
      "CompatibilityArtifactResponse-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-history-1.1.0"
          },
          "artifact": {
            "$ref": "#/components/schemas/CompatibilityArtifact-Output"
          }
        },
        "type": "object",
        "required": [
          "artifact"
        ],
        "title": "CompatibilityArtifactResponse",
        "description": "v2 compatibility-history read response wrapper.\n\nThe ``schema_version`` is the persistence-envelope version. A\nclient should compare the artifact's\n``compatibility_schema_version`` to the report wire version\nbefore reopening to confirm byte-comparability."
      },
      "CompatibilityArtifactSaveRequest": {
        "properties": {
          "user_id": {
            "type": "string",
            "maxLength": 128,
            "minLength": 1,
            "title": "User Id",
            "description": "Owning user id. Required so the artifact can be scoped on read."
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id",
            "description": "Owning session id (chat thread). Optional. When set, the artifact is bound to that session."
          },
          "summary_text": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 400
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary Text",
            "description": "Optional single-sentence summary for the thread preview. When omitted, the service derives one from the report's recommendation text."
          },
          "report": {
            "$ref": "#/components/schemas/CompatibilityReportResponse-Input",
            "description": "The compatibility report to persist. The service copies the report verbatim into the artifact and mirrors the optional ``sections`` field onto the envelope."
          },
          "scenarios": {
            "items": {
              "$ref": "#/components/schemas/DampatyaScenario-Input"
            },
            "type": "array",
            "title": "Scenarios",
            "description": "Authored scenario set from the report generation flow. Persisted into the follow-up block (as compact summaries) so a reopened artifact can rebuild the in-session chat handoff without re-deriving from transient session state. Empty list when the caller did not author scenarios."
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/app__schemas__compatibility__ScenarioAnswer"
            },
            "type": "array",
            "title": "Answers",
            "description": "Selected scenario answers from the report generation flow. Persisted into the follow-up block with stable scenario-id linkage so a reopen can match the same answers to the same scenario ids. Empty list when the caller did not collect answers."
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern",
            "description": "Optional user concern from the report generation flow. Persisted into the follow-up block so a reopened artifact can surface the same concern in the chat handoff. None when the caller did not supply one."
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "report"
        ],
        "title": "CompatibilityArtifactSaveRequest",
        "description": "Save request body.\n\nThe caller supplies the deterministic\n:class:`CompatibilityReportResponse` they just received from\n``POST /api/v2/compatibility/reports`` plus the ``user_id`` and\n``session_id`` that scope the new artifact. ``summary_text``\nis optional; when omitted, the service derives a single-\nsentence summary from the report so the thread preview\nremains useful even if the client forgot to pass one.\n\nThe wire contract is intentionally **additive**: the caller\nsends the report in the same shape the report endpoint\nreturned it. The service is responsible for shaping it into\nthe persisted envelope and stamping the persistence metadata.\n\nThe ``scenarios``, ``answers``, and ``user_concern`` fields\nare the additive **continuity inputs** introduced in M006\nS03 T01. They mirror the authored state from the report-\ngeneration flow so the persisted artifact can rebuild the\nsame in-session chat handoff on reopen without depending on\ntransient session state. All three are optional; an artifact\nsaved without them carries ``followup == None`` on reopen\nand the client surfaces an honest \"no follow-up context\nsaved\" affordance."
      },
      "CompatibilityArtifactSummary": {
        "properties": {
          "summary_text": {
            "type": "string",
            "maxLength": 400,
            "title": "Summary Text",
            "description": "Single-sentence human-readable summary for thread preview. \u2264 400 chars. Render verbatim."
          },
          "total_score": {
            "type": "integer",
            "maximum": 36.0,
            "minimum": 0.0,
            "title": "Total Score",
            "description": "Composite compatibility score, mirrored from the report for thread sorting."
          },
          "recommendation_tier": {
            "$ref": "#/components/schemas/RecommendationTier"
          },
          "person1_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Person1 Name",
            "description": "Echo of person 1's name for previews. None when the artifact was stored without names (legacy)."
          },
          "person2_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Person2 Name",
            "description": "Echo of person 2's name for previews."
          },
          "preview": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Preview",
            "description": "Top three red-flag explanations, mirrored from the report for previews. Render verbatim."
          }
        },
        "type": "object",
        "required": [
          "summary_text",
          "total_score",
          "recommendation_tier"
        ],
        "title": "CompatibilityArtifactSummary",
        "description": "Short preview block for a persisted compatibility artifact.\n\nSurfaced in thread previews so a caller can tell at a glance\nwhat a stored artifact is without loading the full report.\nThe ``summary_text`` is a single-sentence human-readable line\nsuitable for chat-history rendering. The ``preview`` list\ncarries the top red-flag explanations (truncated to three) so\na thread can surface warnings without re-deriving them."
      },
      "CompatibilityBirthInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "title": "Name",
            "description": "Subject's name (non-empty, \u2264 120 chars)."
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "Birth date in DD/MM/YYYY format. Year must be 1900-2100 for bundled DE421 coverage."
          },
          "birth_time": {
            "type": "string",
            "title": "Birth Time",
            "description": "Birth time in HH:MM (24-hour) local civil time at the given timezone_offset."
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude",
            "description": "Latitude in decimal degrees, -90..90."
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude",
            "description": "Longitude in decimal degrees, -180..180."
          },
          "timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -14.0,
            "title": "Timezone Offset",
            "description": "Hours from UTC for the local civil time of birth, -14..14. Must be supplied with the resolved birth place."
          },
          "timezone_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Id",
            "description": "IANA timezone ID (e.g., 'Asia/Kolkata'). Preferred over offset."
          },
          "birth_time_precision_minutes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Time Precision Minutes",
            "description": "Birth time precision in minutes (e.g., 0 for exact, 15 for +/- 15 mins)."
          }
        },
        "type": "object",
        "required": [
          "name",
          "birth_date",
          "birth_time",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "CompatibilityBirthInput",
        "description": "Validated birth input for the compatibility engine.\n\nThe fields and validation rules mirror :class:`KundliBirthInput`\nexactly. The per-person schema is intentionally distinct from the\nKundli schema so the two surfaces can evolve independently -\ncompatibility callers do not need ``user_id`` or ``session_id``,\nfor example, and the schema enforces that absence.\n\nAll range and format rules are enforced here so the engine can\ntrust the input by the time it reaches ``compute_compatibility``.\nFormat-level errors map to HTTP 422 via FastAPI's\n:class:`RequestValidationError` handler.",
        "example": {
          "birth_date": "15/05/1990",
          "birth_time": "10:30",
          "latitude": 19.076,
          "longitude": 72.8777,
          "name": "Asha Sharma",
          "timezone_offset": 5.5
        }
      },
      "CompatibilityBreakdown": {
        "properties": {
          "categories": {
            "items": {
              "$ref": "#/components/schemas/CategoryBreakdown"
            },
            "type": "array",
            "title": "Categories",
            "description": "Per-category breakdown with both sides' patterns."
          },
          "overall_score": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Overall Score",
            "description": "Sum of all category contributions, scaled to 100.",
            "default": 0
          },
          "overall_score_available": {
            "type": "boolean",
            "title": "Overall Score Available",
            "description": "True when enough categories have data.",
            "default": false
          },
          "you_answer_count": {
            "type": "integer",
            "title": "You Answer Count",
            "description": "Total answers from the owner.",
            "default": 0
          },
          "partner_answer_count": {
            "type": "integer",
            "title": "Partner Answer Count",
            "description": "Total answers from the partner.",
            "default": 0
          },
          "primary_mismatch": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Primary Mismatch",
            "description": "The most significant alignment gap, if any."
          },
          "missing_evidence_message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Missing Evidence Message",
            "description": "When the score is unavailable due to insufficient evidence from one side, this message explains what's missing."
          }
        },
        "type": "object",
        "title": "CompatibilityBreakdown",
        "description": "Full side-by-side compatibility calculation.\n\nMakes the overall score transparent by showing each category's\nscore, weight, and contribution."
      },
      "CompatibilityChatContext": {
        "properties": {
          "schema_version": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40
              },
              {
                "type": "null"
              }
            ],
            "title": "Schema Version"
          },
          "context_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 160
              },
              {
                "type": "null"
              }
            ],
            "title": "Context Id"
          },
          "thread_title": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 160
              },
              {
                "type": "null"
              }
            ],
            "title": "Thread Title"
          },
          "person1_name": {
            "type": "string",
            "maxLength": 120,
            "title": "Person1 Name",
            "default": "Unknown"
          },
          "person2_name": {
            "type": "string",
            "maxLength": 120,
            "title": "Person2 Name",
            "default": "Unknown"
          },
          "total_score": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Total Score"
          },
          "maximum_score": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Maximum Score"
          },
          "recommendation": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Recommendation"
          },
          "recommendation_tier": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Recommendation Tier"
          },
          "interpretation_status": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Interpretation Status"
          },
          "interpretation_reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Interpretation Reason"
          },
          "confidence_summary": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Confidence Summary"
          },
          "element_fit": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CompatibilityElementContext"
              },
              {
                "type": "null"
              }
            ]
          },
          "layer_scores": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityLayerContext"
            },
            "type": "array",
            "maxItems": 8,
            "title": "Layer Scores"
          },
          "red_flags": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityFlagContext"
            },
            "type": "array",
            "maxItems": 8,
            "title": "Red Flags"
          },
          "doshas": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityDoshaContext"
            },
            "type": "array",
            "maxItems": 8,
            "title": "Doshas"
          },
          "comparison_mode": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Comparison Mode"
          },
          "comparison_source": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Comparison Source"
          },
          "comparison_note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Comparison Note"
          },
          "compare_people": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityComparePersonContext"
            },
            "type": "array",
            "maxItems": 6,
            "title": "Compare People"
          },
          "scenario_signals": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityScenarioSignalContext"
            },
            "type": "array",
            "maxItems": 12,
            "title": "Scenario Signals"
          },
          "section_markers": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CompatibilitySectionMarkersContext"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "type": "object",
        "title": "CompatibilityChatContext"
      },
      "CompatibilityComparePersonContext": {
        "properties": {
          "role": {
            "type": "string",
            "maxLength": 40,
            "title": "Role",
            "default": "person"
          },
          "name": {
            "type": "string",
            "maxLength": 120,
            "title": "Name",
            "default": "Unknown"
          },
          "birth_date": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 32
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Date"
          },
          "birth_time": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 32
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Time"
          },
          "place_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Place Name"
          },
          "latitude": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 90.0,
                "minimum": -90.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Latitude"
          },
          "longitude": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 180.0,
                "minimum": -180.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Longitude"
          },
          "timezone_offset": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 14.0,
                "minimum": -14.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Offset"
          }
        },
        "type": "object",
        "title": "CompatibilityComparePersonContext"
      },
      "CompatibilityDoshaContext": {
        "properties": {
          "type": {
            "type": "string",
            "maxLength": 120,
            "title": "Type",
            "default": "Unknown"
          },
          "severity": {
            "type": "string",
            "maxLength": 40,
            "title": "Severity",
            "default": "unknown"
          },
          "note": {
            "type": "string",
            "maxLength": 1000,
            "title": "Note",
            "default": ""
          }
        },
        "type": "object",
        "title": "CompatibilityDoshaContext"
      },
      "CompatibilityDoshaOut": {
        "properties": {
          "type": {
            "type": "string",
            "title": "Type",
            "description": "Machine-readable dosha name (e.g. 'kuja_dosha')."
          },
          "severity": {
            "$ref": "#/components/schemas/DoshaSeverity"
          },
          "person1_house": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 12.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Person1 House",
            "description": "Natal house where the dosha-triggering planet sits for person 1. None when the planet is missing."
          },
          "person2_house": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 12.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Person2 House",
            "description": "Natal house where the dosha-triggering planet sits for person 2. None when the planet is missing."
          },
          "note": {
            "type": "string",
            "title": "Note",
            "description": "One-line human-readable note. Render verbatim."
          }
        },
        "type": "object",
        "required": [
          "type",
          "severity",
          "note"
        ],
        "title": "CompatibilityDoshaOut",
        "description": "One classical dosha signal in the compatibility breakdown."
      },
      "CompatibilityElementContext": {
        "properties": {
          "person1_element": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Person1 Element"
          },
          "person2_element": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Person2 Element"
          },
          "relationship": {
            "type": "string",
            "maxLength": 160,
            "title": "Relationship",
            "default": "Unknown"
          },
          "note": {
            "type": "string",
            "maxLength": 1000,
            "title": "Note",
            "default": ""
          }
        },
        "type": "object",
        "title": "CompatibilityElementContext"
      },
      "CompatibilityElementFitOut": {
        "properties": {
          "person1_element": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Person1 Element",
            "description": "Person 1 moon-sign element (e.g. 'water'). None when unreadable."
          },
          "person2_element": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Person2 Element",
            "description": "Person 2 moon-sign element (e.g. 'fire'). None when unreadable."
          },
          "relationship": {
            "$ref": "#/components/schemas/ElementRelationship"
          },
          "note": {
            "type": "string",
            "title": "Note",
            "description": "One-line human-readable note. Render verbatim."
          }
        },
        "type": "object",
        "required": [
          "relationship",
          "note"
        ],
        "title": "CompatibilityElementFitOut",
        "description": "Informational element-fit signal.\n\nNot score-bearing. The two persons' moon-sign elements plus a\nclosed-literal relationship label."
      },
      "CompatibilityEngineMetadataOut": {
        "properties": {
          "compatibility_engine_name": {
            "type": "string",
            "title": "Compatibility Engine Name"
          },
          "compatibility_engine_version": {
            "type": "string",
            "title": "Compatibility Engine Version"
          },
          "compatibility_engine_implementation": {
            "type": "string",
            "title": "Compatibility Engine Implementation"
          },
          "truth_engine_name": {
            "type": "string",
            "title": "Truth Engine Name"
          },
          "truth_engine_version": {
            "type": "string",
            "title": "Truth Engine Version"
          },
          "truth_engine_implementation": {
            "type": "string",
            "title": "Truth Engine Implementation"
          },
          "ayanamsa": {
            "type": "string",
            "title": "Ayanamsa"
          },
          "house_system": {
            "type": "string",
            "title": "House System"
          },
          "ephemeris_provider": {
            "type": "string",
            "title": "Ephemeris Provider"
          },
          "ephemeris_path": {
            "type": "string",
            "title": "Ephemeris Path"
          },
          "generated_at": {
            "type": "string",
            "title": "Generated At",
            "description": "ISO-8601 UTC timestamp at which the compatibility engine composed this payload. Wall-clock; not part of the byte-comparable contract."
          },
          "determinism_guarantee": {
            "type": "string",
            "title": "Determinism Guarantee",
            "description": "Stable string describing the determinism guarantee of the compatibility engine. Clients should compare this string for cache invalidation."
          }
        },
        "type": "object",
        "required": [
          "compatibility_engine_name",
          "compatibility_engine_version",
          "compatibility_engine_implementation",
          "truth_engine_name",
          "truth_engine_version",
          "truth_engine_implementation",
          "ayanamsa",
          "house_system",
          "ephemeris_provider",
          "ephemeris_path",
          "generated_at",
          "determinism_guarantee"
        ],
        "title": "CompatibilityEngineMetadataOut",
        "description": "Identifies the compatibility scoring engine and the underlying\nchart engine.\n\nTwo versions are surfaced:\n\n* ``compatibility_engine_version`` - version of the scoring\n  math itself.\n* ``truth_engine_version`` - version of the deterministic\n  Kundli engine that produced the two truth inputs.\n\nBumping either is a wire-contract change."
      },
      "CompatibilityErrorResponse": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          }
        },
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "title": "CompatibilityErrorResponse",
        "description": "Single typed error envelope for the compatibility API.\n\nFor Pydantic validation rejections ``error`` is\n``\"invalid_birth_input\"`` and ``field`` (optional) names the\noffending field.\n\nFor engine dependency failures ``error`` is one of:\n\n* ``deterministic_dependency_missing``\n* ``ephemeris_missing``\n* ``ephemeris_load_error``\n* ``invalid_birth_input``\n\nFor truth-input failures ``error`` is ``\"compatibility_input_error\"``\nand ``field`` (optional) names the offending field. The\ncompatibility engine itself does not raise on degenerate\ninputs (it degrades gracefully), so this code path is reserved\nfor the API layer's pre-flight validation."
      },
      "CompatibilityFlagContext": {
        "properties": {
          "signal": {
            "type": "string",
            "maxLength": 160,
            "title": "Signal",
            "default": "Unknown"
          },
          "severity": {
            "type": "string",
            "maxLength": 40,
            "title": "Severity",
            "default": "unknown"
          },
          "explanation": {
            "type": "string",
            "maxLength": 1000,
            "title": "Explanation",
            "default": ""
          }
        },
        "type": "object",
        "title": "CompatibilityFlagContext"
      },
      "CompatibilityFollowUpContext-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-followup-1.0.0"
          },
          "scenarios": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityFollowUpScenarioSummary-Input"
            },
            "type": "array",
            "title": "Scenarios",
            "description": "Compact scenario summaries. Empty list when the artifact was saved without authored scenarios."
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/app__schemas__compatibility__ScenarioAnswer"
            },
            "type": "array",
            "title": "Answers",
            "description": "Selected scenario answers. Each ``scenario_id`` MUST match an id in ``scenarios`` when both lists are non-empty."
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern",
            "description": "Original user concern from the report generation flow. None when the caller did not supply one."
          },
          "scenario_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scenario Ids",
            "description": "Derived view: the id list of ``scenarios``. Stable across calls so a renderer can use it as a cache key."
          },
          "evidence_refs": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Evidence Refs",
            "description": "Derived view: union of source signal ids and matrix cell refs from every scenario's evidence block. Stable across calls so a renderer can cross-reference the same refs back to the authoritative scoring cells."
          },
          "has_continuity": {
            "type": "boolean",
            "title": "Has Continuity",
            "description": "True when at least one of scenarios / answers is non-empty AND (user_concern is set OR a scenario carries evidence refs). False otherwise.",
            "default": false
          }
        },
        "type": "object",
        "title": "CompatibilityFollowUpContext",
        "description": "Persisted compatibility follow-up context.\n\nField-by-field invariants:\n\n* ``schema_version`` is the constant\n  :data:`COMPATIBILITY_FOLLOWUP_SCHEMA_VERSION`. Bump on\n  any breaking change to this block.\n* ``scenarios`` is the compact summary list. Empty list\n  when the artifact was saved without authored scenarios\n  (e.g. a legacy save that pre-dates M006 S03 T01, or a\n  save from a caller that did not author scenarios).\n* ``answers`` is the list of selected scenario answers.\n  Each ``scenario_id`` MUST match an id in ``scenarios``\n  when both lists are non-empty \u2014 a chat renderer that\n  cannot match the answer to a scenario surfaces the\n  answer as orphaned and asks the user to re-answer.\n* ``user_concern`` is the original user concern from the\n  report-generation flow. None when the caller did not\n  supply one.\n* ``scenario_ids`` and ``evidence_refs`` are derived\n  views: ``scenario_ids`` mirrors the id list; ``evidence_refs``\n  is the union of source signal ids and matrix cell refs\n  from every scenario's evidence block. A chat handoff\n  can iterate these without re-parsing the full scenario\n  list.\n* ``has_continuity`` is True when at least one of\n  ``scenarios`` / ``answers`` is non-empty AND\n  ``user_concern`` is set OR a scenario carries evidence\n  refs. False otherwise \u2014 the reopen layer surfaces an\n  honest \"no follow-up context saved\" affordance."
      },
      "CompatibilityFollowUpContext-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-followup-1.0.0"
          },
          "scenarios": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityFollowUpScenarioSummary-Output"
            },
            "type": "array",
            "title": "Scenarios",
            "description": "Compact scenario summaries. Empty list when the artifact was saved without authored scenarios."
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/app__schemas__compatibility__ScenarioAnswer"
            },
            "type": "array",
            "title": "Answers",
            "description": "Selected scenario answers. Each ``scenario_id`` MUST match an id in ``scenarios`` when both lists are non-empty."
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern",
            "description": "Original user concern from the report generation flow. None when the caller did not supply one."
          },
          "scenario_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scenario Ids",
            "description": "Derived view: the id list of ``scenarios``. Stable across calls so a renderer can use it as a cache key."
          },
          "evidence_refs": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Evidence Refs",
            "description": "Derived view: union of source signal ids and matrix cell refs from every scenario's evidence block. Stable across calls so a renderer can cross-reference the same refs back to the authoritative scoring cells."
          },
          "has_continuity": {
            "type": "boolean",
            "title": "Has Continuity",
            "description": "True when at least one of scenarios / answers is non-empty AND (user_concern is set OR a scenario carries evidence refs). False otherwise.",
            "default": false
          }
        },
        "type": "object",
        "title": "CompatibilityFollowUpContext",
        "description": "Persisted compatibility follow-up context.\n\nField-by-field invariants:\n\n* ``schema_version`` is the constant\n  :data:`COMPATIBILITY_FOLLOWUP_SCHEMA_VERSION`. Bump on\n  any breaking change to this block.\n* ``scenarios`` is the compact summary list. Empty list\n  when the artifact was saved without authored scenarios\n  (e.g. a legacy save that pre-dates M006 S03 T01, or a\n  save from a caller that did not author scenarios).\n* ``answers`` is the list of selected scenario answers.\n  Each ``scenario_id`` MUST match an id in ``scenarios``\n  when both lists are non-empty \u2014 a chat renderer that\n  cannot match the answer to a scenario surfaces the\n  answer as orphaned and asks the user to re-answer.\n* ``user_concern`` is the original user concern from the\n  report-generation flow. None when the caller did not\n  supply one.\n* ``scenario_ids`` and ``evidence_refs`` are derived\n  views: ``scenario_ids`` mirrors the id list; ``evidence_refs``\n  is the union of source signal ids and matrix cell refs\n  from every scenario's evidence block. A chat handoff\n  can iterate these without re-parsing the full scenario\n  list.\n* ``has_continuity`` is True when at least one of\n  ``scenarios`` / ``answers`` is non-empty AND\n  ``user_concern`` is set OR a scenario carries evidence\n  refs. False otherwise \u2014 the reopen layer surfaces an\n  honest \"no follow-up context saved\" affordance."
      },
      "CompatibilityFollowUpScenarioSummary-Input": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable deterministic scenario id. Mirrored verbatim from :class:`DampatyaScenario.id`."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "Scenario title. Mirrored verbatim from :class:`DampatyaScenario.title`."
          },
          "context_label": {
            "type": "string",
            "title": "Context Label",
            "description": "Scenario context label. Mirrored verbatim."
          },
          "evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DampatyaScenarioEvidence"
              },
              {
                "type": "null"
              }
            ],
            "description": "Backend-authored scenario evidence. Mirrored verbatim from :class:`DampatyaScenario.evidence` when present. None for pure user_concern prompts."
          }
        },
        "type": "object",
        "required": [
          "id",
          "title",
          "context_label"
        ],
        "title": "CompatibilityFollowUpScenarioSummary",
        "description": "Compact scenario summary persisted into the follow-up block.\n\nThe summary carries the fields a chat handoff needs to\nre-link the scenario to a deterministic source: the\nstable ``id`` and the backend-authored ``evidence`` block.\nLarge narrative text fields (``story``, ``options``) are\ndropped \u2014 the renderer re-issues the scenarios request to\nrecover the full narrative, then matches the re-issued\nscenarios to the saved ids one-for-one."
      },
      "CompatibilityFollowUpScenarioSummary-Output": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable deterministic scenario id. Mirrored verbatim from :class:`DampatyaScenario.id`."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "Scenario title. Mirrored verbatim from :class:`DampatyaScenario.title`."
          },
          "context_label": {
            "type": "string",
            "title": "Context Label",
            "description": "Scenario context label. Mirrored verbatim."
          },
          "evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DampatyaScenarioEvidence"
              },
              {
                "type": "null"
              }
            ],
            "description": "Backend-authored scenario evidence. Mirrored verbatim from :class:`DampatyaScenario.evidence` when present. None for pure user_concern prompts."
          }
        },
        "type": "object",
        "required": [
          "id",
          "title",
          "context_label"
        ],
        "title": "CompatibilityFollowUpScenarioSummary",
        "description": "Compact scenario summary persisted into the follow-up block.\n\nThe summary carries the fields a chat handoff needs to\nre-link the scenario to a deterministic source: the\nstable ``id`` and the backend-authored ``evidence`` block.\nLarge narrative text fields (``story``, ``options``) are\ndropped \u2014 the renderer re-issues the scenarios request to\nrecover the full narrative, then matches the re-issued\nscenarios to the saved ids one-for-one."
      },
      "CompatibilityHistoryErrorResponse": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          },
          "retryable": {
            "type": "boolean",
            "title": "Retryable",
            "description": "True when the failure is a transient backend condition the caller can retry (e.g. persistence outage). False for terminal failures (not found, invalid request) the caller should not retry.",
            "default": false
          },
          "partial_state": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Partial State",
            "description": "Honest, safe-to-share context that was available at the failure boundary (user id, session id, artifact id when known, schema version, and any continuity / handoff markers visible before the failure). Never includes DB internals or raw exception traces. None when no safe context exists."
          }
        },
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "title": "CompatibilityHistoryErrorResponse",
        "description": "Typed error envelope for the compatibility-history API.\n\nMirrors :class:`CompatibilityErrorResponse` so the two\ncompatibility surfaces share a single error shape. ``field``\nis included only when the failure names a specific field\n(e.g. Pydantic validation rejections).\n\nS04 adds two additive fields so the wire contract is\nmachine-diagnosable without DB inspection:\n\n* ``retryable`` distinguishes transient persistence\n  failures (HTTP 503, ``retryable=True``) from terminal\n  failures (HTTP 404 not found, HTTP 422 invalid request,\n  ``retryable=False``). A renderer can show a \"retry\"\n  affordance for ``retryable=True`` and an explicit\n  \"this won't change on retry\" affordance for\n  ``retryable=False``.\n* ``partial_state`` carries the honest, safe-to-share\n  context the service had at the failure boundary:\n  user id, session id, artifact id (when known), the\n  history schema version, and any continuity / handoff\n  markers that were visible before the failure\n  (``has_sections``, ``has_followup``). The block never\n  includes DB internals, raw exception traces, or\n  anything that would leak across user boundaries. A\n  renderer can echo this back in the browser-visible\n  degradation state so a maintainer (or the user) can\n  confirm what context the request was in without\n  re-running the request."
      },
      "CompatibilityLayerContext": {
        "properties": {
          "layer": {
            "type": "string",
            "maxLength": 120,
            "title": "Layer",
            "default": "Unknown"
          },
          "points": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Points"
          },
          "maximum_points": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Maximum Points"
          },
          "rationale": {
            "type": "string",
            "maxLength": 1000,
            "title": "Rationale",
            "default": ""
          }
        },
        "type": "object",
        "title": "CompatibilityLayerContext"
      },
      "CompatibilityLayerOut": {
        "properties": {
          "layer": {
            "type": "string",
            "title": "Layer"
          },
          "points": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Points",
            "description": "Layer points, always a non-negative Python int."
          },
          "maximum_points": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Maximum Points",
            "description": "Maximum possible points for this layer."
          },
          "rationale": {
            "type": "string",
            "title": "Rationale",
            "description": "One-line human-readable rationale. Render verbatim."
          }
        },
        "type": "object",
        "required": [
          "layer",
          "points",
          "maximum_points",
          "rationale"
        ],
        "title": "CompatibilityLayerOut",
        "description": "A single scoring layer in the compatibility breakdown.\n\n``points`` is always a non-negative Python ``int`` clamped to\n``[0, maximum_points]``. ``rationale`` is a one-line human-\nreadable explanation rendered verbatim by the transport layer."
      },
      "CompatibilityRedFlagOut": {
        "properties": {
          "signal": {
            "$ref": "#/components/schemas/RedFlagSignal"
          },
          "severity": {
            "$ref": "#/components/schemas/RedFlagSeverity"
          },
          "explanation": {
            "type": "string",
            "title": "Explanation",
            "description": "One-line human-readable explanation. Render verbatim; do not re-derive the rationale from the signal."
          }
        },
        "type": "object",
        "required": [
          "signal",
          "severity",
          "explanation"
        ],
        "title": "CompatibilityRedFlagOut",
        "description": "A first-class explainability signal in the compatibility report.\n\nRed flags are not score-bearing. They are explicit reasons the\ncaller might want to read the chart pair in fuller context."
      },
      "CompatibilityReport-Input": {
        "properties": {
          "person1_input": {
            "type": "object",
            "title": "Person1 Input",
            "description": "Echo of person 1's normalized birth input. Round-trips through BirthInput.to_dict() unchanged."
          },
          "person2_input": {
            "type": "object",
            "title": "Person2 Input",
            "description": "Echo of person 2's normalized birth input."
          },
          "total_score": {
            "type": "integer",
            "maximum": 36.0,
            "minimum": 0.0,
            "title": "Total Score",
            "description": "Composite compatibility score, clamped to [0, maximum_score]. Always a non-negative Python int."
          },
          "maximum_score": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Maximum Score",
            "description": "Maximum possible score. The legacy 36 keeps the v1 contract stable for existing clients.",
            "default": 36
          },
          "recommendation": {
            "type": "string",
            "title": "Recommendation",
            "description": "Single-sentence human-readable recommendation. Render verbatim; do not paraphrase."
          },
          "recommendation_tier": {
            "$ref": "#/components/schemas/RecommendationTier"
          },
          "layer_scores": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityLayerOut"
            },
            "type": "array",
            "title": "Layer Scores",
            "description": "Per-layer scoring breakdown. Exactly one entry per LayerName, in canonical order."
          },
          "doshas": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityDoshaOut"
            },
            "type": "array",
            "title": "Doshas",
            "description": "Classical dosha signals. Always contains at least the Kuja dosha entry."
          },
          "red_flags": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityRedFlagOut"
            },
            "type": "array",
            "title": "Red Flags",
            "description": "First-class explainability signals. Empty list is permitted; the field is never null."
          },
          "element_fit": {
            "$ref": "#/components/schemas/CompatibilityElementFitOut"
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/app__schemas__compatibility__InterpretationStatus",
            "description": "Honest disclosure of narrative interpretation availability. Always 'unavailable' in M004 S01.",
            "default": "unavailable"
          },
          "interpretation_source": {
            "type": "string",
            "title": "Interpretation Source",
            "description": "Provenance of the interpretation layer. 'none' in M004 S01; 'minimax_m3' once the narrative slice ships.",
            "default": "none"
          },
          "interpretation_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interpretation Reason",
            "description": "Short machine-readable reason when the interpretation slot is degraded. None in M004 S01."
          },
          "interpretation_text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interpretation Text",
            "description": "The synthesized LLM report narrative."
          },
          "degradation_reasons": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Degradation Reasons",
            "description": "Short machine-readable reasons the deterministic truth was computed in a degraded mode (e.g. 'person1_mars_missing'). Empty list when the truth is complete."
          },
          "metadata": {
            "$ref": "#/components/schemas/CompatibilityEngineMetadataOut"
          },
          "confidence": {
            "$ref": "#/components/schemas/app__schemas__compatibility__InputConfidenceOut"
          }
        },
        "type": "object",
        "required": [
          "person1_input",
          "person2_input",
          "total_score",
          "recommendation",
          "recommendation_tier",
          "layer_scores",
          "doshas",
          "element_fit",
          "metadata",
          "confidence"
        ],
        "title": "CompatibilityReport",
        "description": "Authoritative two-person compatibility payload.\n\nField set matches\n:class:`app.domain.astrology.compatibility.CompatibilityTruth`\nexactly so the engine's ``to_dict()`` output passes through this\nschema without lossy translation.\n\nInvariants:\n\n* ``total_score`` is a non-negative Python ``int`` clamped to\n  ``[0, maximum_score]``.\n* ``recommendation_tier`` is one of the closed literals\n  (:class:`RecommendationTier`).\n* ``layer_scores`` always contains exactly one entry per\n  :class:`LayerName`, in canonical order.\n* ``doshas`` always contains at least the Kuja dosha entry.\n* ``red_flags`` is a list (possibly empty), never ``None``.\n* ``interpretation_status`` is always ``unavailable`` in this\n  release; the field is included now so the transport contract\n  is stable when the narrative layer ships."
      },
      "CompatibilityReport-Output": {
        "properties": {
          "person1_input": {
            "type": "object",
            "title": "Person1 Input",
            "description": "Echo of person 1's normalized birth input. Round-trips through BirthInput.to_dict() unchanged."
          },
          "person2_input": {
            "type": "object",
            "title": "Person2 Input",
            "description": "Echo of person 2's normalized birth input."
          },
          "total_score": {
            "type": "integer",
            "maximum": 36.0,
            "minimum": 0.0,
            "title": "Total Score",
            "description": "Composite compatibility score, clamped to [0, maximum_score]. Always a non-negative Python int."
          },
          "maximum_score": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Maximum Score",
            "description": "Maximum possible score. The legacy 36 keeps the v1 contract stable for existing clients.",
            "default": 36
          },
          "recommendation": {
            "type": "string",
            "title": "Recommendation",
            "description": "Single-sentence human-readable recommendation. Render verbatim; do not paraphrase."
          },
          "recommendation_tier": {
            "$ref": "#/components/schemas/RecommendationTier"
          },
          "layer_scores": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityLayerOut"
            },
            "type": "array",
            "title": "Layer Scores",
            "description": "Per-layer scoring breakdown. Exactly one entry per LayerName, in canonical order."
          },
          "doshas": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityDoshaOut"
            },
            "type": "array",
            "title": "Doshas",
            "description": "Classical dosha signals. Always contains at least the Kuja dosha entry."
          },
          "red_flags": {
            "items": {
              "$ref": "#/components/schemas/CompatibilityRedFlagOut"
            },
            "type": "array",
            "title": "Red Flags",
            "description": "First-class explainability signals. Empty list is permitted; the field is never null."
          },
          "element_fit": {
            "$ref": "#/components/schemas/CompatibilityElementFitOut"
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/app__schemas__compatibility__InterpretationStatus",
            "description": "Honest disclosure of narrative interpretation availability. Always 'unavailable' in M004 S01.",
            "default": "unavailable"
          },
          "interpretation_source": {
            "type": "string",
            "title": "Interpretation Source",
            "description": "Provenance of the interpretation layer. 'none' in M004 S01; 'minimax_m3' once the narrative slice ships.",
            "default": "none"
          },
          "interpretation_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interpretation Reason",
            "description": "Short machine-readable reason when the interpretation slot is degraded. None in M004 S01."
          },
          "interpretation_text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interpretation Text",
            "description": "The synthesized LLM report narrative."
          },
          "degradation_reasons": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Degradation Reasons",
            "description": "Short machine-readable reasons the deterministic truth was computed in a degraded mode (e.g. 'person1_mars_missing'). Empty list when the truth is complete."
          },
          "metadata": {
            "$ref": "#/components/schemas/CompatibilityEngineMetadataOut"
          },
          "confidence": {
            "$ref": "#/components/schemas/app__schemas__compatibility__InputConfidenceOut"
          }
        },
        "type": "object",
        "required": [
          "person1_input",
          "person2_input",
          "total_score",
          "recommendation",
          "recommendation_tier",
          "layer_scores",
          "doshas",
          "element_fit",
          "metadata",
          "confidence"
        ],
        "title": "CompatibilityReport",
        "description": "Authoritative two-person compatibility payload.\n\nField set matches\n:class:`app.domain.astrology.compatibility.CompatibilityTruth`\nexactly so the engine's ``to_dict()`` output passes through this\nschema without lossy translation.\n\nInvariants:\n\n* ``total_score`` is a non-negative Python ``int`` clamped to\n  ``[0, maximum_score]``.\n* ``recommendation_tier`` is one of the closed literals\n  (:class:`RecommendationTier`).\n* ``layer_scores`` always contains exactly one entry per\n  :class:`LayerName`, in canonical order.\n* ``doshas`` always contains at least the Kuja dosha entry.\n* ``red_flags`` is a list (possibly empty), never ``None``.\n* ``interpretation_status`` is always ``unavailable`` in this\n  release; the field is included now so the transport contract\n  is stable when the narrative layer ships."
      },
      "CompatibilityReportResponse-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-1.0.0"
          },
          "report": {
            "$ref": "#/components/schemas/CompatibilityReport-Input"
          },
          "sections": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SectionedCompatibilityReport-Input"
              },
              {
                "type": "null"
              }
            ],
            "description": "Sectioned trust-first contract. Carries the computed truth verbatim plus derived scaffolding, the AI-authored narrative slot, and explicit confidence / degradation / trust markers. Optional for backward compat with callers that only carry the flat report; the v2 route always populates this field on a freshly served response."
          },
          "behavioral_evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralEvidenceBlock"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional behavioral evidence summary (V2-S08). Contains a Behavioral Fit note, an Accuracy Confidence label, and practical Questions to Ask Partner when behavioral or scenario evidence was supplied."
          }
        },
        "type": "object",
        "required": [
          "report"
        ],
        "title": "CompatibilityReportResponse",
        "description": "v2 compatibility response wrapper around the authoritative\nengine report.\n\nThe ``schema_version`` constant is exposed on the wire so a\nclient can compare it for cache invalidation. Bump\n:data:`COMPATIBILITY_SCHEMA_VERSION` on any breaking change to\n:class:`CompatibilityReport` or its nested blocks.\n\nThe ``sections`` field (added in M006 S01 T01) carries the\nsectioned trust-first contract alongside the flat\n:class:`CompatibilityReport`. The two are guaranteed\nbyte-comparable: ``sections.computed_truth.payload`` is the\nsame object the route returns as ``report``. The flat\n``report`` field is preserved for callers that already parse\nit; the ``sections`` field is the canonical shape for\ntrust-first rendering. Bump\n:data:`COMPATIBILITY_SECTIONED_SCHEMA_VERSION` on any\nbreaking change to :class:`SectionedCompatibilityReport` or\nits nested blocks."
      },
      "CompatibilityReportResponse-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-1.0.0"
          },
          "report": {
            "$ref": "#/components/schemas/CompatibilityReport-Output"
          },
          "sections": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SectionedCompatibilityReport-Output"
              },
              {
                "type": "null"
              }
            ],
            "description": "Sectioned trust-first contract. Carries the computed truth verbatim plus derived scaffolding, the AI-authored narrative slot, and explicit confidence / degradation / trust markers. Optional for backward compat with callers that only carry the flat report; the v2 route always populates this field on a freshly served response."
          },
          "behavioral_evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralEvidenceBlock"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional behavioral evidence summary (V2-S08). Contains a Behavioral Fit note, an Accuracy Confidence label, and practical Questions to Ask Partner when behavioral or scenario evidence was supplied."
          }
        },
        "type": "object",
        "required": [
          "report"
        ],
        "title": "CompatibilityReportResponse",
        "description": "v2 compatibility response wrapper around the authoritative\nengine report.\n\nThe ``schema_version`` constant is exposed on the wire so a\nclient can compare it for cache invalidation. Bump\n:data:`COMPATIBILITY_SCHEMA_VERSION` on any breaking change to\n:class:`CompatibilityReport` or its nested blocks.\n\nThe ``sections`` field (added in M006 S01 T01) carries the\nsectioned trust-first contract alongside the flat\n:class:`CompatibilityReport`. The two are guaranteed\nbyte-comparable: ``sections.computed_truth.payload`` is the\nsame object the route returns as ``report``. The flat\n``report`` field is preserved for callers that already parse\nit; the ``sections`` field is the canonical shape for\ntrust-first rendering. Bump\n:data:`COMPATIBILITY_SECTIONED_SCHEMA_VERSION` on any\nbreaking change to :class:`SectionedCompatibilityReport` or\nits nested blocks."
      },
      "CompatibilityReportWithAnswersRequest": {
        "properties": {
          "person1": {
            "$ref": "#/components/schemas/CompatibilityBirthInput"
          },
          "person2": {
            "$ref": "#/components/schemas/CompatibilityBirthInput"
          },
          "person1_culture": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CulturalContext"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cultural orientation for person 1. When omitted, the narrative slot is honestly emitted as unavailable."
          },
          "person2_culture": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CulturalContext"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cultural orientation for person 2. When omitted, the narrative slot is honestly emitted as unavailable."
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/app__schemas__compatibility__ScenarioAnswer"
            },
            "type": "array",
            "title": "Answers",
            "description": "Scenario answers for the Dampatya synthesis. When empty, the narrative slot is honestly emitted as unavailable even if culture is provided."
          },
          "scenarios": {
            "items": {
              "$ref": "#/components/schemas/DampatyaScenario-Input"
            },
            "type": "array",
            "title": "Scenarios",
            "description": "Generated scenarios the answers refer to. Optional; the route accepts an empty list when answers are provided without the original scenarios payload."
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern",
            "description": "Optional user concern to address directly in the relationship synthesis report. Ignored when the narrative slot is unavailable."
          },
          "relationship_stage": {
            "type": "string",
            "enum": [
              "prospective",
              "married"
            ],
            "title": "Relationship Stage",
            "description": "The couple's relationship stage, passed through to the LLM synthesis so the narrative is framed for the correct life context.",
            "default": "prospective"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "description": "Preferred language for the AI-authored relationship synthesis.",
            "default": "english"
          },
          "behavioral_profile_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Behavioral Profile Id",
            "description": "Optional saved BehavioralProfileSummary id (V2-S08). When present, the synthesis folds the user's behavioral evidence into the narrative and surfaces a Behavioral Fit note. Ignored when the narrative slot is unavailable."
          },
          "behavioral_chat_context": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Behavioral Chat Context",
            "description": "Optional compact behavioral chat-context summary (V2-S08) derived from the saved BehavioralProfileSummary. Contains only everyday-language summaries and confidence notes \u2014 never raw answers. Injected into the LLM prompt when the narrative slot is available."
          },
          "behavioral_action_plan": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Behavioral Action Plan",
            "description": "Optional serialized BehavioralActionPlan (evalution.md Phase 3) from the saved behavioral profile. When present, the compatibility route enriches the BehavioralEvidenceBlock with relationship_impact, watchouts, joint_practices, and evidence_used derived from the plan. Passed as a loose dict so the compatibility schema does not import the behavioral assessment schema."
          }
        },
        "type": "object",
        "required": [
          "person1",
          "person2"
        ],
        "title": "CompatibilityReportWithAnswersRequest",
        "description": "Request body for generating the final report, including scenario answers.\n\nAll scenario-related fields are **optional**. The v2 route accepts\neither the bare two-person compatibility request or a fully-\npopulated cultural-context request:\n\n* Bare request (``person1`` + ``person2`` only) - the route emits\n  the deterministic truth with the narrative slot honestly\n  :data:`InterpretationStatus.UNAVAILABLE`. This is the contract\n  pinned by M004 S01 T02 (``test_interpretation_status_is_unavailable_in_this_slice``).\n* Cultural-context request - when BOTH ``person1_culture`` and\n  ``person2_culture`` are provided AND ``answers`` is non-empty,\n  the route MAY call the LLM synthesis to fill the narrative\n  slot. A failed synthesis still returns the deterministic truth\n  with the narrative slot marked :data:`InterpretationStatus.PARTIAL`.\n\nThis additive shape preserves the byte-comparable deterministic\nsurface for existing callers while letting the sectioned contract\nsurface honesty about narrative availability - introduced in\nM006 S01 T01."
      },
      "CompatibilityRequest": {
        "properties": {
          "person1": {
            "$ref": "#/components/schemas/KundliBirthInput"
          },
          "person2": {
            "$ref": "#/components/schemas/KundliBirthInput"
          }
        },
        "type": "object",
        "required": [
          "person1",
          "person2"
        ],
        "title": "CompatibilityRequest",
        "description": "Request for compatibility matching."
      },
      "CompatibilityScenarioSignalContext": {
        "properties": {
          "scenario_id": {
            "type": "string",
            "maxLength": 160,
            "title": "Scenario Id",
            "default": ""
          },
          "title": {
            "type": "string",
            "maxLength": 300,
            "title": "Title",
            "default": ""
          },
          "chosen_response": {
            "type": "string",
            "maxLength": 500,
            "title": "Chosen Response",
            "default": ""
          },
          "theme": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Theme"
          },
          "grounding_state": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Grounding State"
          },
          "grounding_reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Grounding Reason"
          },
          "signal_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 12,
            "title": "Signal Ids"
          },
          "cell_refs": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 12,
            "title": "Cell Refs"
          },
          "derived_score_delta": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Derived Score Delta"
          }
        },
        "type": "object",
        "title": "CompatibilityScenarioSignalContext"
      },
      "CompatibilityScenariosRequest": {
        "properties": {
          "person1": {
            "$ref": "#/components/schemas/CompatibilityBirthInput"
          },
          "person1_culture": {
            "$ref": "#/components/schemas/CulturalContext"
          },
          "person2": {
            "$ref": "#/components/schemas/CompatibilityBirthInput"
          },
          "person2_culture": {
            "$ref": "#/components/schemas/CulturalContext"
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern",
            "description": "Optional user-provided concern to generate specific scenarios for."
          },
          "relationship_stage": {
            "type": "string",
            "enum": [
              "prospective",
              "married"
            ],
            "title": "Relationship Stage",
            "description": "The couple's relationship stage. 'prospective' frames scenarios for a to-be-married couple evaluating each other (pre-wedding, engagement, wedding planning). 'married' frames scenarios for an already-wedded couple navigating married life.",
            "default": "prospective"
          },
          "scenario_phase": {
            "type": "string",
            "enum": [
              "self",
              "partner"
            ],
            "title": "Scenario Phase",
            "description": "Which perspective the scenarios should ask from. 'self' \u2014 Person 1 answers about their OWN likely behaviour (SJT-style, designed to reveal actual behaviour rather than aspirational self-image). 'partner' \u2014 Person 1 answers about Person 2's likely behaviour (their observation/read of the partner). The two-phase flow calls this endpoint twice: first with 'self', then with 'partner'.",
            "default": "partner"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "description": "Language the scenarios should be generated in.",
            "default": "english"
          }
        },
        "type": "object",
        "required": [
          "person1",
          "person1_culture",
          "person2",
          "person2_culture"
        ],
        "title": "CompatibilityScenariosRequest",
        "description": "Request body to generate scenarios."
      },
      "CompatibilityScenariosResponse": {
        "properties": {
          "scenarios": {
            "items": {
              "$ref": "#/components/schemas/DampatyaScenario-Output"
            },
            "type": "array",
            "title": "Scenarios"
          },
          "degraded": {
            "type": "boolean",
            "title": "Degraded",
            "default": false
          },
          "degradation_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Degradation Reason"
          }
        },
        "type": "object",
        "required": [
          "scenarios"
        ],
        "title": "CompatibilityScenariosResponse",
        "description": "Response containing the generated scenarios.\n\n``degraded`` is ``True`` when the LLM generation path failed and\nthe engine fell back to the static scenario bank. ``degradation_reason``\ncarries a short, log-correlatable explanation (e.g. ``\"quota_exhausted\"``,\n``\"llm_parse_error\"``, ``\"network_timeout\"``). When ``degraded`` is\n``False`` both fields are absent/``None`` \u2014 the scenarios were freshly\nauthored by the LLM from the chart facts."
      },
      "CompatibilitySectionMarkersContext": {
        "properties": {
          "sectioned_schema_version": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40
              },
              {
                "type": "null"
              }
            ],
            "title": "Sectioned Schema Version"
          },
          "contract_type": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Contract Type"
          },
          "matrix_band": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Matrix Band"
          },
          "matrix_band_label": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 160
              },
              {
                "type": "null"
              }
            ],
            "title": "Matrix Band Label"
          },
          "derived_headline": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Derived Headline"
          },
          "narrative_status": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Narrative Status"
          },
          "narrative_source": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Narrative Source"
          },
          "narrative_text": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 3000
              },
              {
                "type": "null"
              }
            ],
            "title": "Narrative Text"
          },
          "narrative_reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Narrative Reason"
          },
          "confidence_level": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Confidence Level"
          },
          "is_degraded": {
            "type": "boolean",
            "title": "Is Degraded",
            "default": false
          },
          "degradation_reasons": {
            "items": {
              "type": "string",
              "maxLength": 500
            },
            "type": "array",
            "maxItems": 8,
            "title": "Degradation Reasons"
          },
          "interpretation_degraded": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interpretation Degraded"
          },
          "interpretation_reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Interpretation Reason"
          }
        },
        "type": "object",
        "title": "CompatibilitySectionMarkersContext"
      },
      "ConcernAnsweredSummary": {
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "fully",
              "partially",
              "insufficiently"
            ],
            "title": "Status",
            "description": "How well the scenarios addressed the user's concern.",
            "default": "partially"
          },
          "explanation": {
            "type": "string",
            "title": "Explanation",
            "description": "Plain-language explanation of why the concern was fully, partially, or insufficiently tested.",
            "default": ""
          }
        },
        "type": "object",
        "title": "ConcernAnsweredSummary",
        "description": "Whether the user's selected concern was adequately tested.\n\nThe report must explicitly state if the concern was not adequately\ntested, rather than silently producing a score from unrelated\ndimensions."
      },
      "ConsentRequest": {
        "properties": {
          "consent_given": {
            "type": "boolean",
            "title": "Consent Given"
          }
        },
        "type": "object",
        "required": [
          "consent_given"
        ],
        "title": "ConsentRequest"
      },
      "ContractType": {
        "type": "string",
        "enum": [
          "sectioned_trust_first"
        ],
        "const": "sectioned_trust_first",
        "title": "ContractType",
        "description": "Closed literal identifying the contract shape.\n\nPinned so a client can detect a future replacement of the\nsectioned contract by checking ``sections.contract_type``."
      },
      "CoverageMapEntry": {
        "properties": {
          "dimension_key": {
            "type": "string",
            "title": "Dimension Key",
            "description": "Dimension key from the registry."
          },
          "importance": {
            "type": "string",
            "enum": [
              "low",
              "moderate",
              "high"
            ],
            "title": "Importance",
            "description": "How important this dimension is given the charts/context.",
            "default": "moderate"
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Short reason for the importance rating."
          }
        },
        "type": "object",
        "required": [
          "dimension_key"
        ],
        "title": "CoverageMapEntry",
        "description": "One dimension coverage entry."
      },
      "CreateSessionRequest": {
        "properties": {
          "display_name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 2,
            "title": "Display Name"
          },
          "email": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "consent_given": {
            "type": "boolean",
            "title": "Consent Given",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "display_name"
        ],
        "title": "CreateSessionRequest"
      },
      "CulturalContext": {
        "properties": {
          "self_orientation": {
            "type": "string",
            "title": "Self Orientation",
            "default": "unsure"
          },
          "family_orientation": {
            "type": "string",
            "title": "Family Orientation",
            "default": "unknown"
          },
          "decision_style": {
            "type": "string",
            "title": "Decision Style",
            "default": "unsure"
          },
          "living_preference": {
            "type": "string",
            "title": "Living Preference",
            "default": "undecided"
          },
          "career_priority": {
            "type": "string",
            "title": "Career Priority",
            "default": "undecided"
          },
          "ritual_practice": {
            "type": "string",
            "title": "Ritual Practice",
            "default": "mixed"
          },
          "social_boundary_comfort": {
            "type": "string",
            "title": "Social Boundary Comfort",
            "default": ""
          },
          "gender": {
            "type": "string",
            "title": "Gender",
            "description": "Gender of this partner (female / male / other / empty). Used by the Dampatya scenario engine to tailor Indian-context scenario stories and pronouns. Treated as 'unspecified' when empty.",
            "default": ""
          }
        },
        "type": "object",
        "title": "CulturalContext",
        "description": "Cultural orientation factors for one partner."
      },
      "DampatyaScenario-Input": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable deterministic scenario id. Two identical compatibility-truth inputs MUST produce the same id; ids are derived from the theme and the referenced signal ids."
          },
          "title": {
            "type": "string",
            "title": "Title"
          },
          "context_label": {
            "type": "string",
            "title": "Context Label"
          },
          "story": {
            "type": "string",
            "title": "Story"
          },
          "options": {
            "items": {
              "$ref": "#/components/schemas/DampatyaScenarioOption"
            },
            "type": "array",
            "title": "Options"
          },
          "evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DampatyaScenarioEvidence"
              },
              {
                "type": "null"
              }
            ],
            "description": "Backend-authored evidence block. The v2 route always populates this when grounded signals are available. None when the scenario is purely a user_concern prompt with no chart grounding."
          }
        },
        "type": "object",
        "required": [
          "id",
          "title",
          "context_label",
          "story"
        ],
        "title": "DampatyaScenario",
        "description": "A generated scenario question based on astrological themes.\n\nThe ``id`` is a *deterministic* stable handle derived from\nthe scenario's theme and the referenced evidence signals\n(see :class:`DampatyaScenarioEvidence`). Two identical\ncompatibility-truth inputs therefore yield identical scenario\nids \u2014 the renderer can use them as cache keys and the wire\ncontract can guarantee that a repeated generation over the\nsame truth produces the same id set.\n\nThe ``evidence`` field is the backend-authored provenance\nblock. When omitted (e.g. a legacy caller) the scenario\nremains wire-compatible; the v2 route always populates the\nblock when grounded signals are available so the renderer\ncan trust the wire shape."
      },
      "DampatyaScenario-Output": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable deterministic scenario id. Two identical compatibility-truth inputs MUST produce the same id; ids are derived from the theme and the referenced signal ids."
          },
          "title": {
            "type": "string",
            "title": "Title"
          },
          "context_label": {
            "type": "string",
            "title": "Context Label"
          },
          "story": {
            "type": "string",
            "title": "Story"
          },
          "options": {
            "items": {
              "$ref": "#/components/schemas/DampatyaScenarioOption"
            },
            "type": "array",
            "title": "Options"
          },
          "evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DampatyaScenarioEvidence"
              },
              {
                "type": "null"
              }
            ],
            "description": "Backend-authored evidence block. The v2 route always populates this when grounded signals are available. None when the scenario is purely a user_concern prompt with no chart grounding."
          }
        },
        "type": "object",
        "required": [
          "id",
          "title",
          "context_label",
          "story"
        ],
        "title": "DampatyaScenario",
        "description": "A generated scenario question based on astrological themes.\n\nThe ``id`` is a *deterministic* stable handle derived from\nthe scenario's theme and the referenced evidence signals\n(see :class:`DampatyaScenarioEvidence`). Two identical\ncompatibility-truth inputs therefore yield identical scenario\nids \u2014 the renderer can use them as cache keys and the wire\ncontract can guarantee that a repeated generation over the\nsame truth produces the same id set.\n\nThe ``evidence`` field is the backend-authored provenance\nblock. When omitted (e.g. a legacy caller) the scenario\nremains wire-compatible; the v2 route always populates the\nblock when grounded signals are available so the renderer\ncan trust the wire shape."
      },
      "DampatyaScenarioEvidence": {
        "properties": {
          "theme": {
            "type": "string",
            "title": "Theme",
            "description": "Stable theme key the scenario bank defines. Mirrored verbatim from the engine's scenario bank."
          },
          "source_signals": {
            "items": {
              "$ref": "#/components/schemas/SourceSignalRef"
            },
            "type": "array",
            "title": "Source Signals",
            "description": "Deterministic signals the scenario depends on. Empty list only when ``grounding_state == 'absent'``."
          },
          "matrix_cell_refs": {
            "items": {
              "$ref": "#/components/schemas/MatrixCellRef"
            },
            "type": "array",
            "title": "Matrix Cell Refs",
            "description": "Matrix cell references the scenario depends on. Empty when the scenario does not reference a scoring cell."
          },
          "grounding_state": {
            "$ref": "#/components/schemas/GroundingState",
            "description": "Closed-literal grounding state. Computed from the readability of the referenced signals and cells."
          },
          "grounding_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Grounding Reason",
            "description": "Short machine-readable reason when the grounding state is ``partial`` or ``absent``. None when the scenario is fully grounded."
          },
          "derived_score_delta": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Derived Score Delta",
            "description": "Deterministic score contribution of the referenced signals, when computable. None when the signals are not score-bearing or the contribution is uncomputable from the truth alone."
          }
        },
        "type": "object",
        "required": [
          "theme",
          "grounding_state"
        ],
        "title": "DampatyaScenarioEvidence",
        "description": "Backend-authored evidence block for a single Dampatya scenario.\n\nThe block is *server-authored provenance*: every field is a\ndeterministic transformation of the compatibility truth. The\nrenderer MUST treat the block as the authoritative answer to\n\"why did this scenario appear, and is it grounded in real\nchart math?\" rather than guessing from narrative tone.\n\nField-by-field invariants:\n\n* ``theme`` mirrors the scenario bank's theme key\n  (``family_and_household_dharma``, ``temper_and_impulse``,\n  etc.). Render verbatim.\n* ``source_signals`` is a non-empty list of\n  :class:`SourceSignalRef` whenever the scenario is\n  ``grounded`` or ``partial``. When ``grounding_state`` is\n  ``absent`` the list is empty and ``grounding_reason`` is\n  populated.\n* ``matrix_cell_refs`` lists every matrix cell the scenario's\n  narrative references. A scenario may reference none (e.g.\n  a cultural-context scenario that depends purely on\n  ``user_concern``) in which case the list is empty and\n  ``grounding_state`` is honestly ``absent``.\n* ``grounding_state`` is one of the closed literals in\n  :class:`GroundingState`. The state is computed from the\n  readability of the referenced signals and cells, never\n  invented.\n* ``derived_score_delta`` is the deterministic score\n  contribution of the signals the scenario references, when\n  that contribution is computable. ``None`` when the\n  referenced signals are not score-bearing or when the\n  contribution cannot be computed from the truth alone."
      },
      "DampatyaScenarioOption": {
        "properties": {
          "label": {
            "type": "string",
            "title": "Label"
          },
          "text": {
            "type": "string",
            "title": "Text"
          },
          "tradeoff": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tradeoff",
            "description": "Explicit cost/tradeoff for this option (fixpartner.md \u00a72.3). Shown under the option text."
          }
        },
        "type": "object",
        "required": [
          "label",
          "text"
        ],
        "title": "DampatyaScenarioOption",
        "description": "An option for a scenario question.\n\n``tradeoff`` (fixpartner.md \u00a72.3) is an optional explicit\ncost/tradeoff marker shown under the option text so the user\nsees the downside of each choice. The scenario builder\nvalidates that at least 3 of 4 options carry a tradeoff."
      },
      "DashaOut": {
        "properties": {
          "planet": {
            "type": "string",
            "title": "Planet"
          },
          "start": {
            "type": "string",
            "title": "Start"
          },
          "end": {
            "type": "string",
            "title": "End"
          }
        },
        "type": "object",
        "required": [
          "planet",
          "start",
          "end"
        ],
        "title": "DashaOut"
      },
      "DeclaredVsObserved": {
        "properties": {
          "declared": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Declared",
            "description": "Stated intake fields (e.g. decision_style, family_orientation)."
          },
          "observed": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Observed",
            "description": "SJT-derived dimension bands, keyed by dimension_key."
          },
          "gaps": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Gaps",
            "description": "Where declared and observed disagree, so reports can surface contradictions honestly."
          }
        },
        "type": "object",
        "title": "DeclaredVsObserved",
        "description": "Difference between stated intake fields and SJT behavior.\n\nStored separately from inferred behavioral dimensions (R2). The\n``declared`` map mirrors the partner-library / cultural-context\nintake fields; the ``observed`` map mirrors the SJT-derived\ndimensions. ``gaps`` lists where the two disagree so reports can\nsurface contradictions honestly."
      },
      "DeleteAccountResponse": {
        "properties": {
          "deleted": {
            "type": "boolean",
            "title": "Deleted"
          },
          "user_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Id"
          }
        },
        "type": "object",
        "required": [
          "deleted"
        ],
        "title": "DeleteAccountResponse"
      },
      "DependencyHealth": {
        "properties": {
          "skyfield_available": {
            "type": "boolean",
            "title": "Skyfield Available",
            "description": "True when the skyfield package is importable. False means the engine cannot run under any path."
          },
          "ephemeris_path": {
            "type": "string",
            "title": "Ephemeris Path",
            "description": "Path the engine would use to load the ephemeris file. Resolved against the same candidate list the engine uses at import time."
          },
          "ephemeris_exists": {
            "type": "boolean",
            "title": "Ephemeris Exists",
            "description": "True when a file is present at ephemeris_path."
          },
          "ephemeris_loadable": {
            "type": "boolean",
            "title": "Ephemeris Loadable",
            "description": "True when skyfield successfully loaded the file. Always False when skyfield is unavailable, regardless of the on-disk state."
          },
          "engine_name": {
            "type": "string",
            "title": "Engine Name",
            "description": "Stable engine identifier, e.g. 'vedicastro.deterministic_kundli_engine'."
          },
          "engine_version": {
            "type": "string",
            "title": "Engine Version",
            "description": "Engine version string. Bump on breaking deterministic-output changes. Golden fixtures pin the engine version they were captured against."
          },
          "ayanamsa": {
            "type": "string",
            "title": "Ayanamsa",
            "description": "Ayanamsa the engine implements (e.g. 'Lahiri')."
          },
          "house_system": {
            "type": "string",
            "title": "House System",
            "description": "House system the engine implements (e.g. 'Whole Sign')."
          },
          "ephemeris_provider": {
            "type": "string",
            "title": "Ephemeris Provider",
            "description": "Ephemeris provider the engine depends on (e.g. 'JPL DE421')."
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes",
            "description": "Backend-owned human-readable notes about non-critical observations (e.g. deprecation warnings, ephemeris probe failure reason). Empty when every dependency is healthy."
          }
        },
        "type": "object",
        "required": [
          "skyfield_available",
          "ephemeris_path",
          "ephemeris_exists",
          "ephemeris_loadable",
          "engine_name",
          "engine_version",
          "ayanamsa",
          "house_system",
          "ephemeris_provider"
        ],
        "title": "DependencyHealth",
        "description": "Per-component health of the deterministic engine dependency stack.\n\nEvery field is a stable, machine-comparable signal so the admin\nbaseline can be diffed across runs without scraping logs. The\nservice layer fills every field from a real, on-disk probe \u2014 no\nvalue is fabricated."
      },
      "DependencyStatus": {
        "type": "string",
        "enum": [
          "ready",
          "degraded",
          "unavailable"
        ],
        "title": "DependencyStatus",
        "description": "Overall readiness of the deterministic engine dependency stack.\n\n* ``ready``       \u2014 every dependency (skyfield import, ephemeris\n  file present, ephemeris loadable) is healthy. The engine can\n  emit authoritative truth.\n* ``degraded``    \u2014 skyfield is importable AND the ephemeris file\n  is present on disk, but the file could not be loaded (corrupt\n  or wrong format). The engine will fail closed on compute();\n  the admin baseline reports the gap honestly.\n* ``unavailable`` \u2014 a hard dependency is missing (skyfield is not\n  importable, or the ephemeris file is absent from disk). The\n  engine cannot emit authoritative truth under any path."
      },
      "DimensionScore": {
        "properties": {
          "dimension_key": {
            "type": "string",
            "title": "Dimension Key",
            "description": "Dimension key from the registry."
          },
          "band": {
            "type": "string",
            "enum": [
              "low",
              "moderate",
              "high",
              "mixed",
              "unknown"
            ],
            "title": "Band",
            "description": "Qualitative confidence band. Raw numeric scores are never exposed to users (S6).",
            "default": "unknown"
          },
          "dominant_trait": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dominant Trait",
            "description": "Most frequently selected option_trait for this dimension, when one is dominant."
          },
          "confidence": {
            "type": "string",
            "enum": [
              "low",
              "moderate",
              "high"
            ],
            "title": "Confidence",
            "description": "Confidence in the band, derived from sample_count, recency, and consistency.",
            "default": "low"
          },
          "sample_count": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Sample Count",
            "description": "Number of scenario answers contributing to this dimension.",
            "default": 0
          },
          "last_answered_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Answered At",
            "description": "ISO timestamp of the most recent answer for this dimension."
          },
          "contradiction_markers": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Contradiction Markers",
            "description": "Contradiction markers (S3). Example: declared 'very direct' but scenario answers repeatedly choose delay/avoidance."
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "Short everyday-language summary for reports. Says 'your answers suggest' rather than 'you are' (R2).",
            "default": ""
          }
        },
        "type": "object",
        "required": [
          "dimension_key"
        ],
        "title": "DimensionScore",
        "description": "Per-dimension score with confidence and recency metadata.\n\nThe score is a qualitative band string (e.g. 'low', 'moderate',\n'high') \u2014 raw numeric personality scores are never exposed to\nusers (S6). ``sample_count`` and ``recency`` let the scoring model\napply confidence weighting (S2) and recency decay (S4).\n``contradiction_markers`` tracks contradictions instead of\nflattening them (S3)."
      },
      "DodoSubscriptionResponse": {
        "properties": {
          "status": {
            "type": "string",
            "title": "Status"
          },
          "plan": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Plan"
          },
          "recurring_amount": {
            "type": "integer",
            "title": "Recurring Amount"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "next_billing_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Billing Date"
          },
          "cancel_at_next_billing_date": {
            "type": "boolean",
            "title": "Cancel At Next Billing Date"
          },
          "auto_renew": {
            "type": "boolean",
            "title": "Auto Renew"
          },
          "payment_frequency_count": {
            "type": "integer",
            "title": "Payment Frequency Count"
          },
          "payment_frequency_interval": {
            "type": "string",
            "title": "Payment Frequency Interval"
          },
          "provider_environment": {
            "type": "string",
            "title": "Provider Environment"
          },
          "scheduled_plan": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scheduled Plan"
          }
        },
        "type": "object",
        "required": [
          "status",
          "recurring_amount",
          "currency",
          "cancel_at_next_billing_date",
          "auto_renew",
          "payment_frequency_count",
          "payment_frequency_interval",
          "provider_environment"
        ],
        "title": "DodoSubscriptionResponse"
      },
      "DodoWebhookResponse": {
        "properties": {
          "received": {
            "type": "boolean",
            "title": "Received",
            "default": true
          },
          "duplicate": {
            "type": "boolean",
            "title": "Duplicate",
            "default": false
          },
          "event_type": {
            "type": "string",
            "title": "Event Type"
          }
        },
        "type": "object",
        "required": [
          "event_type"
        ],
        "title": "DodoWebhookResponse"
      },
      "DoshaRequest": {
        "properties": {
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "DD/MM/YYYY"
          },
          "birth_time": {
            "type": "string",
            "title": "Birth Time",
            "description": "HH:MM"
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude"
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude"
          },
          "timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -14.0,
            "title": "Timezone Offset",
            "description": "Timezone offset supplied by the selected place."
          },
          "timezone_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Id"
          }
        },
        "type": "object",
        "required": [
          "birth_date",
          "birth_time",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "DoshaRequest"
      },
      "DoshaResponse": {
        "properties": {
          "manglik_dosha": {
            "type": "object",
            "title": "Manglik Dosha"
          },
          "kaal_sarp_dosha": {
            "type": "object",
            "title": "Kaal Sarp Dosha"
          },
          "pitra_dosha": {
            "type": "object",
            "title": "Pitra Dosha"
          },
          "remedies": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Remedies"
          },
          "disclaimer": {
            "type": "string",
            "title": "Disclaimer"
          }
        },
        "type": "object",
        "required": [
          "manglik_dosha",
          "kaal_sarp_dosha",
          "pitra_dosha",
          "remedies",
          "disclaimer"
        ],
        "title": "DoshaResponse"
      },
      "DoshaSeverity": {
        "type": "string",
        "enum": [
          "none",
          "balanced",
          "mismatched",
          "absent"
        ],
        "title": "DoshaSeverity",
        "description": "Closed literal for the Kuja dosha severity field.\n\n* ``none``       - Mars sits in non-trigger houses on both sides;\n  no dosha is indicated for the pair.\n* ``balanced``   - Mars is in a trigger house on *both* sides; the\n  dosha balances across the pair, no penalty applied.\n* ``mismatched`` - Mars is in a trigger house on *one* side only;\n  a -4 adjustment is applied.\n* ``absent``     - Mars could not be read on at least one side;\n  the review is reported as absent (graceful degradation)."
      },
      "DyadicResponseSubmission": {
        "properties": {
          "dyad_token": {
            "type": "string",
            "title": "Dyad Token"
          },
          "participant_token": {
            "type": "string",
            "title": "Participant Token"
          },
          "respondent_role": {
            "type": "string",
            "enum": [
              "person1",
              "person2"
            ],
            "title": "Respondent Role"
          },
          "item_id": {
            "type": "string",
            "title": "Item Id"
          },
          "item_version": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Item Version"
          },
          "selected_option": {
            "type": "string",
            "title": "Selected Option"
          },
          "response_ms": {
            "type": "integer",
            "maximum": 7200000.0,
            "minimum": 100.0,
            "title": "Response Ms"
          },
          "independent_confirmation": {
            "type": "boolean",
            "title": "Independent Confirmation"
          },
          "evidence_source": {
            "type": "string",
            "enum": [
              "direct_self_report"
            ],
            "const": "direct_self_report",
            "title": "Evidence Source",
            "default": "direct_self_report"
          },
          "strata": {
            "$ref": "#/components/schemas/ParticipantStrata"
          },
          "consent_version": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Consent Version"
          },
          "wave": {
            "type": "integer",
            "maximum": 20.0,
            "minimum": 1.0,
            "title": "Wave",
            "default": 1
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "dyad_token",
          "participant_token",
          "respondent_role",
          "item_id",
          "item_version",
          "selected_option",
          "response_ms",
          "independent_confirmation",
          "strata",
          "consent_version"
        ],
        "title": "DyadicResponseSubmission"
      },
      "ElementRelationship": {
        "type": "string",
        "enum": [
          "same",
          "supporting",
          "clashing",
          "unknown"
        ],
        "title": "ElementRelationship",
        "description": "Closed literal for the element-fit relationship field."
      },
      "EmailCheckRequest": {
        "properties": {
          "email": {
            "type": "string",
            "maxLength": 254,
            "minLength": 3,
            "title": "Email"
          }
        },
        "type": "object",
        "required": [
          "email"
        ],
        "title": "EmailCheckRequest"
      },
      "EmailCheckResponse": {
        "properties": {
          "is_valid": {
            "type": "boolean",
            "title": "Is Valid"
          },
          "is_disposable": {
            "type": "boolean",
            "title": "Is Disposable"
          },
          "domain": {
            "type": "string",
            "title": "Domain"
          },
          "reason": {
            "type": "string",
            "title": "Reason"
          }
        },
        "type": "object",
        "required": [
          "is_valid",
          "is_disposable",
          "domain",
          "reason"
        ],
        "title": "EmailCheckResponse"
      },
      "EngineMetadataOut": {
        "properties": {
          "engine_name": {
            "type": "string",
            "title": "Engine Name"
          },
          "engine_version": {
            "type": "string",
            "title": "Engine Version"
          },
          "engine_implementation": {
            "type": "string",
            "title": "Engine Implementation"
          },
          "zodiac_type": {
            "type": "string",
            "title": "Zodiac Type",
            "default": "Sidereal"
          },
          "ayanamsa": {
            "type": "string",
            "title": "Ayanamsa"
          },
          "ayanamsa_value_degrees": {
            "type": "number",
            "title": "Ayanamsa Value Degrees"
          },
          "house_system": {
            "type": "string",
            "title": "House System"
          },
          "bhava_method": {
            "type": "string",
            "title": "Bhava Method",
            "default": "Whole Sign"
          },
          "node_type": {
            "type": "string",
            "title": "Node Type",
            "default": "MeanNodes"
          },
          "delta_t_model": {
            "type": "string",
            "title": "Delta T Model",
            "default": "NASA_Eclipse"
          },
          "timezone_db_version": {
            "type": "string",
            "title": "Timezone Db Version",
            "default": "tzdata_latest"
          },
          "geocoder_version": {
            "type": "string",
            "title": "Geocoder Version",
            "default": "internal"
          },
          "coordinate_source": {
            "type": "string",
            "title": "Coordinate Source",
            "default": "user_input"
          },
          "ephemeris_provider": {
            "type": "string",
            "title": "Ephemeris Provider"
          },
          "ephemeris_path": {
            "type": "string",
            "title": "Ephemeris Path"
          },
          "generated_at": {
            "type": "string",
            "title": "Generated At"
          },
          "determinism_guarantee": {
            "type": "string",
            "title": "Determinism Guarantee"
          }
        },
        "type": "object",
        "required": [
          "engine_name",
          "engine_version",
          "engine_implementation",
          "ayanamsa",
          "ayanamsa_value_degrees",
          "house_system",
          "ephemeris_provider",
          "ephemeris_path",
          "generated_at",
          "determinism_guarantee"
        ],
        "title": "EngineMetadataOut"
      },
      "ErrorResponse": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          }
        },
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "title": "ErrorResponse",
        "description": "Single typed error envelope for the v1 and v2 API.\n\nBoth Pydantic :class:`RequestValidationError` rejections and\nengine :class:`DeterministicEngineError` failures are translated\ninto this shape so the client sees a stable contract.\n\nFor validation rejections ``error`` is ``\"invalid_birth_input\"``\nand ``field`` (optional) names the offending field.\n\nFor engine dependency failures ``error`` is one of:\n\n* ``deterministic_dependency_missing`` (skyfield not importable)\n* ``ephemeris_missing`` (DE421 file not found)\n* ``ephemeris_load_error`` (DE421 file corrupt or unreadable)"
      },
      "EventRecord": {
        "properties": {
          "event_id": {
            "type": "string",
            "title": "Event Id"
          },
          "study_id": {
            "type": "string",
            "title": "Study Id"
          },
          "event_type": {
            "type": "string",
            "enum": [
              "expert_review",
              "cognitive_interview",
              "pilot_response",
              "dyadic_response",
              "longitudinal_followup",
              "stage_signoff",
              "measurement_model",
              "withdrawal",
              "validation_release"
            ],
            "title": "Event Type"
          },
          "actor_hash": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Actor Hash"
          },
          "dyad_hash": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dyad Hash"
          },
          "item_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Item Id"
          },
          "bank_version": {
            "type": "string",
            "title": "Bank Version"
          },
          "bank_fingerprint": {
            "type": "string",
            "title": "Bank Fingerprint"
          },
          "payload": {
            "type": "object",
            "title": "Payload"
          },
          "event_hash": {
            "type": "string",
            "title": "Event Hash"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "event_id",
          "study_id",
          "event_type",
          "bank_version",
          "bank_fingerprint",
          "payload",
          "event_hash",
          "created_at"
        ],
        "title": "EventRecord"
      },
      "ExpertReviewSubmission": {
        "properties": {
          "reviewer_token": {
            "type": "string",
            "title": "Reviewer Token"
          },
          "reviewer_role": {
            "type": "string",
            "enum": [
              "couples_counsellor",
              "psychologist",
              "psychometrician",
              "financial_planner",
              "sexual_health_or_consent_expert",
              "indian_arranged_marriage_lived_experience",
              "language_reviewer",
              "research_methodologist",
              "data_scientist",
              "ethics_or_safeguarding_reviewer",
              "other"
            ],
            "title": "Reviewer Role"
          },
          "item_id": {
            "type": "string",
            "title": "Item Id"
          },
          "relevance": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Relevance"
          },
          "clarity": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Clarity"
          },
          "cultural_fit": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Cultural Fit"
          },
          "option_balance": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Option Balance"
          },
          "safety_appropriateness": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Safety Appropriateness"
          },
          "critical_safety_issue": {
            "type": "boolean",
            "title": "Critical Safety Issue",
            "default": false
          },
          "recommended_change": {
            "type": "boolean",
            "title": "Recommended Change",
            "default": false
          },
          "rationale": {
            "type": "string",
            "maxLength": 3000,
            "title": "Rationale",
            "default": ""
          },
          "conflict_of_interest": {
            "type": "string",
            "maxLength": 500,
            "title": "Conflict Of Interest",
            "default": "none_declared"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "reviewer_token",
          "reviewer_role",
          "item_id",
          "relevance",
          "clarity",
          "cultural_fit",
          "option_balance",
          "safety_appropriateness"
        ],
        "title": "ExpertReviewSubmission"
      },
      "FirebaseSessionExchangeRequest": {
        "properties": {
          "display_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120,
                "minLength": 2
              },
              {
                "type": "null"
              }
            ],
            "title": "Display Name"
          },
          "consent_given": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Consent Given"
          }
        },
        "type": "object",
        "title": "FirebaseSessionExchangeRequest"
      },
      "GoldenFixtureSummary": {
        "properties": {
          "truth_fixture_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Truth Fixture Id",
            "description": "SHA-256 hex digest of the truth fixture bytes. None when the fixture is missing or unreadable."
          },
          "truth_fixture_path": {
            "type": "string",
            "title": "Truth Fixture Path",
            "description": "Path the admin baseline resolved the truth fixture against."
          },
          "truth_fixture_present": {
            "type": "boolean",
            "title": "Truth Fixture Present",
            "description": "True when the truth fixture file is present on disk."
          },
          "report_fixture_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Report Fixture Id",
            "description": "SHA-256 hex digest of the report fixture bytes. None when the fixture is missing or unreadable."
          },
          "report_fixture_path": {
            "type": "string",
            "title": "Report Fixture Path",
            "description": "Path the admin baseline resolved the report fixture against."
          },
          "report_fixture_present": {
            "type": "boolean",
            "title": "Report Fixture Present",
            "description": "True when the report fixture file is present on disk."
          },
          "fixtures_consistent": {
            "type": "boolean",
            "title": "Fixtures Consistent",
            "description": "True when both fixtures are present AND the report fixture's ``report`` block matches the truth fixture's engine-relevant fields modulo the documented non-deterministic fields. False when either fixture is missing or the engine-relevant fields drift."
          },
          "pinned_engine_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pinned Engine Version",
            "description": "Engine version pinned inside the truth fixture's ``metadata.engine_version`` block. None when the fixture is missing or the metadata block is absent."
          },
          "non_deterministic_fields": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Non Deterministic Fields",
            "description": "Engine-output fields that must be NORMALIZED (not byte-compared) when comparing a live engine result against a golden fixture. The list is closed: any field not on this list is expected to match exactly."
          }
        },
        "type": "object",
        "required": [
          "truth_fixture_path",
          "truth_fixture_present",
          "report_fixture_path",
          "report_fixture_present",
          "fixtures_consistent"
        ],
        "title": "GoldenFixtureSummary",
        "description": "Coverage summary for the existing golden truth/report fixtures.\n\nEach fixture gets a stable SHA-256 content identifier so\nregression tooling can detect drift without re-reading the file.\nThe DTO also explicitly lists the non-deterministic fields a\nregression harness must NORMALIZE rather than byte-compare when\nasserting a live engine output against a golden fixture."
      },
      "GoogleSessionExchangeRequest": {
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 128,
            "minLength": 1,
            "title": "Code"
          }
        },
        "type": "object",
        "required": [
          "code"
        ],
        "title": "GoogleSessionExchangeRequest"
      },
      "GoogleSessionExchangeResponse": {
        "properties": {
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "session_token": {
            "type": "string",
            "title": "Session Token"
          },
          "display_name": {
            "type": "string",
            "title": "Display Name"
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "session_token",
          "display_name"
        ],
        "title": "GoogleSessionExchangeResponse"
      },
      "GottmanRiskRequest": {
        "properties": {
          "criticism": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 0.0,
            "title": "Criticism",
            "default": 0
          },
          "contempt": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 0.0,
            "title": "Contempt",
            "default": 0
          },
          "defensiveness": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 0.0,
            "title": "Defensiveness",
            "default": 0
          },
          "stonewalling": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 0.0,
            "title": "Stonewalling",
            "default": 0
          },
          "repair_frequency": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 0.0,
            "title": "Repair Frequency",
            "default": 2
          },
          "repair_success_rate": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Repair Success Rate",
            "default": 0.5
          },
          "flooding": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 0.0,
            "title": "Flooding",
            "default": 0
          },
          "positive_to_negative_ratio": {
            "type": "number",
            "minimum": 0.0,
            "title": "Positive To Negative Ratio",
            "default": 5.0
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "GottmanRiskRequest"
      },
      "GrantFullAccessRequest": {
        "properties": {
          "duration_days": {
            "type": "integer",
            "maximum": 365.0,
            "minimum": 1.0,
            "title": "Duration Days",
            "default": 30
          }
        },
        "type": "object",
        "title": "GrantFullAccessRequest"
      },
      "GroundingState": {
        "type": "string",
        "enum": [
          "grounded",
          "partial",
          "absent",
          "narrative_derived"
        ],
        "title": "GroundingState",
        "description": "Closed literal for the grounding state of a scenario or matrix cell.\n\nThe state is *server-authored*: a renderer MUST trust the wire\nvalue rather than infer grounding from narrative tone. The\nstates are intentionally narrow so the wire shape alone\nsurfaces trust failures instead of hiding them behind prose.\n\n* ``grounded`` \u2014 the deterministic truth contains all the\n  signals / cells the scenario or matrix layer references; the\n  evidence block is fully populated and every referenced cell\n  is readable.\n* ``partial``  \u2014 at least one referenced signal or matrix cell\n  is unreadable on one side (e.g. ``mars_house_p1`` is\n  ``None`` because Mars is missing from the chart). The\n  evidence block surfaces the missing references by id so a\n  renderer can show a 'partial grounding' affordance.\n* ``absent``   \u2014 no deterministic signals could be derived for\n  this scenario or matrix cell. The scenario still renders\n  (because the cultural-context flow requested it), but the\n  evidence block is honestly empty and the\n  ``grounding_reason`` is populated.\n* ``narrative_derived`` \u2014 the scenario was authored by the LLM\n  from the supplied chart facts (so it is chart-informed), but\n  the backend cannot *deterministically* verify the grounding\n  the way it can for the static scenario bank. This is distinct\n  from ``absent`` (which means no chart grounding applies at\n  all): a renderer should surface ``narrative_derived`` as\n  \"chart-derived narrative\" rather than as a grounding failure.\n  ``source_signals`` and ``matrix_cell_refs`` are empty and\n  ``grounding_reason`` is populated (e.g.\n  ``llm_generated_from_chart_facts``)."
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "HealthResponse": {
        "properties": {
          "status": {
            "type": "string",
            "title": "Status"
          },
          "version": {
            "type": "string",
            "title": "Version"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "title": "Timestamp"
          }
        },
        "type": "object",
        "required": [
          "status",
          "version",
          "timestamp"
        ],
        "title": "HealthResponse",
        "description": "Health check response."
      },
      "HoroscopeResponse": {
        "properties": {
          "rashi": {
            "type": "string",
            "title": "Rashi"
          },
          "element": {
            "type": "string",
            "title": "Element"
          },
          "ruler": {
            "type": "string",
            "title": "Ruler"
          },
          "traits": {
            "type": "string",
            "title": "Traits"
          },
          "yearly_preview": {
            "type": "string",
            "title": "Yearly Preview"
          },
          "general_prediction": {
            "type": "string",
            "title": "General Prediction"
          },
          "career": {
            "type": "string",
            "title": "Career"
          },
          "love": {
            "type": "string",
            "title": "Love"
          },
          "health": {
            "type": "string",
            "title": "Health"
          },
          "remedies": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Remedies"
          }
        },
        "type": "object",
        "required": [
          "rashi",
          "element",
          "ruler",
          "traits",
          "yearly_preview",
          "general_prediction",
          "career",
          "love",
          "health",
          "remedies"
        ],
        "title": "HoroscopeResponse"
      },
      "ImageMetadataOut": {
        "properties": {
          "original_width": {
            "type": "integer",
            "title": "Original Width",
            "description": "Width of the upload in pixels (before resize)."
          },
          "original_height": {
            "type": "integer",
            "title": "Original Height",
            "description": "Height of the upload in pixels (before resize)."
          },
          "processed_width": {
            "type": "integer",
            "title": "Processed Width",
            "description": "Width of the upload after resize to a Z.ai-spec-compliant dimension."
          },
          "processed_height": {
            "type": "integer",
            "title": "Processed Height",
            "description": "Height of the upload after resize."
          },
          "file_size_bytes": {
            "type": "integer",
            "title": "File Size Bytes",
            "description": "Total size of the upload bytes."
          },
          "file_size_mb": {
            "type": "number",
            "title": "File Size Mb",
            "description": "Total size of the upload in megabytes."
          },
          "mime_type": {
            "type": "string",
            "title": "Mime Type",
            "description": "Best-effort MIME type of the upload.",
            "default": "image/jpeg"
          },
          "format": {
            "type": "string",
            "title": "Format",
            "description": "Image format string (e.g. 'JPEG', 'PNG').",
            "default": "JPEG"
          }
        },
        "type": "object",
        "required": [
          "original_width",
          "original_height",
          "processed_width",
          "processed_height",
          "file_size_bytes",
          "file_size_mb"
        ],
        "title": "ImageMetadataOut",
        "description": "Image metadata captured during the assessment.\n\nPopulated by the backend-local preprocessing pipeline\n(format, dimensions, file size). These fields are NOT\nfabricated; they come from the actual upload bytes."
      },
      "InterpretationOut": {
        "properties": {
          "status": {
            "$ref": "#/components/schemas/app__schemas__kundli__InterpretationStatus"
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "Narrative interpretation text. May contain a bounded, degraded narrative when status is 'partial'; empty when unavailable.",
            "default": ""
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Provenance of the narrative. 'minimax_m3' when the configured model produced it; 'none' when unavailable.",
            "default": "none"
          },
          "model_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model Id",
            "description": "Concrete model identifier used (e.g. 'MiniMax-M3'). None when no model call was made."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "When status is 'partial' or 'unavailable', a short machine-readable reason (e.g. 'llm_timeout', 'quota_exhausted', 'rate_limited', 'parse_error')."
          },
          "attempted_at": {
            "type": "string",
            "title": "Attempted At",
            "description": "ISO-8601 UTC timestamp at which the LLM call was attempted, regardless of outcome."
          }
        },
        "type": "object",
        "required": [
          "status",
          "attempted_at"
        ],
        "title": "InterpretationOut",
        "description": "Optional narrative interpretation layer.\n\nThis is the only block in the report flow that may be absent or\ndegraded. The status field is the source of truth \u2014 the client\nMUST render the chart even when status is ``partial`` or\n``unavailable``."
      },
      "KundliBehaviorLens": {
        "properties": {
          "top_takeaway": {
            "type": "string",
            "title": "Top Takeaway",
            "description": "One plain-language takeaway from the behavioral profile that informed this reading.",
            "default": ""
          },
          "practical_recommendation": {
            "type": "string",
            "title": "Practical Recommendation",
            "description": "One practical recommendation derived from the action plan's next steps, framed for the Kundli context.",
            "default": ""
          },
          "evidence_confidence": {
            "type": "string",
            "title": "Evidence Confidence",
            "description": "Short non-diagnostic note on the evidence confidence behind the lens (e.g. 'moderate evidence, 4 dimensions').",
            "default": ""
          },
          "dimensions": {
            "items": {
              "$ref": "#/components/schemas/KundliBehaviorLensDimension"
            },
            "type": "array",
            "title": "Dimensions",
            "description": "Personality dimensions from the behavioral profile, each with a plain-language description and practical tip. Empty when no scored dimensions are available."
          },
          "strengths": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Strengths",
            "description": "Top 2-3 behavioral strengths (high-band dimensions), each as a short phrase."
          },
          "growth_areas": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Growth Areas",
            "description": "Top 1-2 behavioral growth areas (low-band dimensions), each as a short phrase."
          }
        },
        "type": "object",
        "title": "KundliBehaviorLens",
        "description": "Compact behavior lens surfaced on the Kundli report flow.\n\nevalution.md Phase 4: when a consented behavioral profile was\nused to personalize the interpretation, the response carries a\nsmall panel so the user can see *how* the behavior profile\nchanged the reading. The lens is deterministic \u2014 built from\nthe saved action plan's headline, next step, and confidence\nnote \u2014 so it never blocks on the LLM and never fabricates\nbehavioral claims when no profile was supplied."
      },
      "KundliBehaviorLensDimension": {
        "properties": {
          "dimension_key": {
            "type": "string",
            "title": "Dimension Key",
            "description": "Stable key for the dimension (e.g. 'emotional_regulation')."
          },
          "dimension_label": {
            "type": "string",
            "title": "Dimension Label",
            "description": "Human-readable label (e.g. 'Emotional Regulation').",
            "default": ""
          },
          "band": {
            "type": "string",
            "title": "Band",
            "description": "Score band: 'low', 'moderate', 'high', 'mixed', or 'unknown'.",
            "default": "unknown"
          },
          "score": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Score",
            "description": "Deprecated compatibility field. Numeric personality scores are not exposed to users and new responses leave this null."
          },
          "confidence": {
            "type": "string",
            "title": "Confidence",
            "description": "Confidence in the qualitative band.",
            "default": "low"
          },
          "sample_count": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Sample Count",
            "description": "Number of scorable scenario answers supporting this dimension.",
            "default": 0
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "One-sentence plain-language explanation of what this dimension measures and where the user lands on it.",
            "default": ""
          },
          "evidence": {
            "type": "string",
            "title": "Evidence",
            "description": "Answer-based reasoning for the band. For unknown dimensions this explains what evidence is still missing.",
            "default": ""
          },
          "practical_tip": {
            "type": "string",
            "title": "Practical Tip",
            "description": "One practical tip for how this trait shows up in daily life or relationships.",
            "default": ""
          }
        },
        "type": "object",
        "required": [
          "dimension_key"
        ],
        "title": "KundliBehaviorLensDimension",
        "description": "One behavioral dimension surfaced in the Kundli behavior lens.\n\nEach dimension shows the user's band, a short plain-language\ndescription of what that band means, the evidence that led to the\ndescription, and a practical tip for how it shows up in daily life.\n\nA dimension can be ``unknown`` when fewer than two scorable scenario\nanswers support it. Unknown is an honest state, not a low score."
      },
      "KundliBirthInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "title": "Name",
            "description": "Subject's name (non-empty, \u2264 120 chars)."
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "Birth date in DD/MM/YYYY format. Year must be 1900-2100 for bundled DE421 coverage."
          },
          "birth_time": {
            "type": "string",
            "title": "Birth Time",
            "description": "Birth time in HH:MM (24-hour) local civil time at the given timezone_offset."
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude",
            "description": "Latitude in decimal degrees, -90..90."
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude",
            "description": "Longitude in decimal degrees, -180..180."
          },
          "timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -14.0,
            "title": "Timezone Offset",
            "description": "Hours from UTC for the local civil time of birth, -14..14. Must be supplied with the resolved birth place."
          },
          "timezone_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Id",
            "description": "IANA timezone ID (e.g., 'Asia/Kolkata'). Preferred over offset."
          },
          "birth_time_precision_minutes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Time Precision Minutes",
            "description": "Birth time precision in minutes (e.g., 0 for exact, 15 for +/- 15 mins)."
          },
          "user_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Id",
            "description": "Optional user ID to persist generated kundli facts into working memory."
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id",
            "description": "Optional session ID to associate generated facts with a specific chat session."
          }
        },
        "type": "object",
        "required": [
          "name",
          "birth_date",
          "birth_time",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "KundliBirthInput",
        "description": "Validated birth input for the Kundli engine.\n\nAll range and format rules are enforced here so the engine can\ntrust ``BirthInput`` to be well-formed when it reaches\n:func:`validate_birth_input`. Format-level errors map to HTTP\n422 via FastAPI's :class:`RequestValidationError` handler\nregistered in ``app.main``.",
        "example": {
          "birth_date": "15/05/1990",
          "birth_time": "10:30",
          "latitude": 19.076,
          "longitude": 72.8777,
          "name": "Asha Sharma",
          "timezone_offset": 5.5
        }
      },
      "KundliChatContext": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "title": "Name",
            "default": "Unknown"
          },
          "birth_date": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 32
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Date"
          },
          "birth_time": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 32
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Time"
          },
          "ascendant": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Ascendant"
          },
          "moon_sign": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Moon Sign"
          },
          "sun_sign": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Sun Sign"
          },
          "nakshatra": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Nakshatra"
          },
          "tithi": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Tithi"
          },
          "current_dasha": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Dasha"
          },
          "current_antardasha": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Antardasha"
          },
          "planetary_positions": {
            "items": {
              "$ref": "#/components/schemas/KundliPlanetContext"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Planetary Positions"
          },
          "yogas": {
            "items": {
              "$ref": "#/components/schemas/KundliYogaContext"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Yogas"
          },
          "divisional_charts": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KundliDivisionalChartsContext"
              },
              {
                "type": "null"
              }
            ]
          },
          "current_transits": {
            "items": {
              "$ref": "#/components/schemas/KundliTransitContext"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Current Transits"
          }
        },
        "type": "object",
        "title": "KundliChatContext"
      },
      "KundliDivisionalChartsContext": {
        "properties": {
          "D9": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object",
                "maxProperties": 20
              },
              {
                "type": "null"
              }
            ],
            "title": "D9"
          }
        },
        "type": "object",
        "title": "KundliDivisionalChartsContext"
      },
      "KundliPlanetContext": {
        "properties": {
          "planet": {
            "type": "string",
            "maxLength": 40,
            "title": "Planet",
            "default": "Unknown"
          },
          "sign": {
            "type": "string",
            "maxLength": 40,
            "title": "Sign",
            "default": "Unknown"
          },
          "house": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 12.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "House"
          },
          "degree_in_sign": {
            "type": "number",
            "maximum": 360.0,
            "minimum": 0.0,
            "title": "Degree In Sign",
            "default": 0
          },
          "nakshatra": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Nakshatra"
          },
          "is_retrograde": {
            "type": "boolean",
            "title": "Is Retrograde",
            "default": false
          }
        },
        "type": "object",
        "title": "KundliPlanetContext"
      },
      "KundliReadingArtifactPayload-Input": {
        "properties": {
          "kundli_reading_schema_version": {
            "type": "string",
            "title": "Kundli Reading Schema Version",
            "description": "Per-kind reading schema version. Bumped on any breaking change to the per-kind wire shape.",
            "default": "v2-kundli-reading-1.0.0"
          },
          "report_flow": {
            "$ref": "#/components/schemas/KundliReportFlowResponse-Input",
            "description": "The structured Kundli report flow, stored verbatim. A reopen yields the same fields byte-comparable to a fresh report-flow response."
          }
        },
        "type": "object",
        "required": [
          "report_flow"
        ],
        "title": "KundliReadingArtifactPayload",
        "description": "Per-kind payload for a Kundli reading artifact.\n\nThe :attr:`kundli_reading_schema_version` string is the\nper-kind reading schema version the readings surface\nstamps on its persisted envelope. The :attr:`report_flow`\nis the same :class:`KundliReportFlowResponse` the\n``/api/v2/kundli/report-flow`` route returns \u2014 stored\nverbatim, so a reopen of a stored artifact is\nbyte-comparable to a fresh report-flow response on the\nsame input."
      },
      "KundliReadingArtifactPayload-Output": {
        "properties": {
          "kundli_reading_schema_version": {
            "type": "string",
            "title": "Kundli Reading Schema Version",
            "description": "Per-kind reading schema version. Bumped on any breaking change to the per-kind wire shape.",
            "default": "v2-kundli-reading-1.0.0"
          },
          "report_flow": {
            "$ref": "#/components/schemas/KundliReportFlowResponse-Output",
            "description": "The structured Kundli report flow, stored verbatim. A reopen yields the same fields byte-comparable to a fresh report-flow response."
          }
        },
        "type": "object",
        "required": [
          "report_flow"
        ],
        "title": "KundliReadingArtifactPayload",
        "description": "Per-kind payload for a Kundli reading artifact.\n\nThe :attr:`kundli_reading_schema_version` string is the\nper-kind reading schema version the readings surface\nstamps on its persisted envelope. The :attr:`report_flow`\nis the same :class:`KundliReportFlowResponse` the\n``/api/v2/kundli/report-flow`` route returns \u2014 stored\nverbatim, so a reopen of a stored artifact is\nbyte-comparable to a fresh report-flow response on the\nsame input."
      },
      "KundliReport": {
        "properties": {
          "input": {
            "$ref": "#/components/schemas/KundliBirthInput"
          },
          "ascendant_rashi": {
            "type": "string",
            "title": "Ascendant Rashi"
          },
          "ascendant_longitude_sidereal": {
            "type": "number",
            "title": "Ascendant Longitude Sidereal"
          },
          "ascendant_degree_in_sign": {
            "type": "number",
            "title": "Ascendant Degree In Sign"
          },
          "moon_rashi": {
            "type": "string",
            "title": "Moon Rashi"
          },
          "sun_rashi": {
            "type": "string",
            "title": "Sun Rashi"
          },
          "moon_longitude_sidereal": {
            "type": "number",
            "title": "Moon Longitude Sidereal"
          },
          "sun_longitude_sidereal": {
            "type": "number",
            "title": "Sun Longitude Sidereal"
          },
          "nakshatra": {
            "type": "string",
            "title": "Nakshatra"
          },
          "nakshatra_pada": {
            "type": "integer",
            "title": "Nakshatra Pada"
          },
          "nakshatra_lord": {
            "type": "string",
            "title": "Nakshatra Lord"
          },
          "planetary_positions": {
            "items": {
              "$ref": "#/components/schemas/PlanetaryPositionOut"
            },
            "type": "array",
            "title": "Planetary Positions"
          },
          "tithi": {
            "type": "string",
            "title": "Tithi"
          },
          "karana": {
            "type": "string",
            "title": "Karana"
          },
          "yoga_name": {
            "type": "string",
            "title": "Yoga Name"
          },
          "current_dasha": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DashaOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "current_antardasha": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DashaOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "yogas": {
            "items": {
              "$ref": "#/components/schemas/YogaOut"
            },
            "type": "array",
            "title": "Yogas"
          },
          "divisional_charts": {
            "additionalProperties": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "type": "object",
            "title": "Divisional Charts"
          },
          "current_transits": {
            "items": {
              "$ref": "#/components/schemas/PlanetaryPositionOut"
            },
            "type": "array",
            "title": "Current Transits"
          },
          "planetary_aspects": {
            "items": {
              "$ref": "#/components/schemas/PlanetaryAspectOut"
            },
            "type": "array",
            "title": "Planetary Aspects"
          },
          "metadata": {
            "$ref": "#/components/schemas/EngineMetadataOut"
          },
          "confidence": {
            "$ref": "#/components/schemas/app__schemas__kundli__InputConfidenceOut"
          }
        },
        "type": "object",
        "required": [
          "input",
          "ascendant_rashi",
          "ascendant_longitude_sidereal",
          "ascendant_degree_in_sign",
          "moon_rashi",
          "sun_rashi",
          "moon_longitude_sidereal",
          "sun_longitude_sidereal",
          "nakshatra",
          "nakshatra_pada",
          "nakshatra_lord",
          "planetary_positions",
          "tithi",
          "karana",
          "yoga_name",
          "yogas",
          "divisional_charts",
          "current_transits",
          "planetary_aspects",
          "metadata",
          "confidence"
        ],
        "title": "KundliReport",
        "description": "Authoritative D1 chart payload.\n\nField set matches :class:`KundliTruth` exactly so the engine's\n``to_dict()`` output passes through this schema without losing\ninformation. The ``schema_version`` constant on the response\nwrapper advertises that this payload is the v2 contract."
      },
      "KundliReportFlowRequest": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "title": "Name",
            "description": "Subject's name (non-empty, \u2264 120 chars)."
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "Birth date in DD/MM/YYYY format. Year must be 1900-2100 for bundled DE421 coverage."
          },
          "birth_time": {
            "type": "string",
            "title": "Birth Time",
            "description": "Birth time in HH:MM (24-hour) local civil time at the given timezone_offset."
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude",
            "description": "Latitude in decimal degrees, -90..90."
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude",
            "description": "Longitude in decimal degrees, -180..180."
          },
          "timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -14.0,
            "title": "Timezone Offset",
            "description": "Hours from UTC for the local civil time of birth, -14..14. Must be supplied with the resolved birth place."
          },
          "timezone_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Id",
            "description": "IANA timezone ID (e.g., 'Asia/Kolkata'). Preferred over offset."
          },
          "birth_time_precision_minutes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Time Precision Minutes",
            "description": "Birth time precision in minutes (e.g., 0 for exact, 15 for +/- 15 mins)."
          },
          "user_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Id",
            "description": "Optional user ID to persist generated kundli facts into working memory."
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id",
            "description": "Optional session ID to associate generated facts with a specific chat session."
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "default": "english"
          }
        },
        "type": "object",
        "required": [
          "name",
          "birth_date",
          "birth_time",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "KundliReportFlowRequest",
        "example": {
          "birth_date": "15/05/1990",
          "birth_time": "10:30",
          "latitude": 19.076,
          "longitude": 72.8777,
          "name": "Asha Sharma",
          "timezone_offset": 5.5
        }
      },
      "KundliReportFlowResponse-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-report-flow-1.0.0"
          },
          "report": {
            "$ref": "#/components/schemas/KundliReport"
          },
          "trust": {
            "$ref": "#/components/schemas/app__schemas__kundli__TrustMetadataOut"
          },
          "disclaimer": {
            "$ref": "#/components/schemas/app__schemas__kundli__DisclaimerMetadataOut"
          },
          "interpretation": {
            "$ref": "#/components/schemas/InterpretationOut"
          },
          "behavioral_evidence": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Behavioral Evidence",
            "description": "Consented behavioral profile summary used to personalize the interpretation, if any."
          },
          "behavior_lens": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KundliBehaviorLens"
              },
              {
                "type": "null"
              }
            ],
            "description": "Compact behavior lens panel (evalution.md Phase 4). Present only when a consented behavioral profile was used to personalize the interpretation."
          }
        },
        "type": "object",
        "required": [
          "report",
          "trust",
          "disclaimer",
          "interpretation"
        ],
        "title": "KundliReportFlowResponse",
        "description": "Structured v2 Kundli report-flow response.\n\nComposition contract:\n\n* ``report`` is the deterministic engine truth passed through\n  verbatim \u2014 the composer must not mutate, summarize, or\n  reinterpret it. ``KundliReportFlowResponse.report`` is the\n  same :class:`KundliReport` type used by\n  :class:`KundliReportResponse`.\n* ``trust`` is backend-owned trust metadata; clients render\n  this verbatim and must not regenerate provenance copy.\n* ``disclaimer`` is backend-owned disclaimer metadata; the\n  full text lives at ``disclaimer.full_text_endpoint``.\n* ``interpretation`` is the optional narrative layer with an\n  explicit :class:`InterpretationStatus`. The chart is fully\n  usable even when status is ``partial`` or ``unavailable``.\n* ``behavioral_evidence`` is an optional consented behavioral\n  profile summary used to personalize the interpretation. Empty\n  when the user has no saved profile or the profile is not\n  consented.\n* ``behavior_lens`` (evalution.md Phase 4) is an optional\n  compact panel that explains how the saved behavior profile\n  changed the interpretation. ``None`` when no consented\n  profile was used."
      },
      "KundliReportFlowResponse-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-report-flow-1.0.0"
          },
          "report": {
            "$ref": "#/components/schemas/KundliReport"
          },
          "trust": {
            "$ref": "#/components/schemas/app__schemas__kundli__TrustMetadataOut"
          },
          "disclaimer": {
            "$ref": "#/components/schemas/app__schemas__kundli__DisclaimerMetadataOut"
          },
          "interpretation": {
            "$ref": "#/components/schemas/InterpretationOut"
          },
          "behavioral_evidence": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Behavioral Evidence",
            "description": "Consented behavioral profile summary used to personalize the interpretation, if any."
          },
          "behavior_lens": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KundliBehaviorLens"
              },
              {
                "type": "null"
              }
            ],
            "description": "Compact behavior lens panel (evalution.md Phase 4). Present only when a consented behavioral profile was used to personalize the interpretation."
          }
        },
        "type": "object",
        "required": [
          "report",
          "trust",
          "disclaimer",
          "interpretation"
        ],
        "title": "KundliReportFlowResponse",
        "description": "Structured v2 Kundli report-flow response.\n\nComposition contract:\n\n* ``report`` is the deterministic engine truth passed through\n  verbatim \u2014 the composer must not mutate, summarize, or\n  reinterpret it. ``KundliReportFlowResponse.report`` is the\n  same :class:`KundliReport` type used by\n  :class:`KundliReportResponse`.\n* ``trust`` is backend-owned trust metadata; clients render\n  this verbatim and must not regenerate provenance copy.\n* ``disclaimer`` is backend-owned disclaimer metadata; the\n  full text lives at ``disclaimer.full_text_endpoint``.\n* ``interpretation`` is the optional narrative layer with an\n  explicit :class:`InterpretationStatus`. The chart is fully\n  usable even when status is ``partial`` or ``unavailable``.\n* ``behavioral_evidence`` is an optional consented behavioral\n  profile summary used to personalize the interpretation. Empty\n  when the user has no saved profile or the profile is not\n  consented.\n* ``behavior_lens`` (evalution.md Phase 4) is an optional\n  compact panel that explains how the saved behavior profile\n  changed the interpretation. ``None`` when no consented\n  profile was used."
      },
      "KundliReportResponse-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2"
          },
          "report": {
            "$ref": "#/components/schemas/KundliReport"
          }
        },
        "type": "object",
        "required": [
          "report"
        ],
        "title": "KundliReportResponse",
        "description": "v2 response wrapper around the authoritative engine report."
      },
      "KundliReportResponse-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2"
          },
          "report": {
            "$ref": "#/components/schemas/KundliReport"
          }
        },
        "type": "object",
        "required": [
          "report"
        ],
        "title": "KundliReportResponse",
        "description": "v2 response wrapper around the authoritative engine report."
      },
      "KundliTransitContext": {
        "properties": {
          "planet": {
            "type": "string",
            "maxLength": 40,
            "title": "Planet",
            "default": "Unknown"
          },
          "sign": {
            "type": "string",
            "maxLength": 40,
            "title": "Sign",
            "default": "Unknown"
          },
          "house": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 12.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "House"
          },
          "is_retrograde": {
            "type": "boolean",
            "title": "Is Retrograde",
            "default": false
          }
        },
        "type": "object",
        "title": "KundliTransitContext"
      },
      "KundliV1Response": {
        "properties": {
          "kundli": {
            "type": "object",
            "title": "Kundli"
          },
          "message": {
            "type": "string",
            "title": "Message",
            "default": "Kundli generated successfully"
          }
        },
        "type": "object",
        "required": [
          "kundli"
        ],
        "title": "KundliV1Response",
        "description": "v1 endpoint response \u2014 kept for the existing app build.\n\nThe engine version is exposed as an additive ``engine_metadata``\nfield on the inner ``kundli`` object so v1 clients gain engine\nprovenance without breaking their existing parsers."
      },
      "KundliYogaContext": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "title": "Name",
            "default": "Unknown"
          },
          "strength": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80
              },
              {
                "type": "null"
              }
            ],
            "title": "Strength"
          },
          "description": {
            "type": "string",
            "maxLength": 800,
            "title": "Description",
            "default": ""
          }
        },
        "type": "object",
        "title": "KundliYogaContext"
      },
      "LineAnalysisOut": {
        "properties": {
          "line_name": {
            "type": "string",
            "title": "Line Name"
          },
          "present": {
            "type": "boolean",
            "title": "Present"
          },
          "quality": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Quality"
          },
          "description": {
            "type": "string",
            "title": "Description"
          },
          "interpretation": {
            "type": "string",
            "title": "Interpretation"
          },
          "confidence": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Confidence",
            "default": 1.0
          }
        },
        "type": "object",
        "required": [
          "line_name",
          "present",
          "quality",
          "description",
          "interpretation"
        ],
        "title": "LineAnalysisOut",
        "description": "Analysis of a single palm line \u2014 typed wire shape.\n\nMirrors the dataclass shape used in the existing palmistry\nservice. The ``confidence`` field is in [0.0, 1.0]; the\n``quality`` list contains human-readable descriptors like\n``deep``, ``broken``, ``chained``, ``curved``, ``straight``."
      },
      "LogoutResponse": {
        "properties": {
          "revoked": {
            "type": "boolean",
            "title": "Revoked"
          },
          "user_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Id"
          }
        },
        "type": "object",
        "required": [
          "revoked"
        ],
        "title": "LogoutResponse"
      },
      "LongitudinalFollowupSubmission": {
        "properties": {
          "participant_token": {
            "type": "string",
            "title": "Participant Token"
          },
          "dyad_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dyad Token"
          },
          "wave": {
            "type": "integer",
            "maximum": 20.0,
            "minimum": 2.0,
            "title": "Wave"
          },
          "elapsed_days": {
            "type": "integer",
            "maximum": 3650.0,
            "minimum": 1.0,
            "title": "Elapsed Days"
          },
          "consent_version": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Consent Version"
          },
          "strata": {
            "$ref": "#/components/schemas/ParticipantStrata"
          },
          "responses": {
            "items": {
              "$ref": "#/components/schemas/LongitudinalItemResponse"
            },
            "type": "array",
            "maxItems": 100,
            "title": "Responses"
          },
          "discussion_usefulness": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 5.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Discussion Usefulness"
          },
          "decision_clarity": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 5.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Decision Clarity"
          },
          "major_context_change": {
            "type": "boolean",
            "title": "Major Context Change",
            "default": false
          },
          "context_change_category": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Context Change Category"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "participant_token",
          "wave",
          "elapsed_days",
          "consent_version",
          "strata"
        ],
        "title": "LongitudinalFollowupSubmission"
      },
      "LongitudinalItemResponse": {
        "properties": {
          "item_id": {
            "type": "string",
            "title": "Item Id"
          },
          "item_version": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Item Version"
          },
          "selected_option": {
            "type": "string",
            "title": "Selected Option"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "item_id",
          "item_version",
          "selected_option"
        ],
        "title": "LongitudinalItemResponse"
      },
      "MatrixBand": {
        "type": "string",
        "enum": [
          "strong_support",
          "supportive",
          "mixed",
          "caution",
          "high_attention"
        ],
        "title": "MatrixBand",
        "description": "Closed literal for the derived matrix band.\n\nDerived strictly from the deterministic\n``recommendation_tier`` (and degraded-state override) so the\nband can never disagree with the authoritative tier. Bumping\nthe band mapping rules is an additive change inside\n:class:`SectionedDerivedInterpretation` and does not require a\nschema bump."
      },
      "MatrixCellEvidence": {
        "properties": {
          "cell_ref": {
            "type": "string",
            "title": "Cell Ref",
            "description": "Stable cell reference, format 'layer:<LayerName.value>'. Mirrored verbatim."
          },
          "source_signals": {
            "items": {
              "$ref": "#/components/schemas/SourceSignalRef"
            },
            "type": "array",
            "title": "Source Signals",
            "description": "Deterministic signals that contributed to this layer's score. Empty when no signals are score-bearing for this layer."
          },
          "grounding_state": {
            "$ref": "#/components/schemas/GroundingState",
            "description": "Closed-literal grounding state for this cell. Mirrors the scenario grounding contract."
          },
          "grounding_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Grounding Reason",
            "description": "Short machine-readable reason when the grounding state is ``partial`` or ``absent``."
          }
        },
        "type": "object",
        "required": [
          "cell_ref",
          "grounding_state"
        ],
        "title": "MatrixCellEvidence",
        "description": "Backend-authored evidence for one matrix layer cell.\n\nMirrors :class:`DampatyaScenarioEvidence` at the matrix\nlayer (cell) level. The :class:`SectionedDomainSummary`\nsurfaces one ``MatrixCellEvidence`` per layer so a renderer\ncan cross-reference the deterministic signals that drove\nthe layer's score without parsing the layer rationale for\nsignal names.\n\nField-by-field invariants:\n\n* ``cell_ref`` is the stable handle in the form\n  ``layer:<LayerName.value>``. Render verbatim.\n* ``source_signals`` is the deterministic list of\n  :class:`SourceSignalRef` that contributed to the layer's\n  score. Empty when no signals are score-bearing for this\n  layer (defensive \u2014 every canonical layer has at least\n  one signal in M006 S02).\n* ``grounding_state`` is one of the closed literals in\n  :class:`GroundingState`. ``absent`` means the layer was\n  not computed by the engine (graceful degradation);\n  ``partial`` means at least one signal is unreadable;\n  ``grounded`` means all referenced signals are readable\n  AND the layer's scoring block is present.\n* ``grounding_reason`` is populated whenever the state is\n  not ``grounded`` so a renderer can show an explicit\n  reason rather than infer one from tone."
      },
      "MatrixCellRef": {
        "properties": {
          "cell_ref": {
            "type": "string",
            "title": "Cell Ref",
            "description": "Stable cell reference, format 'layer:<LayerName.value>'. Mirrored verbatim."
          },
          "readable": {
            "type": "boolean",
            "title": "Readable",
            "description": "True when the corresponding layer scoring block is present and non-degraded."
          }
        },
        "type": "object",
        "required": [
          "cell_ref",
          "readable"
        ],
        "title": "MatrixCellRef",
        "description": "A reference to a deterministic matrix cell.\n\nThe compatibility scoring surface is organised into six\ncanonical layers (see :class:`LayerName`). Each layer's\nscoring block (see :class:`CompatibilityLayerOut`) is the\ndeterministic cell the sectioned contract references. The\n``cell_ref`` string is the stable handle (``layer:<layer>``)\nso a renderer can map an evidence reference back to the\nauthoritative scoring cell."
      },
      "MeasurementModelSubmission": {
        "properties": {
          "signer_token": {
            "type": "string",
            "title": "Signer Token"
          },
          "model_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_.:-]{3,120}$",
            "title": "Model Id"
          },
          "model_family": {
            "type": "string",
            "enum": [
              "nominal_response_model",
              "multinomial_irt",
              "other"
            ],
            "title": "Model Family"
          },
          "version": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Version"
          },
          "preregistration_uri": {
            "type": "string",
            "maxLength": 500,
            "minLength": 4,
            "title": "Preregistration Uri"
          },
          "artifact_digest": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "title": "Artifact Digest"
          },
          "supports_dif": {
            "type": "boolean",
            "title": "Supports Dif",
            "default": false
          },
          "review_status": {
            "type": "string",
            "enum": [
              "proposed",
              "approved",
              "rejected"
            ],
            "title": "Review Status"
          },
          "reviewer_roles": {
            "items": {
              "type": "string",
              "enum": [
                "couples_counsellor",
                "psychologist",
                "psychometrician",
                "financial_planner",
                "sexual_health_or_consent_expert",
                "indian_arranged_marriage_lived_experience",
                "language_reviewer",
                "research_methodologist",
                "data_scientist",
                "ethics_or_safeguarding_reviewer",
                "other"
              ]
            },
            "type": "array",
            "title": "Reviewer Roles"
          },
          "limitations": {
            "type": "string",
            "maxLength": 4000,
            "minLength": 1,
            "title": "Limitations"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "signer_token",
          "model_id",
          "model_family",
          "version",
          "preregistration_uri",
          "artifact_digest",
          "review_status",
          "limitations"
        ],
        "title": "MeasurementModelSubmission"
      },
      "MemoryFactRequest": {
        "properties": {
          "user_id": {
            "type": "string",
            "maxLength": 128,
            "minLength": 1,
            "title": "User Id"
          },
          "key": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "pattern": "^[A-Za-z][A-Za-z0-9_.-]*$",
            "title": "Key",
            "description": "Stable data key, never prompt text."
          },
          "value": {
            "type": "string",
            "maxLength": 4000,
            "title": "Value"
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "key",
          "value"
        ],
        "title": "MemoryFactRequest",
        "description": "Request to set a user fact."
      },
      "MuhuratRequest": {
        "properties": {
          "activity": {
            "type": "string",
            "title": "Activity",
            "description": "Activity type: marriage, griha_pravesh, business, travel, naming"
          },
          "start_date": {
            "type": "string",
            "title": "Start Date",
            "description": "DD/MM/YYYY"
          },
          "end_date": {
            "type": "string",
            "title": "End Date",
            "description": "DD/MM/YYYY"
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude",
            "description": "Latitude supplied by the selected place."
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude",
            "description": "Longitude supplied by the selected place."
          },
          "timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -14.0,
            "title": "Timezone Offset",
            "description": "Timezone offset supplied by the selected place."
          }
        },
        "type": "object",
        "required": [
          "activity",
          "start_date",
          "end_date",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "MuhuratRequest"
      },
      "MuhuratResponse": {
        "properties": {
          "activity": {
            "type": "string",
            "title": "Activity"
          },
          "slots": {
            "items": {
              "$ref": "#/components/schemas/MuhuratSlot"
            },
            "type": "array",
            "title": "Slots"
          }
        },
        "type": "object",
        "required": [
          "activity",
          "slots"
        ],
        "title": "MuhuratResponse"
      },
      "MuhuratSlot": {
        "properties": {
          "date": {
            "type": "string",
            "title": "Date"
          },
          "vara": {
            "type": "string",
            "title": "Vara"
          },
          "tithi": {
            "type": "string",
            "title": "Tithi"
          },
          "nakshatra": {
            "type": "string",
            "title": "Nakshatra"
          },
          "yoga": {
            "type": "string",
            "title": "Yoga"
          },
          "score": {
            "type": "integer",
            "title": "Score"
          },
          "rating": {
            "type": "string",
            "title": "Rating"
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes"
          }
        },
        "type": "object",
        "required": [
          "date",
          "vara",
          "tithi",
          "nakshatra",
          "yoga",
          "score",
          "rating",
          "notes"
        ],
        "title": "MuhuratSlot"
      },
      "NumerologyRequest": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name"
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "DD/MM/YYYY"
          }
        },
        "type": "object",
        "required": [
          "name",
          "birth_date"
        ],
        "title": "NumerologyRequest"
      },
      "NumerologyResponse": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name"
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date"
          },
          "destiny_number": {
            "type": "integer",
            "title": "Destiny Number"
          },
          "destiny_meaning": {
            "type": "string",
            "title": "Destiny Meaning"
          },
          "soul_number": {
            "type": "integer",
            "title": "Soul Number"
          },
          "soul_meaning": {
            "type": "string",
            "title": "Soul Meaning"
          },
          "personality_number": {
            "type": "integer",
            "title": "Personality Number"
          },
          "personality_meaning": {
            "type": "string",
            "title": "Personality Meaning"
          },
          "planet_association": {
            "type": "string",
            "title": "Planet Association"
          },
          "lucky_numbers": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "title": "Lucky Numbers"
          },
          "lucky_colors": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Lucky Colors"
          },
          "lucky_days": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Lucky Days"
          }
        },
        "type": "object",
        "required": [
          "name",
          "birth_date",
          "destiny_number",
          "destiny_meaning",
          "soul_number",
          "soul_meaning",
          "personality_number",
          "personality_meaning",
          "planet_association",
          "lucky_numbers",
          "lucky_colors",
          "lucky_days"
        ],
        "title": "NumerologyResponse"
      },
      "PalmImageQualityGrade": {
        "type": "string",
        "enum": [
          "acceptable",
          "weak_quality",
          "weak_resolution",
          "weak_composition",
          "weak_format",
          "no_palm_detected",
          "not_a_palm_image"
        ],
        "title": "PalmImageQualityGrade",
        "description": "Image quality grade for the upload.\n\nThe grade is a finer-grained label than\n:class:`UploadStatus`. The :class:`UploadStatus` is the\noverall verdict the UI keys off; this enum is the diagnosis.\n\n* ``acceptable`` \u2014 passes every quality check.\n* ``weak_quality`` \u2014 too blurry, too dark, or too bright.\n* ``weak_resolution`` \u2014 dimensions below the minimum for\n  reliable interpretation.\n* ``weak_composition`` \u2014 partial palm visible, fingers cut\n  off, or excessive background.\n* ``weak_format`` \u2014 unsupported format or corrupt file.\n* ``no_palm_detected`` \u2014 the VLM did not find a palm in the\n  image.\n* ``not_a_palm_image`` \u2014 the VLM found a hand but not a palm\n  (e.g., back of hand, side profile, clenched fist)."
      },
      "PalmReadingReportOut": {
        "properties": {
          "lines": {
            "additionalProperties": {
              "$ref": "#/components/schemas/LineAnalysisOut"
            },
            "type": "object",
            "title": "Lines",
            "description": "Per-line analysis keyed by the line identifier (e.g. 'life_line', 'head_line')."
          },
          "overall_interpretation": {
            "type": "string",
            "title": "Overall Interpretation",
            "default": ""
          },
          "personality_traits": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Personality Traits"
          },
          "life_themes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Life Themes"
          },
          "recommendations": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Recommendations"
          },
          "raw_response_present": {
            "type": "boolean",
            "title": "Raw Response Present",
            "description": "True when the raw VLM response was captured by the service. The raw text is NOT exposed in the report-flow response to keep the contract clean.",
            "default": false
          }
        },
        "type": "object",
        "title": "PalmReadingReportOut",
        "description": "The structured palm reading report.\n\nThis is the wire shape for the report content. It mirrors\nthe legacy ``PalmReading.to_dict()`` shape for backward\ncompatibility but is typed, versioned, and intentionally\nomits the raw VLM response text from the wire (clients\nshould not be parsing the raw response \u2014 that's a service\nconcern)."
      },
      "PalmReadingResponse": {
        "properties": {
          "reading": {
            "type": "object",
            "title": "Reading"
          },
          "image_metadata": {
            "type": "object",
            "title": "Image Metadata"
          },
          "message": {
            "type": "string",
            "title": "Message",
            "default": "Palm reading completed"
          }
        },
        "type": "object",
        "required": [
          "reading",
          "image_metadata"
        ],
        "title": "PalmReadingResponse",
        "description": "Response from palm reading."
      },
      "PalmistryErrorCode": {
        "type": "string",
        "enum": [
          "invalid_image",
          "image_too_small",
          "image_too_large",
          "unsupported_format",
          "missing_file",
          "empty_file",
          "weak_quality",
          "weak_resolution",
          "weak_composition",
          "no_palm_detected",
          "not_a_palm_image",
          "vision_provider_unavailable",
          "vision_provider_timeout",
          "vision_provider_rate_limited",
          "vision_provider_quota_exhausted",
          "vision_provider_invalid_response"
        ],
        "title": "PalmistryErrorCode",
        "description": "Machine-readable Palmistry error / degraded-state codes.\n\nThese codes are stable, frontend-visible identifiers. They\ndrive the typed UI states for weak uploads, retry guidance,\nand provider failures. Every value is also a valid\n``PalmistryErrorResponse.error`` payload.\n\nThe set is closed: any new value is a breaking change to the\nwire contract and requires bumping\n:data:`PALMISTRY_REPORT_FLOW_SCHEMA_VERSION`."
      },
      "PalmistryErrorResponse": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error",
            "description": "PalmistryErrorCode value. Stable, machine-readable."
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          }
        },
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "title": "PalmistryErrorResponse",
        "description": "Single typed error envelope for the v2 palmistry surface.\n\nDistinct from the Kundli ``ErrorResponse`` because the\n``error`` field uses Palmistry-specific codes (see\n:class:`PalmistryErrorCode`), not the Kundli ones. This\nkeeps the error contract per-domain: a frontend that\nkeys off ``error`` can switch on Palmistry codes without\nworrying about cross-domain collisions.\n\nFor validation rejections ``error`` is one of\n``invalid_image``, ``image_too_small``, ``image_too_large``,\n``unsupported_format``, ``missing_file``, ``empty_file`` and\n``field`` (when present) names the offending field.\n\nFor provider dependency failures ``error`` is one of\n``vision_provider_unavailable``, ``vision_provider_timeout``,\n``vision_provider_rate_limited``,\n``vision_provider_quota_exhausted``,\n``vision_provider_invalid_response``."
      },
      "PalmistryInterpretationOut": {
        "properties": {
          "status": {
            "$ref": "#/components/schemas/PalmistryInterpretationStatus"
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "Narrative interpretation text. Empty when status is not 'complete'.",
            "default": ""
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Provenance of the narrative. 'minimax_vision' when the configured model produced it; 'none' when unavailable.",
            "default": "none"
          },
          "model_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model Id",
            "description": "Concrete model identifier used (e.g. 'MiniMax-M3'). None when no model call was made."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "When status is 'partial' or 'unavailable', a short machine-readable reason (e.g. 'llm_timeout', 'quota_exhausted', 'rate_limited', 'parse_error')."
          },
          "attempted_at": {
            "type": "string",
            "title": "Attempted At",
            "description": "ISO-8601 UTC timestamp at which the VLM call was attempted, regardless of outcome."
          }
        },
        "type": "object",
        "required": [
          "status",
          "attempted_at"
        ],
        "title": "PalmistryInterpretationOut",
        "description": "Optional narrative interpretation layer.\n\nDistinct from the structured :class:`PalmReadingReportOut`:\nthe interpretation is the optional narrative layer, the\nreport is the structured reading. The\n:attr:`PalmistryInterpretationStatus` field is the source of\ntruth for the UI's narrative surface."
      },
      "PalmistryInterpretationStatus": {
        "type": "string",
        "enum": [
          "complete",
          "partial",
          "unavailable"
        ],
        "title": "PalmistryInterpretationStatus",
        "description": "Honest disclosure of palmistry interpretation availability.\n\n* ``complete``   \u2014 interpretation succeeded and is fully\n  attached. The structured report is present in the\n  response.\n* ``partial``    \u2014 the VLM returned a degraded result. The\n  structured report is still present in the response; the\n  narrative ``text`` may be incomplete.\n* ``unavailable`` \u2014 the LLM/VLM call failed, returned no\n  text, or was disabled. The response is still valid; the\n  narrative ``text`` is empty.\n\nThe status is the source of truth for the UI's narrative\nsurface. The structured report is unaffected by the status\n(the VLM either produced the reading or it didn't)."
      },
      "PalmistryReadingArtifactPayload-Input": {
        "properties": {
          "palmistry_reading_schema_version": {
            "type": "string",
            "title": "Palmistry Reading Schema Version",
            "description": "Per-kind reading schema version. Bumped on any breaking change to the per-kind wire shape.",
            "default": "v2-palmistry-reading-1.0.0"
          },
          "report_flow": {
            "$ref": "#/components/schemas/PalmistryReportFlowResponse-Input",
            "description": "The structured Palmistry report flow, stored verbatim. A reopen yields the same fields byte-comparable to a fresh report-flow response, including any 'weak' / 'rejected' upload state."
          }
        },
        "type": "object",
        "required": [
          "report_flow"
        ],
        "title": "PalmistryReadingArtifactPayload",
        "description": "Per-kind payload for a Palmistry reading artifact.\n\nThe :attr:`palmistry_reading_schema_version` string is\nthe per-kind reading schema version. The\n:attr:`report_flow` is the same\n:class:`PalmistryReportFlowResponse` the\n``/api/v2/palmistry/report-flow`` route returns \u2014\nstored verbatim, so a reopen is byte-comparable to a\nfresh report-flow response.\n\nA palmistry report-flow response may carry\n``upload.status = \"weak\"`` or ``\"rejected\"``, in which\ncase ``report`` is ``None``. The reopen must surface\nthe same shape byte-comparable to the original\nresponse, including the (possibly empty) report block."
      },
      "PalmistryReadingArtifactPayload-Output": {
        "properties": {
          "palmistry_reading_schema_version": {
            "type": "string",
            "title": "Palmistry Reading Schema Version",
            "description": "Per-kind reading schema version. Bumped on any breaking change to the per-kind wire shape.",
            "default": "v2-palmistry-reading-1.0.0"
          },
          "report_flow": {
            "$ref": "#/components/schemas/PalmistryReportFlowResponse-Output",
            "description": "The structured Palmistry report flow, stored verbatim. A reopen yields the same fields byte-comparable to a fresh report-flow response, including any 'weak' / 'rejected' upload state."
          }
        },
        "type": "object",
        "required": [
          "report_flow"
        ],
        "title": "PalmistryReadingArtifactPayload",
        "description": "Per-kind payload for a Palmistry reading artifact.\n\nThe :attr:`palmistry_reading_schema_version` string is\nthe per-kind reading schema version. The\n:attr:`report_flow` is the same\n:class:`PalmistryReportFlowResponse` the\n``/api/v2/palmistry/report-flow`` route returns \u2014\nstored verbatim, so a reopen is byte-comparable to a\nfresh report-flow response.\n\nA palmistry report-flow response may carry\n``upload.status = \"weak\"`` or ``\"rejected\"``, in which\ncase ``report`` is ``None``. The reopen must surface\nthe same shape byte-comparable to the original\nresponse, including the (possibly empty) report block."
      },
      "PalmistryReportFlowResponse-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-palmistry-report-flow-1.0.0"
          },
          "upload": {
            "$ref": "#/components/schemas/UploadAssessmentOut-Input"
          },
          "report": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PalmReadingReportOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The structured palm reading report. None when upload status is 'weak' or 'rejected'."
          },
          "trust": {
            "$ref": "#/components/schemas/app__schemas__palmistry__TrustMetadataOut"
          },
          "disclaimer": {
            "$ref": "#/components/schemas/app__schemas__palmistry__DisclaimerMetadataOut"
          },
          "interpretation": {
            "$ref": "#/components/schemas/PalmistryInterpretationOut"
          }
        },
        "type": "object",
        "required": [
          "upload",
          "trust",
          "disclaimer",
          "interpretation"
        ],
        "title": "PalmistryReportFlowResponse",
        "description": "Structured v2 Palmistry report-flow response.\n\nComposition contract:\n\n* :attr:`schema_version` is the stable wire identifier.\n* :attr:`upload` is the typed upload assessment; its\n  ``status`` field is the source of truth for the upload\n  verdict.\n* :attr:`report` is the structured palm reading; present\n  when :attr:`upload.status` is ``acceptable``, ``None``\n  otherwise.\n* :attr:`trust` is backend-owned trust metadata; clients\n  render it verbatim and must not regenerate provenance copy.\n* :attr:`disclaimer` is backend-owned disclaimer metadata;\n  the full text lives at\n  :attr:`disclaimer.full_text_endpoint`.\n* :attr:`interpretation` is the optional narrative layer\n  with an explicit\n  :class:`PalmistryInterpretationStatus`. The structured\n  report is unaffected by the interpretation status."
      },
      "PalmistryReportFlowResponse-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-palmistry-report-flow-1.0.0"
          },
          "upload": {
            "$ref": "#/components/schemas/UploadAssessmentOut-Output"
          },
          "report": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PalmReadingReportOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The structured palm reading report. None when upload status is 'weak' or 'rejected'."
          },
          "trust": {
            "$ref": "#/components/schemas/app__schemas__palmistry__TrustMetadataOut"
          },
          "disclaimer": {
            "$ref": "#/components/schemas/app__schemas__palmistry__DisclaimerMetadataOut"
          },
          "interpretation": {
            "$ref": "#/components/schemas/PalmistryInterpretationOut"
          }
        },
        "type": "object",
        "required": [
          "upload",
          "trust",
          "disclaimer",
          "interpretation"
        ],
        "title": "PalmistryReportFlowResponse",
        "description": "Structured v2 Palmistry report-flow response.\n\nComposition contract:\n\n* :attr:`schema_version` is the stable wire identifier.\n* :attr:`upload` is the typed upload assessment; its\n  ``status`` field is the source of truth for the upload\n  verdict.\n* :attr:`report` is the structured palm reading; present\n  when :attr:`upload.status` is ``acceptable``, ``None``\n  otherwise.\n* :attr:`trust` is backend-owned trust metadata; clients\n  render it verbatim and must not regenerate provenance copy.\n* :attr:`disclaimer` is backend-owned disclaimer metadata;\n  the full text lives at\n  :attr:`disclaimer.full_text_endpoint`.\n* :attr:`interpretation` is the optional narrative layer\n  with an explicit\n  :class:`PalmistryInterpretationStatus`. The structured\n  report is unaffected by the interpretation status."
      },
      "PanchangRequest": {
        "properties": {
          "date": {
            "type": "string",
            "title": "Date",
            "description": "DD/MM/YYYY (defaults to today if omitted)"
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude",
            "description": "Latitude supplied by the selected place."
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude",
            "description": "Longitude supplied by the selected place."
          },
          "timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -14.0,
            "title": "Timezone Offset",
            "description": "Timezone offset supplied by the selected place."
          }
        },
        "type": "object",
        "required": [
          "date",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "PanchangRequest"
      },
      "PanchangResponse": {
        "properties": {
          "date": {
            "type": "string",
            "title": "Date"
          },
          "tithi": {
            "type": "string",
            "title": "Tithi"
          },
          "paksha": {
            "type": "string",
            "title": "Paksha"
          },
          "nakshatra": {
            "type": "string",
            "title": "Nakshatra"
          },
          "nakshatra_lord": {
            "type": "string",
            "title": "Nakshatra Lord"
          },
          "yoga": {
            "type": "string",
            "title": "Yoga"
          },
          "karana": {
            "type": "string",
            "title": "Karana"
          },
          "vara": {
            "type": "string",
            "title": "Vara"
          },
          "sunrise_approx": {
            "type": "string",
            "title": "Sunrise Approx"
          },
          "sunset_approx": {
            "type": "string",
            "title": "Sunset Approx"
          },
          "rashi_of_moon": {
            "type": "string",
            "title": "Rashi Of Moon"
          },
          "auspicious": {
            "type": "boolean",
            "title": "Auspicious"
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes"
          }
        },
        "type": "object",
        "required": [
          "date",
          "tithi",
          "paksha",
          "nakshatra",
          "nakshatra_lord",
          "yoga",
          "karana",
          "vara",
          "sunrise_approx",
          "sunset_approx",
          "rashi_of_moon",
          "auspicious",
          "notes"
        ],
        "title": "PanchangResponse"
      },
      "ParticipantStrata": {
        "properties": {
          "language": {
            "type": "string",
            "enum": [
              "english",
              "hindi",
              "hinglish",
              "other"
            ],
            "title": "Language"
          },
          "residence_context": {
            "type": "string",
            "enum": [
              "urban",
              "semi_urban",
              "rural",
              "other",
              "prefer_not_to_say"
            ],
            "title": "Residence Context",
            "default": "prefer_not_to_say"
          },
          "household_structure": {
            "type": "string",
            "enum": [
              "joint",
              "nuclear",
              "multigenerational",
              "living_alone",
              "other",
              "prefer_not_to_say"
            ],
            "title": "Household Structure",
            "default": "prefer_not_to_say"
          },
          "marriage_experience": {
            "type": "string",
            "enum": [
              "never_married",
              "first_marriage",
              "second_or_later_marriage",
              "divorced_or_separated",
              "widowed",
              "prefer_not_to_say"
            ],
            "title": "Marriage Experience",
            "default": "prefer_not_to_say"
          },
          "relationship_stage": {
            "type": "string",
            "enum": [
              "arranged",
              "considering",
              "dating",
              "engaged",
              "married",
              "reconnecting",
              "other"
            ],
            "title": "Relationship Stage",
            "default": "arranged"
          },
          "gender_identity": {
            "type": "string",
            "enum": [
              "woman",
              "man",
              "non_binary",
              "self_described",
              "prefer_not_to_say"
            ],
            "title": "Gender Identity",
            "default": "prefer_not_to_say"
          },
          "sexual_orientation": {
            "type": "string",
            "enum": [
              "heterosexual",
              "gay_or_lesbian",
              "bisexual",
              "asexual",
              "self_described",
              "prefer_not_to_say"
            ],
            "title": "Sexual Orientation",
            "default": "prefer_not_to_say"
          },
          "religion_or_worldview": {
            "type": "string",
            "maxLength": 80,
            "title": "Religion Or Worldview",
            "default": "prefer_not_to_say"
          },
          "caste_or_community_context": {
            "type": "string",
            "maxLength": 80,
            "title": "Caste Or Community Context",
            "default": "prefer_not_to_say"
          },
          "socioeconomic_band": {
            "type": "string",
            "enum": [
              "lower_income",
              "lower_middle",
              "middle",
              "upper_middle",
              "higher_income",
              "prefer_not_to_say"
            ],
            "title": "Socioeconomic Band",
            "default": "prefer_not_to_say"
          },
          "family_structure": {
            "type": "string",
            "maxLength": 80,
            "title": "Family Structure",
            "default": "prefer_not_to_say"
          },
          "disability_status": {
            "type": "string",
            "enum": [
              "disabled",
              "not_disabled",
              "self_described",
              "prefer_not_to_say"
            ],
            "title": "Disability Status",
            "default": "prefer_not_to_say"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "language"
        ],
        "title": "ParticipantStrata",
        "description": "Optional, minimised demographics used for coverage/fairness audits."
      },
      "PartnerComparisonRequest": {
        "properties": {
          "user": {
            "$ref": "#/components/schemas/BirthInput"
          },
          "partners": {
            "items": {
              "$ref": "#/components/schemas/BirthInput"
            },
            "type": "array",
            "maxItems": 5,
            "minItems": 2,
            "title": "Partners"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "user",
          "partners"
        ],
        "title": "PartnerComparisonRequest"
      },
      "PartnerDimensionContext": {
        "properties": {
          "dimension_key": {
            "type": "string",
            "maxLength": 120,
            "title": "Dimension Key",
            "default": "Unknown"
          },
          "band": {
            "type": "string",
            "maxLength": 80,
            "title": "Band",
            "default": "unknown"
          },
          "confidence": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              },
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Confidence"
          },
          "summary": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary"
          }
        },
        "type": "object",
        "title": "PartnerDimensionContext"
      },
      "PartnerEvaluationChatContext": {
        "properties": {
          "schema_version": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40
              },
              {
                "type": "null"
              }
            ],
            "title": "Schema Version"
          },
          "context_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 160
              },
              {
                "type": "null"
              }
            ],
            "title": "Context Id"
          },
          "owner_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner Name"
          },
          "partner_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Partner Name"
          },
          "thread_title": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 160
              },
              {
                "type": "null"
              }
            ],
            "title": "Thread Title"
          },
          "relationship_stage": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Relationship Stage"
          },
          "themes": {
            "items": {
              "$ref": "#/components/schemas/PartnerThemeContext"
            },
            "type": "array",
            "maxItems": 8,
            "title": "Themes"
          },
          "dimension_scores": {
            "items": {
              "$ref": "#/components/schemas/PartnerDimensionContext"
            },
            "type": "array",
            "maxItems": 12,
            "title": "Dimension Scores"
          },
          "chat_context_summary": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 3000
              },
              {
                "type": "null"
              }
            ],
            "title": "Chat Context Summary"
          },
          "action_plan_headline": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Action Plan Headline"
          },
          "action_plan_top_patterns": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 5,
            "title": "Action Plan Top Patterns"
          },
          "answer_count": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Answer Count"
          },
          "evidence_provenance": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "human_reported",
                  "astro_hypothesis",
                  "mixed"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Evidence Provenance"
          },
          "scenario_answers": {
            "items": {
              "$ref": "#/components/schemas/PartnerScenarioAnswerContext"
            },
            "type": "array",
            "maxItems": 60,
            "title": "Scenario Answers"
          }
        },
        "type": "object",
        "title": "PartnerEvaluationChatContext"
      },
      "PartnerInviteCreateRequest": {
        "properties": {
          "partner_display_name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "title": "Partner Display Name"
          },
          "owner_display_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner Display Name"
          },
          "scenario_session_id": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Scenario Session Id"
          },
          "selected_scenario_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Selected Scenario Ids"
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern"
          },
          "expires_in_hours": {
            "type": "integer",
            "maximum": 720.0,
            "minimum": 1.0,
            "title": "Expires In Hours",
            "default": 168
          },
          "scenario_questions": {
            "items": {
              "type": "object"
            },
            "type": "array",
            "title": "Scenario Questions"
          },
          "owner_answers": {
            "items": {
              "type": "object"
            },
            "type": "array",
            "title": "Owner Answers"
          },
          "partner_answers": {
            "items": {
              "type": "object"
            },
            "type": "array",
            "title": "Partner Answers"
          },
          "share_kind": {
            "type": "string",
            "enum": [
              "questions",
              "report"
            ],
            "title": "Share Kind",
            "default": "questions"
          },
          "report_score": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Report Score"
          },
          "report_verdict": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Report Verdict"
          },
          "report_top_risk": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 300
              },
              {
                "type": "null"
              }
            ],
            "title": "Report Top Risk"
          },
          "score_state": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Score State"
          },
          "score_response": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Score Response"
          }
        },
        "type": "object",
        "required": [
          "partner_display_name",
          "scenario_session_id"
        ],
        "title": "PartnerInviteCreateRequest",
        "description": "Request to create a one-time partner invite link."
      },
      "PartnerInviteErrorResponse": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "invite_token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invite Token"
          }
        },
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "title": "PartnerInviteErrorResponse",
        "description": "Error envelope for partner invite endpoints."
      },
      "PartnerInviteOwnerEvidenceUpdateRequest": {
        "properties": {
          "owner_answers": {
            "items": {
              "type": "object"
            },
            "type": "array",
            "title": "Owner Answers"
          },
          "scenario_questions": {
            "anyOf": [
              {
                "items": {
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scenario Questions"
          },
          "score_response": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Score Response"
          },
          "score_state": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Score State"
          }
        },
        "type": "object",
        "title": "PartnerInviteOwnerEvidenceUpdateRequest",
        "description": "Owner-only persistence payload for a completed compatibility run."
      },
      "PartnerInviteResponse": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-partner-invite-1.2.0"
          },
          "invite_token": {
            "type": "string",
            "title": "Invite Token"
          },
          "invite_url": {
            "type": "string",
            "title": "Invite Url"
          },
          "partner_display_name": {
            "type": "string",
            "title": "Partner Display Name"
          },
          "owner_display_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner Display Name"
          },
          "status": {
            "$ref": "#/components/schemas/PartnerInviteStatus"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "expires_at": {
            "type": "string",
            "title": "Expires At"
          },
          "consumed_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Consumed At"
          },
          "scenario_session_id": {
            "type": "string",
            "title": "Scenario Session Id"
          },
          "selected_scenario_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Selected Scenario Ids"
          },
          "scenario_questions": {
            "items": {
              "type": "object"
            },
            "type": "array",
            "title": "Scenario Questions"
          },
          "share_kind": {
            "type": "string",
            "enum": [
              "questions",
              "report"
            ],
            "title": "Share Kind",
            "default": "questions"
          },
          "report_score": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Report Score"
          },
          "report_verdict": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Report Verdict"
          },
          "report_top_risk": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Report Top Risk"
          },
          "score_state": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Score State"
          },
          "score_response": {
            "anyOf": [
              {
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Score Response"
          },
          "user_concern": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Concern"
          }
        },
        "type": "object",
        "required": [
          "invite_token",
          "invite_url",
          "partner_display_name",
          "status",
          "created_at",
          "expires_at",
          "scenario_session_id"
        ],
        "title": "PartnerInviteResponse",
        "description": "Response containing the invite token and metadata."
      },
      "PartnerInviteStatus": {
        "type": "string",
        "enum": [
          "created",
          "opened",
          "answered",
          "expired"
        ],
        "title": "PartnerInviteStatus"
      },
      "PartnerInviteSubmitRequest": {
        "properties": {
          "answers": {
            "items": {
              "type": "object"
            },
            "type": "array",
            "minItems": 1,
            "title": "Answers"
          }
        },
        "type": "object",
        "required": [
          "answers"
        ],
        "title": "PartnerInviteSubmitRequest",
        "description": "Partner submits their answers via the invite token."
      },
      "PartnerInviteSubmitResponse": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-partner-invite-1.2.0"
          },
          "invite_token": {
            "type": "string",
            "title": "Invite Token"
          },
          "status": {
            "$ref": "#/components/schemas/PartnerInviteStatus"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "compatibility_artifact_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Compatibility Artifact Id"
          },
          "partner_display_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Partner Display Name"
          }
        },
        "type": "object",
        "required": [
          "invite_token",
          "status",
          "message"
        ],
        "title": "PartnerInviteSubmitResponse",
        "description": "Response after partner submits answers."
      },
      "PartnerProfile": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable profile id (UUID)."
          },
          "user_id": {
            "type": "string",
            "title": "User Id",
            "description": "Owning user id (account-scoped)."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Partner's display name."
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "Birth date as DD/MM/YYYY."
          },
          "birth_time": {
            "type": "string",
            "title": "Birth Time",
            "description": "Birth time as HH:MM."
          },
          "place_name": {
            "type": "string",
            "title": "Place Name",
            "description": "Birth place name (free text)."
          },
          "latitude": {
            "type": "string",
            "title": "Latitude",
            "description": "Birth place latitude (string)."
          },
          "longitude": {
            "type": "string",
            "title": "Longitude",
            "description": "Birth place longitude (string)."
          },
          "timezone_offset": {
            "type": "string",
            "title": "Timezone Offset",
            "description": "Timezone offset as a string (e.g. '5.5')."
          },
          "gender": {
            "type": "string",
            "title": "Gender",
            "description": "Partner's gender.",
            "default": ""
          },
          "self_orientation": {
            "type": "string",
            "title": "Self Orientation",
            "default": "unsure"
          },
          "family_orientation": {
            "type": "string",
            "title": "Family Orientation",
            "default": "unknown"
          },
          "decision_style": {
            "type": "string",
            "title": "Decision Style",
            "default": "unsure"
          },
          "living_preference": {
            "type": "string",
            "title": "Living Preference",
            "default": "undecided"
          },
          "career_priority": {
            "type": "string",
            "title": "Career Priority",
            "default": "undecided"
          },
          "ritual_practice": {
            "type": "string",
            "title": "Ritual Practice",
            "default": "mixed"
          },
          "social_boundary_comfort": {
            "type": "string",
            "title": "Social Boundary Comfort",
            "default": ""
          },
          "is_draft": {
            "type": "boolean",
            "title": "Is Draft",
            "description": "When True, the profile may have incomplete birth data and is clearly labeled as a draft. When False, the service validates that all required birth-data fields are present.",
            "default": false
          },
          "last_compared_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Compared At",
            "description": "ISO timestamp of the last compatibility comparison that used this profile. Updated by the caller via the edit endpoint."
          },
          "last_report_artifact_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Report Artifact Id",
            "description": "Id of the last saved compatibility report artifact that used this profile. Lets the UI re-open the last report without re-selecting."
          },
          "saved_at": {
            "type": "string",
            "title": "Saved At",
            "description": "ISO timestamp when first saved."
          },
          "updated_at": {
            "type": "string",
            "title": "Updated At",
            "description": "ISO timestamp of last update."
          }
        },
        "type": "object",
        "required": [
          "id",
          "user_id",
          "name",
          "birth_date",
          "birth_time",
          "place_name",
          "latitude",
          "longitude",
          "timezone_offset",
          "saved_at",
          "updated_at"
        ],
        "title": "PartnerProfile",
        "description": "A saved partner birth-data profile, account-scoped.\n\nMirrors the frontend ``SavedCompatibilityProfile`` with server-side\nadditions (``user_id``, ``last_compared_at``,\n``last_report_artifact_id``, ``is_draft``)."
      },
      "PartnerProfileErrorResponse": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          }
        },
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "title": "PartnerProfileErrorResponse",
        "description": "Error response shape."
      },
      "PartnerProfileListResponse": {
        "properties": {
          "profiles": {
            "items": {
              "$ref": "#/components/schemas/PartnerProfile"
            },
            "type": "array",
            "title": "Profiles"
          },
          "total": {
            "type": "integer",
            "title": "Total"
          }
        },
        "type": "object",
        "required": [
          "profiles",
          "total"
        ],
        "title": "PartnerProfileListResponse",
        "description": "Response for the list endpoint."
      },
      "PartnerProfileSaveRequest": {
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Id",
            "description": "Profile id. Omit to create a new profile."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Partner's display name."
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "DD/MM/YYYY."
          },
          "birth_time": {
            "type": "string",
            "title": "Birth Time",
            "description": "HH:MM."
          },
          "place_name": {
            "type": "string",
            "title": "Place Name",
            "description": "Birth place name."
          },
          "latitude": {
            "type": "string",
            "title": "Latitude",
            "description": "Latitude string."
          },
          "longitude": {
            "type": "string",
            "title": "Longitude",
            "description": "Longitude string."
          },
          "timezone_offset": {
            "type": "string",
            "title": "Timezone Offset",
            "description": "Timezone offset string."
          },
          "gender": {
            "type": "string",
            "title": "Gender",
            "default": ""
          },
          "self_orientation": {
            "type": "string",
            "title": "Self Orientation",
            "default": "unsure"
          },
          "family_orientation": {
            "type": "string",
            "title": "Family Orientation",
            "default": "unknown"
          },
          "decision_style": {
            "type": "string",
            "title": "Decision Style",
            "default": "unsure"
          },
          "living_preference": {
            "type": "string",
            "title": "Living Preference",
            "default": "undecided"
          },
          "career_priority": {
            "type": "string",
            "title": "Career Priority",
            "default": "undecided"
          },
          "ritual_practice": {
            "type": "string",
            "title": "Ritual Practice",
            "default": "mixed"
          },
          "social_boundary_comfort": {
            "type": "string",
            "title": "Social Boundary Comfort",
            "default": ""
          },
          "is_draft": {
            "type": "boolean",
            "title": "Is Draft",
            "description": "When True, incomplete birth data is allowed (the profile is labeled as a draft). When False, the service validates that all required birth-data fields are present and non-empty.",
            "default": false
          },
          "last_compared_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Compared At"
          },
          "last_report_artifact_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Report Artifact Id"
          }
        },
        "type": "object",
        "required": [
          "name",
          "birth_date",
          "birth_time",
          "place_name",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "PartnerProfileSaveRequest",
        "description": "Request body for creating or updating a partner profile.\n\nWhen ``id`` is omitted the service creates a new profile. When\n``id`` is present the service updates the existing profile (if\nowned by the authenticated user)."
      },
      "PartnerScenarioAnswerContext": {
        "properties": {
          "question_id": {
            "type": "string",
            "maxLength": 160,
            "title": "Question Id",
            "default": ""
          },
          "question_title": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 300
              },
              {
                "type": "null"
              }
            ],
            "title": "Question Title"
          },
          "question": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Question"
          },
          "selected_option": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 20
              },
              {
                "type": "null"
              }
            ],
            "title": "Selected Option"
          },
          "selected_option_text": {
            "type": "string",
            "maxLength": 1000,
            "title": "Selected Option Text",
            "default": ""
          },
          "perspective": {
            "type": "string",
            "maxLength": 40,
            "title": "Perspective",
            "default": "self"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "response_source": {
            "type": "string",
            "enum": [
              "human",
              "astro_hypothesis"
            ],
            "title": "Response Source",
            "default": "human"
          },
          "observed_or_guessed": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "observed",
                  "guessed",
                  "not_enough_info"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Observed Or Guessed"
          },
          "observation_frequency": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "rarely",
                  "sometimes",
                  "often",
                  "always"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Observation Frequency"
          }
        },
        "type": "object",
        "title": "PartnerScenarioAnswerContext"
      },
      "PartnerThemeContext": {
        "properties": {
          "theme_id": {
            "type": "string",
            "maxLength": 120,
            "title": "Theme Id",
            "default": ""
          },
          "label": {
            "type": "string",
            "maxLength": 200,
            "title": "Label",
            "default": "Unknown"
          },
          "target": {
            "type": "string",
            "maxLength": 40,
            "title": "Target",
            "default": "self"
          }
        },
        "type": "object",
        "title": "PartnerThemeContext"
      },
      "PaymentStatusResponse": {
        "properties": {
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "access_tier": {
            "type": "string",
            "title": "Access Tier"
          },
          "access_expires_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Expires At"
          },
          "subscription_status": {
            "type": "string",
            "title": "Subscription Status"
          },
          "payment_provider": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Provider"
          },
          "payment_customer_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Customer Id"
          },
          "payment_subscription_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Subscription Id"
          },
          "last_payment_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Payment At"
          },
          "plan": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Plan"
          },
          "recurring_amount": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Recurring Amount"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency"
          },
          "next_billing_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Billing Date"
          },
          "cancel_at_next_billing_date": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancel At Next Billing Date"
          },
          "auto_renew": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Auto Renew"
          },
          "payment_frequency_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Frequency Count"
          },
          "payment_frequency_interval": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Frequency Interval"
          },
          "provider_environment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Provider Environment"
          },
          "scheduled_plan": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scheduled Plan"
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "access_tier",
          "subscription_status"
        ],
        "title": "PaymentStatusResponse"
      },
      "PersonPattern": {
        "properties": {
          "dominant_trait": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dominant Trait",
            "description": "Human-readable trait label for this person."
          },
          "evidence": {
            "type": "string",
            "title": "Evidence",
            "description": "Short excerpt of the answer that supports this trait.",
            "default": ""
          },
          "sample_count": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Sample Count",
            "description": "Number of answers this person has for this dimension.",
            "default": 0
          }
        },
        "type": "object",
        "title": "PersonPattern",
        "description": "One person's pattern for a single dimension."
      },
      "PersonaResponse": {
        "properties": {
          "persona_type": {
            "type": "string",
            "title": "Persona Type"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "title": {
            "type": "string",
            "title": "Title"
          },
          "description": {
            "type": "string",
            "title": "Description"
          },
          "greeting": {
            "type": "string",
            "title": "Greeting"
          },
          "color_palette": {
            "type": "object",
            "title": "Color Palette"
          },
          "specialties": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Specialties"
          }
        },
        "type": "object",
        "required": [
          "persona_type",
          "name",
          "title",
          "description",
          "greeting",
          "color_palette",
          "specialties"
        ],
        "title": "PersonaResponse",
        "description": "Response with persona information."
      },
      "PersonaType": {
        "type": "string",
        "enum": [
          "sage",
          "caregiver",
          "magician",
          "sarvajna"
        ],
        "title": "PersonaType",
        "description": "Available AI persona types."
      },
      "PilotResponseSubmission": {
        "properties": {
          "participant_token": {
            "type": "string",
            "title": "Participant Token"
          },
          "item_id": {
            "type": "string",
            "title": "Item Id"
          },
          "item_version": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Item Version"
          },
          "selected_option": {
            "type": "string",
            "title": "Selected Option"
          },
          "response_ms": {
            "type": "integer",
            "maximum": 7200000.0,
            "minimum": 100.0,
            "title": "Response Ms"
          },
          "answer_changed": {
            "type": "boolean",
            "title": "Answer Changed",
            "default": false
          },
          "comprehension_check_passed": {
            "type": "boolean",
            "title": "Comprehension Check Passed"
          },
          "impression_management_concern": {
            "type": "boolean",
            "title": "Impression Management Concern",
            "default": false
          },
          "strata": {
            "$ref": "#/components/schemas/ParticipantStrata"
          },
          "consent_version": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Consent Version"
          },
          "wave": {
            "type": "integer",
            "maximum": 20.0,
            "minimum": 1.0,
            "title": "Wave",
            "default": 1
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "participant_token",
          "item_id",
          "item_version",
          "selected_option",
          "response_ms",
          "comprehension_check_passed",
          "strata",
          "consent_version"
        ],
        "title": "PilotResponseSubmission"
      },
      "PlaceSearchErrorResponse": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error"
          },
          "message": {
            "type": "string",
            "title": "Message"
          }
        },
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "title": "PlaceSearchErrorResponse",
        "description": "Typed error envelope for the places search surface."
      },
      "PlaceSearchResponse": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-places-search-1.0.0"
          },
          "query": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Query"
          },
          "results": {
            "items": {
              "$ref": "#/components/schemas/PlaceSearchResult"
            },
            "type": "array",
            "title": "Results"
          },
          "count": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Count"
          }
        },
        "type": "object",
        "required": [
          "query",
          "count"
        ],
        "title": "PlaceSearchResponse",
        "description": "Top-level response for ``GET /api/v2/places/search``.\n\nThe list is bounded to 5 entries to keep the response small.\n``count`` mirrors ``len(results)`` so a client can paginate or\nbranch without re-counting the array."
      },
      "PlaceSearchResult": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 240,
            "minLength": 1,
            "title": "Name"
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude"
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude"
          },
          "timezone_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Id",
            "description": "IANA timezone id (preferred by the engine)."
          },
          "timezone_offset": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 14.0,
                "minimum": -12.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Offset",
            "description": "UTC offset in hours derived from timezone_id, for client-side birth-time autofill."
          },
          "country_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2,
                "minLength": 2
              },
              {
                "type": "null"
              }
            ],
            "title": "Country Code",
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "admin_area": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Admin Area",
            "description": "Admin level 1 region (state/province)."
          }
        },
        "type": "object",
        "required": [
          "name",
          "latitude",
          "longitude"
        ],
        "title": "PlaceSearchResult",
        "description": "One autocomplete candidate from the places service.\n\n``name`` is the human-readable, fully-qualified label\n(e.g. \"Lalitpur, Uttar Pradesh, India\"). ``latitude`` and\n``longitude`` are decimal degrees. ``timezone_id`` is the IANA\nidentifier the engine prefers (e.g. ``Asia/Kolkata``); the route\nfills it from Google when available and falls back to a derived\nvalue otherwise. ``timezone_offset`` is the UTC offset in hours\n(e.g. ``5.5`` for IST) derived from ``timezone_id`` so the client\ncan autofill the birth-time offset without a local IANA table.",
        "example": {
          "admin_area": "Uttar Pradesh",
          "country_code": "IN",
          "latitude": 24.6877,
          "longitude": 78.411,
          "name": "Lalitpur, Uttar Pradesh, India",
          "timezone_id": "Asia/Kolkata",
          "timezone_offset": 5.5
        }
      },
      "PlanChangePreviewResponse": {
        "properties": {
          "target_plan": {
            "type": "string",
            "title": "Target Plan"
          },
          "immediate_charge": {
            "type": "integer",
            "title": "Immediate Charge"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "recurring_amount": {
            "type": "integer",
            "title": "Recurring Amount"
          },
          "next_billing_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Billing Date"
          }
        },
        "type": "object",
        "required": [
          "target_plan",
          "immediate_charge",
          "currency",
          "recurring_amount"
        ],
        "title": "PlanChangePreviewResponse"
      },
      "PlanChangeRequest": {
        "properties": {
          "plan": {
            "type": "string",
            "pattern": "^(monthly|quarterly|semiannual|annual)$",
            "title": "Plan"
          }
        },
        "type": "object",
        "required": [
          "plan"
        ],
        "title": "PlanChangeRequest"
      },
      "PlanetaryAspectOut": {
        "properties": {
          "aspecting_planet": {
            "type": "string",
            "title": "Aspecting Planet"
          },
          "aspecting_house": {
            "type": "integer",
            "title": "Aspecting House"
          },
          "aspected_house": {
            "type": "integer",
            "title": "Aspected House"
          },
          "aspected_sign": {
            "type": "string",
            "title": "Aspected Sign"
          },
          "aspect_type": {
            "type": "string",
            "title": "Aspect Type"
          },
          "aspected_planets": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Aspected Planets"
          }
        },
        "type": "object",
        "required": [
          "aspecting_planet",
          "aspecting_house",
          "aspected_house",
          "aspected_sign",
          "aspect_type",
          "aspected_planets"
        ],
        "title": "PlanetaryAspectOut"
      },
      "PlanetaryPositionOut": {
        "properties": {
          "planet": {
            "type": "string",
            "title": "Planet"
          },
          "longitude_sidereal": {
            "type": "number",
            "title": "Longitude Sidereal"
          },
          "sign": {
            "type": "string",
            "title": "Sign"
          },
          "degree_in_sign": {
            "type": "number",
            "title": "Degree In Sign"
          },
          "house": {
            "type": "integer",
            "title": "House"
          },
          "nakshatra": {
            "type": "string",
            "title": "Nakshatra"
          },
          "nakshatra_pada": {
            "type": "integer",
            "title": "Nakshatra Pada"
          },
          "nakshatra_lord": {
            "type": "string",
            "title": "Nakshatra Lord"
          },
          "is_retrograde": {
            "type": "boolean",
            "title": "Is Retrograde"
          },
          "is_borderline": {
            "type": "boolean",
            "title": "Is Borderline",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "planet",
          "longitude_sidereal",
          "sign",
          "degree_in_sign",
          "house",
          "nakshatra",
          "nakshatra_pada",
          "nakshatra_lord",
          "is_retrograde"
        ],
        "title": "PlanetaryPositionOut"
      },
      "ProfileUpdateRequest": {
        "properties": {
          "display_name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 2,
            "title": "Display Name"
          },
          "bio": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 400
              },
              {
                "type": "null"
              }
            ],
            "title": "Bio"
          },
          "location": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Location"
          },
          "avatar_url": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Avatar Url"
          },
          "birth_date": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Date"
          },
          "birth_time": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^\\d{2}:\\d{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Time"
          },
          "birth_place": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 160
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Place"
          },
          "birth_latitude": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 90.0,
                "minimum": -90.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Latitude"
          },
          "birth_longitude": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 180.0,
                "minimum": -180.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Longitude"
          },
          "birth_timezone_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Timezone Id"
          },
          "birth_timezone_offset": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 14.0,
                "minimum": -12.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Birth Timezone Offset"
          }
        },
        "type": "object",
        "required": [
          "display_name"
        ],
        "title": "ProfileUpdateRequest"
      },
      "QualityAssessmentOut": {
        "properties": {
          "quality_grade": {
            "$ref": "#/components/schemas/PalmImageQualityGrade"
          },
          "quality_score": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Quality Score",
            "description": "Overall quality score in [0.0, 1.0]. Higher is better. Backend-local computation; the VLM may further downgrade."
          },
          "resolution_acceptable": {
            "type": "boolean",
            "title": "Resolution Acceptable",
            "description": "True when both dimensions meet the minimum threshold."
          },
          "aspect_ratio_acceptable": {
            "type": "boolean",
            "title": "Aspect Ratio Acceptable",
            "description": "True when the aspect ratio is in the palm-photo range."
          },
          "format_acceptable": {
            "type": "boolean",
            "title": "Format Acceptable",
            "description": "True when the file format is supported."
          },
          "is_palm_image": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Palm Image",
            "description": "True when the VLM confirms the image contains a palm. None when the VLM did not run (e.g. upload was rejected at the file level)."
          },
          "issues": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Issues",
            "description": "Human-readable descriptions of any quality issues. Empty when the upload is acceptable."
          },
          "recommendations": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Recommendations",
            "description": "Backend-owned retry guidance. UI renders this verbatim."
          }
        },
        "type": "object",
        "required": [
          "quality_grade",
          "quality_score",
          "resolution_acceptable",
          "aspect_ratio_acceptable",
          "format_acceptable"
        ],
        "title": "QualityAssessmentOut",
        "description": "Backend-owned image quality assessment.\n\nThe backend-local half of the assessment is fully\ndeterministic: the score, the boolean checks, and the\nissue list are derived from the upload bytes alone \u2014 no VLM\ncall is required. The :attr:`is_palm_image` field is\npopulated by the VLM and is the only field that depends on\nthe vision model."
      },
      "QualityRequest": {
        "properties": {
          "satisfaction": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Satisfaction",
            "default": 50
          },
          "commitment": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Commitment",
            "default": 50
          },
          "intimacy": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Intimacy",
            "default": 50
          },
          "trust": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Trust",
            "default": 50
          },
          "passion": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Passion",
            "default": 50
          },
          "love": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Love",
            "default": 50
          },
          "safety": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Safety",
            "default": 50
          },
          "cohesion": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Cohesion",
            "default": 50
          },
          "acceptance": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Acceptance",
            "default": 50
          },
          "appreciation": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Appreciation",
            "default": 50
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "QualityRequest"
      },
      "ReadinessReport": {
        "properties": {
          "study_id": {
            "type": "string",
            "title": "Study Id"
          },
          "protocol_version": {
            "type": "string",
            "title": "Protocol Version",
            "default": "compatibility-validation-1.0.0"
          },
          "bank_version": {
            "type": "string",
            "title": "Bank Version"
          },
          "bank_fingerprint": {
            "type": "string",
            "title": "Bank Fingerprint"
          },
          "evidence_snapshot_hash": {
            "type": "string",
            "title": "Evidence Snapshot Hash"
          },
          "stages": {
            "type": "object",
            "title": "Stages"
          },
          "production_claim_allowed": {
            "type": "boolean",
            "title": "Production Claim Allowed"
          },
          "validated_scope": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Validated Scope"
          },
          "predictive_validity_claim_allowed": {
            "type": "boolean",
            "title": "Predictive Validity Claim Allowed",
            "default": false
          },
          "marriage_outcome_probability_allowed": {
            "type": "boolean",
            "title": "Marriage Outcome Probability Allowed",
            "default": false
          },
          "dif_claim_allowed": {
            "type": "boolean",
            "title": "Dif Claim Allowed",
            "default": false
          },
          "blockers": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Blockers"
          },
          "non_claims": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Non Claims"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "study_id",
          "bank_version",
          "bank_fingerprint",
          "evidence_snapshot_hash",
          "stages",
          "production_claim_allowed"
        ],
        "title": "ReadinessReport"
      },
      "ReadingArtifact-Input": {
        "properties": {
          "artifact_id": {
            "type": "string",
            "title": "Artifact Id",
            "description": "Stable uuid identifying the persisted artifact."
          },
          "user_id": {
            "type": "string",
            "maxLength": 128,
            "minLength": 1,
            "title": "User Id",
            "description": "Owning user id. Used to scope reads."
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id",
            "description": "Owning session id (chat thread). Optional. When set, the artifact is bound to that session."
          },
          "history_schema_version": {
            "type": "string",
            "title": "History Schema Version",
            "description": "Persistence-envelope version. Bumped on any breaking change to the artifact wire shape.",
            "default": "v2-readings-history-1.0.0"
          },
          "created_at": {
            "type": "string",
            "title": "Created At",
            "description": "ISO-8601 UTC timestamp at which the artifact was persisted. Wall-clock; not part of the byte-comparable contract."
          },
          "kind": {
            "$ref": "#/components/schemas/ReadingKind",
            "description": "Closed-literal discriminator that decides which per-kind payload field is set on this artifact."
          },
          "summary": {
            "$ref": "#/components/schemas/ReadingArtifactSummary"
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/ReadingInterpretationStatus",
            "description": "Cross-kind interpretation status mirror. Matches the per-kind report-flow interpretation status so thread previews can render the honest availability state without loading the payload."
          },
          "kundli_payload": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KundliReadingArtifactPayload-Input"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per-kind payload when ``kind == 'kundli'``. ``None`` otherwise."
          },
          "palmistry_payload": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PalmistryReadingArtifactPayload-Input"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per-kind payload when ``kind == 'palmistry'``. ``None`` otherwise."
          }
        },
        "type": "object",
        "required": [
          "artifact_id",
          "user_id",
          "created_at",
          "kind",
          "summary",
          "interpretation_status"
        ],
        "title": "ReadingArtifact",
        "description": "Persisted envelope for a single reading.\n\nField set is the deterministic per-kind report-flow\npayload plus the persistence metadata needed to reopen\nthe reading without recomputation:\n\n* :attr:`artifact_id` is a stable uuid so the same\n  stored report-flow can be reopened across sessions and\n  across client reloads.\n* :attr:`user_id` and :attr:`session_id` scope the\n  artifact so one account cannot read another account's\n  readings.\n* :attr:`history_schema_version` is the\n  persistence-envelope version (this module's\n  contract).\n* :attr:`created_at` is the wall-clock time the\n  artifact was persisted (ISO-8601, UTC, ``Z`` suffix).\n* :attr:`kind` is the closed-literal discriminator that\n  decides which per-kind payload field is set.\n* :attr:`summary` is a short preview block for thread\n  rendering.\n* :attr:`interpretation_status` is the cross-kind\n  interpretation status mirror.\n* :attr:`kundli_payload` and :attr:`palmistry_payload`\n  are the per-kind payload blocks. Exactly one is\n  set, matching :attr:`kind`. The model validator\n  enforces the cross-field invariant."
      },
      "ReadingArtifact-Output": {
        "properties": {
          "artifact_id": {
            "type": "string",
            "title": "Artifact Id",
            "description": "Stable uuid identifying the persisted artifact."
          },
          "user_id": {
            "type": "string",
            "maxLength": 128,
            "minLength": 1,
            "title": "User Id",
            "description": "Owning user id. Used to scope reads."
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id",
            "description": "Owning session id (chat thread). Optional. When set, the artifact is bound to that session."
          },
          "history_schema_version": {
            "type": "string",
            "title": "History Schema Version",
            "description": "Persistence-envelope version. Bumped on any breaking change to the artifact wire shape.",
            "default": "v2-readings-history-1.0.0"
          },
          "created_at": {
            "type": "string",
            "title": "Created At",
            "description": "ISO-8601 UTC timestamp at which the artifact was persisted. Wall-clock; not part of the byte-comparable contract."
          },
          "kind": {
            "$ref": "#/components/schemas/ReadingKind",
            "description": "Closed-literal discriminator that decides which per-kind payload field is set on this artifact."
          },
          "summary": {
            "$ref": "#/components/schemas/ReadingArtifactSummary"
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/ReadingInterpretationStatus",
            "description": "Cross-kind interpretation status mirror. Matches the per-kind report-flow interpretation status so thread previews can render the honest availability state without loading the payload."
          },
          "kundli_payload": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KundliReadingArtifactPayload-Output"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per-kind payload when ``kind == 'kundli'``. ``None`` otherwise."
          },
          "palmistry_payload": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PalmistryReadingArtifactPayload-Output"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per-kind payload when ``kind == 'palmistry'``. ``None`` otherwise."
          }
        },
        "type": "object",
        "required": [
          "artifact_id",
          "user_id",
          "created_at",
          "kind",
          "summary",
          "interpretation_status"
        ],
        "title": "ReadingArtifact",
        "description": "Persisted envelope for a single reading.\n\nField set is the deterministic per-kind report-flow\npayload plus the persistence metadata needed to reopen\nthe reading without recomputation:\n\n* :attr:`artifact_id` is a stable uuid so the same\n  stored report-flow can be reopened across sessions and\n  across client reloads.\n* :attr:`user_id` and :attr:`session_id` scope the\n  artifact so one account cannot read another account's\n  readings.\n* :attr:`history_schema_version` is the\n  persistence-envelope version (this module's\n  contract).\n* :attr:`created_at` is the wall-clock time the\n  artifact was persisted (ISO-8601, UTC, ``Z`` suffix).\n* :attr:`kind` is the closed-literal discriminator that\n  decides which per-kind payload field is set.\n* :attr:`summary` is a short preview block for thread\n  rendering.\n* :attr:`interpretation_status` is the cross-kind\n  interpretation status mirror.\n* :attr:`kundli_payload` and :attr:`palmistry_payload`\n  are the per-kind payload blocks. Exactly one is\n  set, matching :attr:`kind`. The model validator\n  enforces the cross-field invariant."
      },
      "ReadingArtifactListItem-Input": {
        "properties": {
          "artifact_id": {
            "type": "string",
            "title": "Artifact Id"
          },
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          },
          "history_schema_version": {
            "type": "string",
            "title": "History Schema Version",
            "default": "v2-readings-history-1.0.0"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "kind": {
            "$ref": "#/components/schemas/ReadingKind"
          },
          "summary": {
            "$ref": "#/components/schemas/ReadingArtifactSummary"
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/ReadingInterpretationStatus"
          }
        },
        "type": "object",
        "required": [
          "artifact_id",
          "user_id",
          "created_at",
          "kind",
          "summary",
          "interpretation_status"
        ],
        "title": "ReadingArtifactListItem",
        "description": "One entry in a readings list response.\n\nCarries the preview block, the cross-kind interpretation\nstatus, the identity fields, and the closed-literal\n``kind`` discriminator \u2014 but **not** the per-kind\npayload. A client opens the full reading through a\nfollow-up read by ``artifact_id``. The :attr:`kind`\nfield is mirrored on the list item so a client can\nbranch on it without loading the artifact envelope."
      },
      "ReadingArtifactListItem-Output": {
        "properties": {
          "artifact_id": {
            "type": "string",
            "title": "Artifact Id"
          },
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          },
          "history_schema_version": {
            "type": "string",
            "title": "History Schema Version",
            "default": "v2-readings-history-1.0.0"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "kind": {
            "$ref": "#/components/schemas/ReadingKind"
          },
          "summary": {
            "$ref": "#/components/schemas/ReadingArtifactSummary"
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/ReadingInterpretationStatus"
          }
        },
        "type": "object",
        "required": [
          "artifact_id",
          "user_id",
          "created_at",
          "kind",
          "summary",
          "interpretation_status"
        ],
        "title": "ReadingArtifactListItem",
        "description": "One entry in a readings list response.\n\nCarries the preview block, the cross-kind interpretation\nstatus, the identity fields, and the closed-literal\n``kind`` discriminator \u2014 but **not** the per-kind\npayload. A client opens the full reading through a\nfollow-up read by ``artifact_id``. The :attr:`kind`\nfield is mirrored on the list item so a client can\nbranch on it without loading the artifact envelope."
      },
      "ReadingArtifactListResponse-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-readings-history-1.0.0"
          },
          "artifacts": {
            "items": {
              "$ref": "#/components/schemas/ReadingArtifactListItem-Input"
            },
            "type": "array",
            "title": "Artifacts"
          },
          "count": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Count",
            "description": "Number of artifacts returned. Mirrors ``len(artifacts)`` so a client can paginate without trusting the array length under concurrent writes."
          }
        },
        "type": "object",
        "required": [
          "count"
        ],
        "title": "ReadingArtifactListResponse",
        "description": "v2 readings list response wrapper.\n\nNewest artifact first (sorted by ``created_at``\ndescending at the service boundary). The list is\nuser-scoped: a caller can only see artifacts belonging\nto the user they authenticate as. Session filtering and\nkind filtering are additive \u2014 the list is filtered by\n``session_id`` and/or ``kind`` when the caller\nprovides them. The :attr:`count` field mirrors\n``len(artifacts)`` so a client can paginate without\ntrusting the array length under concurrent writes."
      },
      "ReadingArtifactListResponse-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-readings-history-1.0.0"
          },
          "artifacts": {
            "items": {
              "$ref": "#/components/schemas/ReadingArtifactListItem-Output"
            },
            "type": "array",
            "title": "Artifacts"
          },
          "count": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Count",
            "description": "Number of artifacts returned. Mirrors ``len(artifacts)`` so a client can paginate without trusting the array length under concurrent writes."
          }
        },
        "type": "object",
        "required": [
          "count"
        ],
        "title": "ReadingArtifactListResponse",
        "description": "v2 readings list response wrapper.\n\nNewest artifact first (sorted by ``created_at``\ndescending at the service boundary). The list is\nuser-scoped: a caller can only see artifacts belonging\nto the user they authenticate as. Session filtering and\nkind filtering are additive \u2014 the list is filtered by\n``session_id`` and/or ``kind`` when the caller\nprovides them. The :attr:`count` field mirrors\n``len(artifacts)`` so a client can paginate without\ntrusting the array length under concurrent writes."
      },
      "ReadingArtifactResponse-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-readings-history-1.0.0"
          },
          "artifact": {
            "$ref": "#/components/schemas/ReadingArtifact-Input"
          }
        },
        "type": "object",
        "required": [
          "artifact"
        ],
        "title": "ReadingArtifactResponse",
        "description": "v2 readings read response wrapper.\n\nThe :attr:`schema_version` is the persistence-envelope\nversion. A client should compare the artifact's\nper-kind schema version to the live per-kind contract\nbefore reopening to confirm byte-comparability."
      },
      "ReadingArtifactResponse-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-readings-history-1.0.0"
          },
          "artifact": {
            "$ref": "#/components/schemas/ReadingArtifact-Output"
          }
        },
        "type": "object",
        "required": [
          "artifact"
        ],
        "title": "ReadingArtifactResponse",
        "description": "v2 readings read response wrapper.\n\nThe :attr:`schema_version` is the persistence-envelope\nversion. A client should compare the artifact's\nper-kind schema version to the live per-kind contract\nbefore reopening to confirm byte-comparability."
      },
      "ReadingArtifactSaveRequest": {
        "properties": {
          "session_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id",
            "description": "Owning session id (chat thread). Optional. When set, the artifact is bound to that session."
          },
          "summary_text": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 400
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary Text",
            "description": "Optional single-sentence summary for the thread preview. When omitted, the service derives one from the per-kind report-flow payload so the thread preview remains useful even if the client forgot to pass one."
          },
          "kind": {
            "$ref": "#/components/schemas/ReadingKind",
            "description": "Closed-literal discriminator. Decides which per-kind report-flow field is expected to be set on this save request and which per-kind payload block the persisted envelope will carry."
          },
          "kundli_report_flow": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KundliReportFlowResponse-Input"
              },
              {
                "type": "null"
              }
            ],
            "description": "The structured Kundli report-flow payload to persist. Required when ``kind == 'kundli'``; must be ``None`` otherwise. The service copies the report-flow verbatim into the artifact envelope."
          },
          "palmistry_report_flow": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PalmistryReportFlowResponse-Input"
              },
              {
                "type": "null"
              }
            ],
            "description": "The structured Palmistry report-flow payload to persist. Required when ``kind == 'palmistry'``; must be ``None`` otherwise. The service copies the report-flow verbatim into the artifact envelope, including any 'weak' / 'rejected' upload state."
          }
        },
        "type": "object",
        "required": [
          "kind"
        ],
        "title": "ReadingArtifactSaveRequest",
        "description": "Save request body.\n\nThe caller supplies the closed-literal :attr:`kind`\ndiscriminator and exactly one of the per-kind\nreport-flow fields (:attr:`kundli_report_flow` or\n:attr:`palmistry_report_flow`). The service is\nresponsible for shaping the supplied report-flow into\nthe persisted envelope and stamping the persistence\nmetadata; the route layer authenticates the caller and\nforwards the body.\n\nThe wire contract is intentionally **additive**: the\ncaller sends the report-flow in the same shape the\ncorresponding report-flow endpoint returned it. The\nservice copies the payload verbatim into the artifact\nenvelope so a reopen yields the same fields\nbyte-comparable to the live report-flow contract.\n\n:attr:`summary_text` is optional; when omitted, the\nservice derives a single-sentence summary from the\nper-kind report-flow so the thread preview remains\nuseful even if the client forgot to pass one."
      },
      "ReadingArtifactSummary": {
        "properties": {
          "summary_text": {
            "type": "string",
            "maxLength": 400,
            "title": "Summary Text",
            "description": "Single-sentence human-readable summary for thread preview. \u2264 400 chars. Render verbatim."
          },
          "subject_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subject Label",
            "description": "Cross-kind subject label. For Kundli, the subject's name from the report input. For Palmistry, a stable 'Palm reading' placeholder so the preview renders even when the caller did not pass a label."
          },
          "reading_kind": {
            "$ref": "#/components/schemas/ReadingKind",
            "description": "The kind discriminator. Mirrors the artifact's ``kind`` field so a list item can be rendered without loading the artifact envelope."
          },
          "preview": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Preview",
            "description": "Up to three short bullet previews. For Kundli this carries the ascendant, moon sign, and a short interpretation status label; for Palmistry this carries the upload status and (when present) a short report highlight. Render verbatim."
          },
          "interpretation_status": {
            "$ref": "#/components/schemas/ReadingInterpretationStatus",
            "description": "Cross-kind interpretation status mirror. Matches the per-kind report-flow interpretation status so thread previews can render the honest availability state without loading the full payload."
          }
        },
        "type": "object",
        "required": [
          "summary_text",
          "reading_kind",
          "interpretation_status"
        ],
        "title": "ReadingArtifactSummary",
        "description": "Short preview block for a persisted reading artifact.\n\nSurfaced in thread previews so a caller can tell at a\nglance what a stored artifact is without loading the\nper-kind report-flow payload. The :attr:`summary_text`\nis a single-sentence human-readable line suitable for\nchat-history rendering; the :attr:`preview` list carries\nup to three short bullet previews (key fields per\nkind) so a thread can surface highlights without\nre-deriving them. The :attr:`subject_label` is the\nper-kind \"who is this reading for?\" label \u2014 for\nKundli, the subject's name; for Palmistry, a stable\n``\"Palm reading\"`` placeholder."
      },
      "ReadingErrorResponse": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          }
        },
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "title": "ReadingErrorResponse",
        "description": "Typed error envelope for the readings API.\n\nMirrors :class:`app.schemas.compatibility.CompatibilityHistoryErrorResponse`\nso the two persistence surfaces share a single error\nshape. The ``error`` field is a stable, machine-readable\nstring the client can switch on. The ``field`` is\nincluded only when the failure names a specific field\n(e.g. Pydantic validation rejections).\n\nStable ``error`` values include (M003 S03 T01):\n\n* ``missing_session_token`` \u2014 the request did not\n  carry an ``X-Session-Token`` header.\n* ``invalid_session`` \u2014 the supplied token has never\n  been issued, or the underlying user was deleted.\n* ``expired_session`` \u2014 the supplied token existed\n  but its ``expires_at`` has passed.\n* ``revoked_session`` \u2014 the supplied token was\n  explicitly signed out.\n* ``reading_artifact_not_found`` \u2014 the requested\n  ``artifact_id`` does not exist for the calling user\n  (also returned for cross-user reads so the wire\n  shape does not leak artifact existence).\n* ``reading_unsupported_kind`` \u2014 the save request's\n  ``kind`` discriminator does not match the supplied\n  per-kind report-flow field.\n* ``reading_persistence_unavailable`` \u2014 the underlying\n  message-history store could not be reached."
      },
      "ReadingInterpretationStatus": {
        "type": "string",
        "enum": [
          "complete",
          "partial",
          "unavailable"
        ],
        "title": "ReadingInterpretationStatus",
        "description": "Closed literal for the cross-kind interpretation status.\n\nThe per-kind report-flow surfaces each carry their own\n:class:`InterpretationStatus` /\n:class:`PalmistryInterpretationStatus` enum. This enum\nis the **cross-kind** mirror: the same ``complete`` /\n``partial`` / ``unavailable`` literal semantics, surfaced\non the readings envelope so thread previews can render\nthe honest availability state without loading the\nper-kind report-flow payload. The values are stable\nstrings and a client should compare the string for\nbranch decisions."
      },
      "ReadingKind": {
        "type": "string",
        "enum": [
          "kundli",
          "palmistry"
        ],
        "title": "ReadingKind",
        "description": "Closed literal for the reading-kind discriminator.\n\nThe set is closed: any new value is a breaking change to\nthe wire contract and requires bumping\n:data:`READINGS_HISTORY_SCHEMA_VERSION`. The discriminator\nis the only field a client needs to inspect to know which\nper-kind payload is set on a :class:`ReadingArtifact`."
      },
      "RecommendationTier": {
        "type": "string",
        "enum": [
          "strong",
          "moderate",
          "mixed"
        ],
        "title": "RecommendationTier",
        "description": "Closed literal for the recommendation tier field.\n\n* ``strong``   - total_score \u2265 28.\n* ``moderate`` - 20 \u2264 total_score < 28.\n* ``mixed``    - total_score < 20."
      },
      "RectificationAnswer": {
        "properties": {
          "question_id": {
            "type": "string",
            "title": "Question Id"
          },
          "answer": {
            "type": "string",
            "title": "Answer"
          }
        },
        "type": "object",
        "required": [
          "question_id",
          "answer"
        ],
        "title": "RectificationAnswer"
      },
      "RectificationRequest": {
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "title": "Name"
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "DD/MM/YYYY"
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude"
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude"
          },
          "timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -14.0,
            "title": "Timezone Offset",
            "description": "Timezone offset supplied by the selected place."
          },
          "timezone_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Id"
          },
          "approximate_time": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approximate Time",
            "description": "HH:MM approximate if known"
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/RectificationAnswer"
            },
            "type": "array",
            "title": "Answers"
          }
        },
        "type": "object",
        "required": [
          "name",
          "birth_date",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "RectificationRequest"
      },
      "RectificationResponse": {
        "properties": {
          "suggested_birth_time": {
            "type": "string",
            "title": "Suggested Birth Time"
          },
          "confidence": {
            "type": "string",
            "title": "Confidence"
          },
          "ascendant_rashi": {
            "type": "string",
            "title": "Ascendant Rashi"
          },
          "moon_rashi": {
            "type": "string",
            "title": "Moon Rashi"
          },
          "nakshatra": {
            "type": "string",
            "title": "Nakshatra"
          },
          "reasoning": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Reasoning"
          },
          "alternative_times": {
            "items": {
              "type": "object"
            },
            "type": "array",
            "title": "Alternative Times"
          },
          "disclaimer": {
            "type": "string",
            "title": "Disclaimer"
          }
        },
        "type": "object",
        "required": [
          "suggested_birth_time",
          "confidence",
          "ascendant_rashi",
          "moon_rashi",
          "nakshatra",
          "reasoning",
          "alternative_times",
          "disclaimer"
        ],
        "title": "RectificationResponse"
      },
      "RedFlagRequest": {
        "properties": {
          "observed_indicators": {
            "additionalProperties": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "type": "object",
            "title": "Observed Indicators",
            "description": "Map of red flag category to observed indicator descriptions"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "RedFlagRequest"
      },
      "RedFlagSeverity": {
        "type": "string",
        "enum": [
          "info",
          "warning",
          "alert"
        ],
        "title": "RedFlagSeverity",
        "description": "Closed literal for the red-flag severity field."
      },
      "RedFlagSignal": {
        "type": "string",
        "enum": [
          "mars_in_trigger_house",
          "kuja_dosha_balanced",
          "kuja_dosha_mismatched",
          "kuja_dosha_absent",
          "element_clash",
          "same_moon_rashi",
          "same_nakshatra",
          "input_field_missing"
        ],
        "title": "RedFlagSignal",
        "description": "Closed literal for the red-flag signal identifier.\n\nThe set is closed; adding a new signal is a breaking change to\nthe wire contract. Each value has a one-line render contract\ndescribed in the domain module's docstring."
      },
      "RedeemUnlockCodeRequest": {
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 64,
            "minLength": 4,
            "title": "Code"
          }
        },
        "type": "object",
        "required": [
          "code"
        ],
        "title": "RedeemUnlockCodeRequest"
      },
      "ReliabilityMarkers": {
        "properties": {
          "straight_lining": {
            "type": "boolean",
            "title": "Straight Lining",
            "description": "True when the user selected the same option label for most questions.",
            "default": false
          },
          "low_sample_size": {
            "type": "boolean",
            "title": "Low Sample Size",
            "description": "True when total sample_count across dimensions is below the confidence threshold.",
            "default": false
          },
          "too_fast_answers": {
            "type": "boolean",
            "title": "Too Fast Answers",
            "description": "True when one or more answers were recorded below a minimum response time, suggesting insufficient reflection (fixpartner.md \u00a72.3).",
            "default": false
          },
          "repeated_same_trait": {
            "type": "boolean",
            "title": "Repeated Same Trait",
            "description": "True when the same option_trait was selected across most items, suggesting a response pattern rather than genuine differentiation (fixpartner.md \u00a72.3).",
            "default": false
          },
          "low_confidence_answers": {
            "type": "boolean",
            "title": "Low Confidence Answers",
            "description": "True when the user reported low confidence (1-2 on a 5-point scale) across most answers, suggesting uncertainty about their own responses (fixpartner.md \u00a72.3).",
            "default": false
          },
          "skipped_sensitive_domains": {
            "type": "boolean",
            "title": "Skipped Sensitive Domains",
            "description": "True when sensitive domains (intimacy, money, family pressure, trust, conflict) were skipped or left unanswered (fixpartner.md \u00a72.3).",
            "default": false
          },
          "self_partner_contradiction": {
            "type": "boolean",
            "title": "Self Partner Contradiction",
            "description": "True when declared profile, self SJT answers, and partner-observation answers contradict each other (fixpartner.md \u00a72.3).",
            "default": false
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes",
            "description": "Human-readable reliability notes for reports."
          }
        },
        "type": "object",
        "title": "ReliabilityMarkers",
        "description": "Reliability markers for the profile (S2, S3).\n\nStraight-lining and low sample size lower confidence. The markers are\nsurfaced to reports so the analysis is honest about evidence\nquality. Additional markers (fixpartner.md \u00a72.3) cover too-fast\nanswers, repeated same-trait patterns, low-confidence answers,\nskipped sensitive domains, and self-vs-partner contradictions."
      },
      "RevokeAllSessionsResponse": {
        "properties": {
          "revoked_count": {
            "type": "integer",
            "title": "Revoked Count"
          },
          "user_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Id"
          }
        },
        "type": "object",
        "required": [
          "revoked_count"
        ],
        "title": "RevokeAllSessionsResponse"
      },
      "SadeSatiRequest": {
        "properties": {
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "DD/MM/YYYY"
          },
          "birth_time": {
            "type": "string",
            "title": "Birth Time",
            "description": "HH:MM"
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude"
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude"
          },
          "timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -14.0,
            "title": "Timezone Offset",
            "description": "Timezone offset supplied by the selected place."
          },
          "timezone_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Id"
          }
        },
        "type": "object",
        "required": [
          "birth_date",
          "birth_time",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "SadeSatiRequest"
      },
      "SadeSatiResponse": {
        "properties": {
          "moon_sign": {
            "type": "string",
            "title": "Moon Sign"
          },
          "is_in_sade_sati": {
            "type": "boolean",
            "title": "Is In Sade Sati"
          },
          "current_phase": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Phase"
          },
          "phase_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phase Description"
          },
          "sade_sati_periods": {
            "items": {
              "type": "object"
            },
            "type": "array",
            "title": "Sade Sati Periods"
          },
          "recommendations": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Recommendations"
          },
          "disclaimer": {
            "type": "string",
            "title": "Disclaimer"
          }
        },
        "type": "object",
        "required": [
          "moon_sign",
          "is_in_sade_sati",
          "current_phase",
          "phase_description",
          "sade_sati_periods",
          "recommendations",
          "disclaimer"
        ],
        "title": "SadeSatiResponse"
      },
      "SarvajnaRequest": {
        "properties": {
          "user_id": {
            "type": "string",
            "minLength": 1,
            "title": "User Id"
          },
          "message": {
            "type": "string",
            "maxLength": 10000,
            "minLength": 1,
            "title": "Message"
          },
          "session_id": {
            "type": "string",
            "maxLength": 128,
            "minLength": 1,
            "title": "Session Id"
          },
          "include_context": {
            "type": "boolean",
            "title": "Include Context",
            "default": true
          },
          "behavioral_profile_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128,
                "minLength": 1,
                "pattern": "^[A-Za-z0-9:_-]+$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Behavioral Profile Id",
            "description": "Optional saved behavioral profile to load server-side for a profile-scoped follow-up."
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "message",
          "session_id"
        ],
        "title": "SarvajnaRequest",
        "description": "Request for Sarvajna assessment conversation."
      },
      "SarvajnaResponse": {
        "properties": {
          "response": {
            "type": "string",
            "title": "Response"
          },
          "session_id": {
            "type": "string",
            "title": "Session Id"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "title": "Timestamp"
          }
        },
        "type": "object",
        "required": [
          "response",
          "session_id"
        ],
        "title": "SarvajnaResponse",
        "description": "Response from Sarvajna assessment."
      },
      "SarvajnaTrustedResult": {
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "quick",
              "standard",
              "deep"
            ],
            "title": "Mode"
          },
          "finalized": {
            "type": "boolean",
            "title": "Finalized"
          },
          "answered": {
            "type": "integer",
            "maximum": 45.0,
            "minimum": 0.0,
            "title": "Answered"
          },
          "mode_question_count": {
            "type": "integer",
            "maximum": 45.0,
            "minimum": 1.0,
            "title": "Mode Question Count"
          },
          "minimum_for_result": {
            "type": "integer",
            "maximum": 45.0,
            "minimum": 1.0,
            "title": "Minimum For Result"
          },
          "neutral_rate": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Neutral Rate"
          },
          "confidence_label": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "title": "Confidence Label"
          },
          "confidence_value": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Confidence Value"
          },
          "confidence_reason": {
            "type": "string",
            "title": "Confidence Reason"
          },
          "quality_note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quality Note"
          },
          "axis_scores": {
            "additionalProperties": {
              "type": "number"
            },
            "type": "object",
            "title": "Axis Scores"
          },
          "axis_answer_counts": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Axis Answer Counts"
          },
          "axis_definitions": {
            "additionalProperties": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "type": "object",
            "title": "Axis Definitions"
          },
          "graha_scores": {
            "additionalProperties": {
              "type": "number"
            },
            "type": "object",
            "title": "Graha Scores"
          },
          "graha_evidence_counts": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Graha Evidence Counts"
          },
          "top_grahas": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 3,
            "title": "Top Grahas"
          },
          "selected_archetype_definitions": {
            "additionalProperties": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "type": "object",
            "title": "Selected Archetype Definitions"
          },
          "tattva_scores": {
            "additionalProperties": {
              "type": "number"
            },
            "type": "object",
            "title": "Tattva Scores"
          },
          "tattva_evidence_counts": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Tattva Evidence Counts"
          },
          "top_tattva": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Top Tattva"
          },
          "selected_tattva_definition": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Selected Tattva Definition"
          }
        },
        "type": "object",
        "required": [
          "mode",
          "finalized",
          "answered",
          "mode_question_count",
          "minimum_for_result",
          "neutral_rate",
          "confidence_label",
          "confidence_value",
          "confidence_reason"
        ],
        "title": "SarvajnaTrustedResult",
        "description": "Server-calculated Sarvajna facts returned beside generated prose."
      },
      "ScenarioBuilderErrorResponse": {
        "properties": {
          "error": {
            "type": "string",
            "title": "Error"
          },
          "message": {
            "type": "string",
            "title": "Message"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          }
        },
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "title": "ScenarioBuilderErrorResponse"
      },
      "ScenarioBuilderGenerateRequest": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "title": "Name"
          },
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "DD/MM/YYYY"
          },
          "birth_time": {
            "type": "string",
            "title": "Birth Time",
            "description": "HH:MM 24h"
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude"
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude"
          },
          "timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -12.0,
            "title": "Timezone Offset"
          },
          "timezone_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Id"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "default": "english"
          },
          "focus_area": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Focus Area",
            "description": "Optional focus: 'communication', 'values', 'family', etc."
          },
          "partner_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120
              },
              {
                "type": "null"
              }
            ],
            "title": "Partner Name",
            "description": "Optional partner name to personalize the generated questions."
          }
        },
        "type": "object",
        "required": [
          "name",
          "birth_date",
          "birth_time",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "ScenarioBuilderGenerateRequest",
        "description": "Request to generate scenario questions from a Kundli."
      },
      "ScenarioBuilderGenerateResponse-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "1.1.0"
          },
          "session_id": {
            "type": "string",
            "title": "Session Id",
            "description": "Deterministic session ID from chart signals."
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/ScenarioQuestion"
            },
            "type": "array",
            "title": "Questions",
            "description": "Generated partner-evaluation questions."
          },
          "chart_summary": {
            "type": "string",
            "title": "Chart Summary",
            "description": "Short human-readable chart summary for context."
          },
          "degraded": {
            "type": "boolean",
            "title": "Degraded",
            "default": false
          },
          "degradation_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Degradation Reason"
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "questions",
          "chart_summary"
        ],
        "title": "ScenarioBuilderGenerateResponse",
        "description": "Response with generated scenario questions.\n\n``degraded`` is ``True`` when the LLM generation path failed and\nthe service fell back to the static question bank. ``degradation_reason``\ncarries a short, log-correlatable explanation (e.g.\n``\"quota_exhausted\"``, ``\"llm_parse_error\"``, ``\"network_error\"``).\nWhen ``degraded`` is ``False`` both fields are absent/``None`` \u2014 the\nquestions were freshly authored by the LLM from the chart facts."
      },
      "ScenarioBuilderGenerateResponse-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "1.1.0"
          },
          "session_id": {
            "type": "string",
            "title": "Session Id",
            "description": "Deterministic session ID from chart signals."
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/ScenarioQuestion"
            },
            "type": "array",
            "title": "Questions",
            "description": "Generated partner-evaluation questions."
          },
          "chart_summary": {
            "type": "string",
            "title": "Chart Summary",
            "description": "Short human-readable chart summary for context."
          },
          "degraded": {
            "type": "boolean",
            "title": "Degraded",
            "default": false
          },
          "degradation_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Degradation Reason"
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "questions",
          "chart_summary"
        ],
        "title": "ScenarioBuilderGenerateResponse",
        "description": "Response with generated scenario questions.\n\n``degraded`` is ``True`` when the LLM generation path failed and\nthe service fell back to the static question bank. ``degradation_reason``\ncarries a short, log-correlatable explanation (e.g.\n``\"quota_exhausted\"``, ``\"llm_parse_error\"``, ``\"network_error\"``).\nWhen ``degraded`` is ``False`` both fields are absent/``None`` \u2014 the\nquestions were freshly authored by the LLM from the chart facts."
      },
      "ScenarioBuilderSaveRequest": {
        "properties": {
          "session_id": {
            "type": "string",
            "minLength": 1,
            "title": "Session Id"
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/ScenarioQuestion"
            },
            "type": "array",
            "title": "Questions"
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/app__schemas__scenario_builder__ScenarioAnswer"
            },
            "type": "array",
            "title": "Answers"
          },
          "chart_summary": {
            "type": "string",
            "title": "Chart Summary",
            "default": ""
          },
          "focus_area": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Focus Area"
          },
          "partner_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Partner Name"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "default": "english"
          }
        },
        "type": "object",
        "required": [
          "session_id"
        ],
        "title": "ScenarioBuilderSaveRequest",
        "description": "Request to save or update a scenario builder session."
      },
      "ScenarioBuilderSession-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "1.1.0"
          },
          "session_id": {
            "type": "string",
            "title": "Session Id"
          },
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "updated_at": {
            "type": "string",
            "title": "Updated At"
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/ScenarioQuestion"
            },
            "type": "array",
            "title": "Questions"
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/app__schemas__scenario_builder__ScenarioAnswer"
            },
            "type": "array",
            "title": "Answers"
          },
          "chart_summary": {
            "type": "string",
            "title": "Chart Summary",
            "default": ""
          },
          "focus_area": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Focus Area"
          },
          "partner_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Partner Name"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "default": "english"
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "Short preview text for list rendering.",
            "default": ""
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "user_id",
          "created_at",
          "updated_at"
        ],
        "title": "ScenarioBuilderSession",
        "description": "A persisted scenario builder session."
      },
      "ScenarioBuilderSession-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "1.1.0"
          },
          "session_id": {
            "type": "string",
            "title": "Session Id"
          },
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "updated_at": {
            "type": "string",
            "title": "Updated At"
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/ScenarioQuestion"
            },
            "type": "array",
            "title": "Questions"
          },
          "answers": {
            "items": {
              "$ref": "#/components/schemas/app__schemas__scenario_builder__ScenarioAnswer"
            },
            "type": "array",
            "title": "Answers"
          },
          "chart_summary": {
            "type": "string",
            "title": "Chart Summary",
            "default": ""
          },
          "focus_area": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Focus Area"
          },
          "partner_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Partner Name"
          },
          "preferred_language": {
            "type": "string",
            "enum": [
              "english",
              "hinglish",
              "hindi"
            ],
            "title": "Preferred Language",
            "default": "english"
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "Short preview text for list rendering.",
            "default": ""
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "user_id",
          "created_at",
          "updated_at"
        ],
        "title": "ScenarioBuilderSession",
        "description": "A persisted scenario builder session."
      },
      "ScenarioBuilderSessionListItem": {
        "properties": {
          "session_id": {
            "type": "string",
            "title": "Session Id"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "updated_at": {
            "type": "string",
            "title": "Updated At"
          },
          "summary": {
            "type": "string",
            "title": "Summary"
          },
          "question_count": {
            "type": "integer",
            "title": "Question Count"
          },
          "answered_count": {
            "type": "integer",
            "title": "Answered Count"
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "created_at",
          "updated_at",
          "summary",
          "question_count",
          "answered_count"
        ],
        "title": "ScenarioBuilderSessionListItem",
        "description": "A list item for browsing saved sessions."
      },
      "ScenarioBuilderSessionListResponse": {
        "properties": {
          "sessions": {
            "items": {
              "$ref": "#/components/schemas/ScenarioBuilderSessionListItem"
            },
            "type": "array",
            "title": "Sessions"
          },
          "total": {
            "type": "integer",
            "title": "Total"
          }
        },
        "type": "object",
        "required": [
          "sessions",
          "total"
        ],
        "title": "ScenarioBuilderSessionListResponse",
        "description": "Response listing saved sessions."
      },
      "ScenarioJobStatusResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "title": "Job Id"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ],
            "title": "Status",
            "default": "pending"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralScenariosResponse"
              },
              {
                "type": "null"
              }
            ]
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          }
        },
        "type": "object",
        "required": [
          "job_id"
        ],
        "title": "ScenarioJobStatusResponse",
        "description": "Status of an async scenario generation job.\n\nWhen ``status`` is ``completed``, ``result`` contains the full\n``BehavioralScenariosResponse``. When ``status`` is ``failed``,\n``error`` contains a human-readable message."
      },
      "ScenarioQuestion": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Deterministic ID (hash of chart signals + question text)."
          },
          "category": {
            "type": "string",
            "title": "Category",
            "description": "Broad category: 'communication', 'values', 'lifestyle', 'emotional', 'family'."
          },
          "chart_signal": {
            "type": "string",
            "title": "Chart Signal",
            "description": "The chart signal that inspired this question, e.g. 'Mars in 7th house'."
          },
          "question": {
            "type": "string",
            "title": "Question",
            "description": "The question text, ending with a prompt to the user."
          },
          "options": {
            "items": {
              "$ref": "#/components/schemas/ScenarioQuestionOption"
            },
            "type": "array",
            "maxItems": 6,
            "minItems": 2,
            "title": "Options",
            "description": "Multiple-choice options."
          },
          "measurement_target": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Measurement Target",
            "description": "The dimension this question measures (e.g. 'conflict_style', 'family_boundary'). Drawn from a backend-owned closed list. Hidden from the UI; used for synthesis and report interpretation."
          },
          "rationale_for_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rationale For Category",
            "description": "Short LLM-authored rationale for why this category/target fits the chart signal. Hidden from the UI; retained for auditability and downstream synthesis."
          },
          "construct_family": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "attachment",
                  "conflict",
                  "big_five_proxy",
                  "values",
                  "culture",
                  "lifestyle"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Construct Family",
            "description": "Research background construct family for this question. Hidden from the UI; used to group evidence by construct and enforce scenario diversity constraints."
          },
          "evidence_refs": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Evidence Refs",
            "description": "Backend-authored evidence references that ground this question (e.g. chart signals, compatibility matrix cells). Hidden from the UI; used for grounding validation."
          },
          "difficulty": {
            "type": "string",
            "enum": [
              "light",
              "medium",
              "sensitive"
            ],
            "title": "Difficulty",
            "description": "Difficulty band. 'sensitive' scenarios touch intimacy, finances, or family pressure; the UI may surface a softer framing for them.",
            "default": "medium"
          },
          "cultural_sensitivity_tag": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cultural Sensitivity Tag",
            "description": "Tag indicating cultural sensitivity considerations (e.g. 'family_pressure', 'interfaith', 'caste_context'). Hidden from the UI; used to soften framing when needed."
          },
          "item_bank_version": {
            "type": "string",
            "title": "Item Bank Version",
            "description": "Version of the item bank / rubric this question was generated against. Used for analytics correlation.",
            "default": "1.1.0"
          }
        },
        "type": "object",
        "required": [
          "id",
          "category",
          "chart_signal",
          "question",
          "options"
        ],
        "title": "ScenarioQuestion",
        "description": "A single partner-evaluation question generated from the chart."
      },
      "ScenarioQuestionOption": {
        "properties": {
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Short label, e.g. 'A', 'B'."
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "The option text the user reads."
          },
          "option_trait": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Option Trait",
            "description": "Backend-owned trait this option represents (e.g. 'harmony_deference'). Hidden from the UI; used by reports/chat synthesis to interpret the answer without relying only on prose."
          },
          "score_vector": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "number"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Score Vector",
            "description": "Backend-owned per-dimension score contribution of this option. Hidden from the UI; used by the scoring model. Keys are measurement_target keys, values are signed floats."
          }
        },
        "type": "object",
        "required": [
          "label",
          "text"
        ],
        "title": "ScenarioQuestionOption",
        "description": "A single multiple-choice option for a scenario question."
      },
      "SectionedCompatibilityReport-Input": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-sectioned-1.0.0"
          },
          "contract_type": {
            "$ref": "#/components/schemas/ContractType",
            "default": "sectioned_trust_first"
          },
          "computed_truth": {
            "$ref": "#/components/schemas/SectionedComputedTruth-Input"
          },
          "derived_interpretation": {
            "$ref": "#/components/schemas/SectionedDerivedInterpretation-Input"
          },
          "narrative": {
            "$ref": "#/components/schemas/SectionedNarrative"
          },
          "confidence": {
            "$ref": "#/components/schemas/SectionedConfidenceBlock"
          },
          "degradation": {
            "$ref": "#/components/schemas/SectionedDegradationBlock"
          },
          "trust": {
            "$ref": "#/components/schemas/SectionedTrustMetadata"
          },
          "behavioral_evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralEvidenceBlock"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional behavioral evidence summary. Mirrors the block on :class:`CompatibilityReportResponse`."
          }
        },
        "type": "object",
        "required": [
          "computed_truth",
          "derived_interpretation",
          "narrative",
          "confidence",
          "degradation",
          "trust"
        ],
        "title": "SectionedCompatibilityReport",
        "description": "Additive sectioned compatibility report contract (M006 S01 T01).\n\nThe contract splits the flat report into three explicit\nprovenance sections plus first-class confidence, degradation,\nand trust markers so a renderer can show what was computed,\nwhat was derived, and what was AI-authored without reading\nsource code or guessing from tone.\n\nField-by-field invariants:\n\n* ``schema_version`` is the constant\n  :data:`COMPATIBILITY_SECTIONED_SCHEMA_VERSION`. Bump on any\n  breaking change to this block.\n* ``computed_truth.payload`` is byte-comparable to the flat\n  :class:`CompatibilityReport` exposed on\n  :class:`CompatibilityReportResponse.report`.\n* ``derived_interpretation`` contains NO LLM-authored text.\n  Every field is a deterministic transformation of\n  ``computed_truth.payload``.\n* ``narrative.status`` is one of the closed literals in\n  :class:`InterpretationStatus`. When ``unavailable``,\n  ``narrative.text`` MUST be ``None``.\n* ``degradation.is_degraded`` and\n  ``degradation.interpretation_degraded`` are independent\n  flags - a renderer can show \"truth is complete, narrative\n  is unavailable\" distinctly from \"truth is degraded,\n  narrative is unavailable\".\n* ``trust.schema_version`` mirrors this contract's\n  ``schema_version``; ``trust.compatibility_engine_version``\n  mirrors the underlying engine version for cache\n  invalidation."
      },
      "SectionedCompatibilityReport-Output": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-sectioned-1.0.0"
          },
          "contract_type": {
            "$ref": "#/components/schemas/ContractType",
            "default": "sectioned_trust_first"
          },
          "computed_truth": {
            "$ref": "#/components/schemas/SectionedComputedTruth-Output"
          },
          "derived_interpretation": {
            "$ref": "#/components/schemas/SectionedDerivedInterpretation-Output"
          },
          "narrative": {
            "$ref": "#/components/schemas/SectionedNarrative"
          },
          "confidence": {
            "$ref": "#/components/schemas/SectionedConfidenceBlock"
          },
          "degradation": {
            "$ref": "#/components/schemas/SectionedDegradationBlock"
          },
          "trust": {
            "$ref": "#/components/schemas/SectionedTrustMetadata"
          },
          "behavioral_evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BehavioralEvidenceBlock"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional behavioral evidence summary. Mirrors the block on :class:`CompatibilityReportResponse`."
          }
        },
        "type": "object",
        "required": [
          "computed_truth",
          "derived_interpretation",
          "narrative",
          "confidence",
          "degradation",
          "trust"
        ],
        "title": "SectionedCompatibilityReport",
        "description": "Additive sectioned compatibility report contract (M006 S01 T01).\n\nThe contract splits the flat report into three explicit\nprovenance sections plus first-class confidence, degradation,\nand trust markers so a renderer can show what was computed,\nwhat was derived, and what was AI-authored without reading\nsource code or guessing from tone.\n\nField-by-field invariants:\n\n* ``schema_version`` is the constant\n  :data:`COMPATIBILITY_SECTIONED_SCHEMA_VERSION`. Bump on any\n  breaking change to this block.\n* ``computed_truth.payload`` is byte-comparable to the flat\n  :class:`CompatibilityReport` exposed on\n  :class:`CompatibilityReportResponse.report`.\n* ``derived_interpretation`` contains NO LLM-authored text.\n  Every field is a deterministic transformation of\n  ``computed_truth.payload``.\n* ``narrative.status`` is one of the closed literals in\n  :class:`InterpretationStatus`. When ``unavailable``,\n  ``narrative.text`` MUST be ``None``.\n* ``degradation.is_degraded`` and\n  ``degradation.interpretation_degraded`` are independent\n  flags - a renderer can show \"truth is complete, narrative\n  is unavailable\" distinctly from \"truth is degraded,\n  narrative is unavailable\".\n* ``trust.schema_version`` mirrors this contract's\n  ``schema_version``; ``trust.compatibility_engine_version``\n  mirrors the underlying engine version for cache\n  invalidation."
      },
      "SectionedComputedTruth-Input": {
        "properties": {
          "payload": {
            "$ref": "#/components/schemas/CompatibilityReport-Input",
            "description": "The authoritative CompatibilityReport. Mirrored verbatim from the response's ``report`` field."
          }
        },
        "type": "object",
        "required": [
          "payload"
        ],
        "title": "SectionedComputedTruth",
        "description": "The full deterministic engine output, passed through verbatim.\n\nField set is the closed :class:`CompatibilityReport` shape\nexactly. A client reading ``sections.computed_truth.payload``\nsees the same fields it would see on the flat ``report``\nblock; the two are guaranteed byte-comparable."
      },
      "SectionedComputedTruth-Output": {
        "properties": {
          "payload": {
            "$ref": "#/components/schemas/CompatibilityReport-Output",
            "description": "The authoritative CompatibilityReport. Mirrored verbatim from the response's ``report`` field."
          }
        },
        "type": "object",
        "required": [
          "payload"
        ],
        "title": "SectionedComputedTruth",
        "description": "The full deterministic engine output, passed through verbatim.\n\nField set is the closed :class:`CompatibilityReport` shape\nexactly. A client reading ``sections.computed_truth.payload``\nsees the same fields it would see on the flat ``report``\nblock; the two are guaranteed byte-comparable."
      },
      "SectionedConfidenceBlock": {
        "properties": {
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Provenance of the confidence value. Always 'deterministic_engine_input_confidence' for M006 S01."
          },
          "level": {
            "$ref": "#/components/schemas/SectionedConfidenceLevel",
            "description": "Closed-literal confidence band. 'high' / 'medium' / 'low'. See :class:`SectionedConfidenceLevel`."
          },
          "time_precision_minutes": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Time Precision Minutes",
            "description": "Birth-time precision in minutes for the less-precise of the two inputs."
          },
          "has_place_resolved": {
            "type": "boolean",
            "title": "Has Place Resolved",
            "description": "True when both birth places were resolved (coordinate + IANA timezone) by the engine."
          },
          "has_timezone_validated": {
            "type": "boolean",
            "title": "Has Timezone Validated",
            "description": "True when the timezone offset / ID was validated by the engine."
          },
          "note": {
            "type": "string",
            "title": "Note",
            "description": "One-line human-readable confidence note. Render verbatim."
          }
        },
        "type": "object",
        "required": [
          "source",
          "level",
          "time_precision_minutes",
          "has_place_resolved",
          "has_timezone_validated",
          "note"
        ],
        "title": "SectionedConfidenceBlock",
        "description": "Honest disclosure of confidence in this report.\n\nMirrors :class:`InputConfidenceOut` for the input side and\nadds a derived ``level`` for cross-renderer comparison. The\nblock is computed deterministically from the engine output;\nit never makes the report look more confident than it is."
      },
      "SectionedConfidenceLevel": {
        "type": "string",
        "enum": [
          "high",
          "medium",
          "low"
        ],
        "title": "SectionedConfidenceLevel",
        "description": "Closed literal for the sectioned confidence block.\n\n* ``high``   - no degradation, narrative available (or honestly\n  unavailable but the deterministic truth is complete).\n* ``medium`` - narrative degraded OR a single input-degradation\n  reason on the deterministic truth.\n* ``low``    - two or more input-degradation reasons OR both\n  truth and narrative degraded."
      },
      "SectionedDegradationBlock": {
        "properties": {
          "is_degraded": {
            "type": "boolean",
            "title": "Is Degraded",
            "description": "True when the deterministic truth carries one or more degradation reasons."
          },
          "reasons": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Reasons",
            "description": "Mirrored from ``CompatibilityReport.degradation_reasons``. Render verbatim; never reword."
          },
          "interpretation_degraded": {
            "type": "boolean",
            "title": "Interpretation Degraded",
            "description": "True when ``interpretation_status`` is not 'complete'. Honest unavailability counts as degraded so the renderer can show a unified 'narrative unavailable' affordance."
          },
          "interpretation_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interpretation Reason",
            "description": "Short machine-readable reason for narrative degradation (e.g. 'narrative_slice_not_yet_shipped' or 'llm_unavailable'). None when the narrative is complete."
          }
        },
        "type": "object",
        "required": [
          "is_degraded",
          "interpretation_degraded"
        ],
        "title": "SectionedDegradationBlock",
        "description": "First-class degradation markers for the report.\n\nSplits degradation along two orthogonal axes:\n\n* ``is_degraded`` / ``reasons`` - the deterministic truth was\n  computed in a degraded mode (e.g. ``person1_mars_missing``).\n* ``interpretation_degraded`` / ``interpretation_reason`` -\n  the narrative slot is degraded (or honestly unavailable).\n\nA maintainer reading the wire shape alone can distinguish\n\"the chart math is fine, the narrative is missing\" from\n\"the chart math is also degraded\" without parsing prose."
      },
      "SectionedDerivedInterpretation-Input": {
        "properties": {
          "band": {
            "$ref": "#/components/schemas/MatrixBand",
            "description": "Closed-literal matrix band derived from the report's ``recommendation_tier`` (or overridden to 'high_attention' when the truth is degraded)."
          },
          "band_label": {
            "type": "string",
            "title": "Band Label",
            "description": "Human-readable label for the band. Render verbatim."
          },
          "headline": {
            "type": "string",
            "title": "Headline",
            "description": "Single-sentence deterministic headline. Built from the report's recommendation tier; render verbatim."
          },
          "strengths": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Strengths",
            "description": "Deterministically derived per-layer rationales with fill_ratio >= 0.75. Render verbatim."
          },
          "frictions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Frictions",
            "description": "Deterministically derived per-layer rationales with fill_ratio <= 0.40. Render verbatim."
          },
          "domain_summaries": {
            "items": {
              "$ref": "#/components/schemas/SectionedDomainSummary-Input"
            },
            "type": "array",
            "title": "Domain Summaries",
            "description": "Per-layer scaffolding, one entry per layer in the truth's ``layer_scores`` list. Always six entries in canonical order."
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes",
            "description": "Deterministic one-liners summarising the Kuja review and element-fit relationship. Render verbatim."
          }
        },
        "type": "object",
        "required": [
          "band",
          "band_label",
          "headline"
        ],
        "title": "SectionedDerivedInterpretation",
        "description": "Deterministic scaffolding built from the computed truth.\n\n**MUST NOT contain LLM-authored text.** The block is a\npresentation layer; every field is a deterministic\ntransformation of :class:`SectionedComputedTruth.payload`.\nThe renderer MUST trust this block as scaffolding only and\nfall back to the computed truth whenever a renderer needs to\nshow an authoritative number."
      },
      "SectionedDerivedInterpretation-Output": {
        "properties": {
          "band": {
            "$ref": "#/components/schemas/MatrixBand",
            "description": "Closed-literal matrix band derived from the report's ``recommendation_tier`` (or overridden to 'high_attention' when the truth is degraded)."
          },
          "band_label": {
            "type": "string",
            "title": "Band Label",
            "description": "Human-readable label for the band. Render verbatim."
          },
          "headline": {
            "type": "string",
            "title": "Headline",
            "description": "Single-sentence deterministic headline. Built from the report's recommendation tier; render verbatim."
          },
          "strengths": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Strengths",
            "description": "Deterministically derived per-layer rationales with fill_ratio >= 0.75. Render verbatim."
          },
          "frictions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Frictions",
            "description": "Deterministically derived per-layer rationales with fill_ratio <= 0.40. Render verbatim."
          },
          "domain_summaries": {
            "items": {
              "$ref": "#/components/schemas/SectionedDomainSummary-Output"
            },
            "type": "array",
            "title": "Domain Summaries",
            "description": "Per-layer scaffolding, one entry per layer in the truth's ``layer_scores`` list. Always six entries in canonical order."
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes",
            "description": "Deterministic one-liners summarising the Kuja review and element-fit relationship. Render verbatim."
          }
        },
        "type": "object",
        "required": [
          "band",
          "band_label",
          "headline"
        ],
        "title": "SectionedDerivedInterpretation",
        "description": "Deterministic scaffolding built from the computed truth.\n\n**MUST NOT contain LLM-authored text.** The block is a\npresentation layer; every field is a deterministic\ntransformation of :class:`SectionedComputedTruth.payload`.\nThe renderer MUST trust this block as scaffolding only and\nfall back to the computed truth whenever a renderer needs to\nshow an authoritative number."
      },
      "SectionedDomainSummary-Input": {
        "properties": {
          "layer": {
            "type": "string",
            "title": "Layer",
            "description": "Closed-literal layer name. Matches :class:`LayerName`."
          },
          "points": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Points",
            "description": "Points earned by the layer, mirrored verbatim."
          },
          "maximum_points": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Maximum Points",
            "description": "Maximum possible points, mirrored verbatim."
          },
          "fill_ratio": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Fill Ratio",
            "description": "points / maximum_points, clamped to [0, 1]. Used to label the layer as a strength (>= 0.75) or a friction (<= 0.40)."
          },
          "band": {
            "type": "string",
            "title": "Band",
            "description": "One-line deterministic band label for the layer ('strong' / 'supporting' / 'caution' / 'unread')."
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "One-line human-readable rationale. Mirrored from the layer's rationale field; render verbatim."
          },
          "evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MatrixCellEvidence"
              },
              {
                "type": "null"
              }
            ],
            "description": "Backend-authored matrix cell evidence for this layer. Surfaces the deterministic signals that drove the layer's score plus an explicit grounding state. The composer always populates this on the v2 wire shape so a renderer can cross-reference the evidence refs to the authoritative scoring cell. None only when the layer was not computed by the engine (graceful degradation)."
          }
        },
        "type": "object",
        "required": [
          "layer",
          "points",
          "maximum_points",
          "fill_ratio",
          "band",
          "summary"
        ],
        "title": "SectionedDomainSummary",
        "description": "Per-layer scaffolding inside the derived interpretation.\n\nStrictly derived from :class:`CompatibilityLayerOut`. The\nblock is a presentation aid for the renderer; the\nauthoritative values still live in\n:class:`CompatibilityReport.layer_scores`."
      },
      "SectionedDomainSummary-Output": {
        "properties": {
          "layer": {
            "type": "string",
            "title": "Layer",
            "description": "Closed-literal layer name. Matches :class:`LayerName`."
          },
          "points": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Points",
            "description": "Points earned by the layer, mirrored verbatim."
          },
          "maximum_points": {
            "type": "integer",
            "minimum": 0.0,
            "title": "Maximum Points",
            "description": "Maximum possible points, mirrored verbatim."
          },
          "fill_ratio": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Fill Ratio",
            "description": "points / maximum_points, clamped to [0, 1]. Used to label the layer as a strength (>= 0.75) or a friction (<= 0.40)."
          },
          "band": {
            "type": "string",
            "title": "Band",
            "description": "One-line deterministic band label for the layer ('strong' / 'supporting' / 'caution' / 'unread')."
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "One-line human-readable rationale. Mirrored from the layer's rationale field; render verbatim."
          },
          "evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MatrixCellEvidence"
              },
              {
                "type": "null"
              }
            ],
            "description": "Backend-authored matrix cell evidence for this layer. Surfaces the deterministic signals that drove the layer's score plus an explicit grounding state. The composer always populates this on the v2 wire shape so a renderer can cross-reference the evidence refs to the authoritative scoring cell. None only when the layer was not computed by the engine (graceful degradation)."
          }
        },
        "type": "object",
        "required": [
          "layer",
          "points",
          "maximum_points",
          "fill_ratio",
          "band",
          "summary"
        ],
        "title": "SectionedDomainSummary",
        "description": "Per-layer scaffolding inside the derived interpretation.\n\nStrictly derived from :class:`CompatibilityLayerOut`. The\nblock is a presentation aid for the renderer; the\nauthoritative values still live in\n:class:`CompatibilityReport.layer_scores`."
      },
      "SectionedNarrative": {
        "properties": {
          "status": {
            "$ref": "#/components/schemas/app__schemas__compatibility__InterpretationStatus",
            "description": "Closed-literal narrative status. Mirrors :class:`InterpretationStatus`."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Provenance of the narrative text. 'none' when the slot is unavailable; the model identifier when the slot is filled."
          },
          "text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Text",
            "description": "The AI-authored narrative text. None when the slot is unavailable; verbatim text from the named source otherwise."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Short machine-readable reason for the current status. None when the narrative is complete; 'narrative_slice_not_yet_shipped' when the route never attempted synthesis; 'llm_unavailable' when synthesis failed and the slot fell back to partial."
          }
        },
        "type": "object",
        "required": [
          "status",
          "source"
        ],
        "title": "SectionedNarrative",
        "description": "AI-authored narrative slot.\n\nThe contract here is intentionally narrow: the slot is\neither honestly unavailable (``status == 'unavailable'``,\n``text == None``) or it was filled by a named LLM source.\nThe renderer MUST show the status verbatim so a user can\ntell whether a piece of text was generated or not."
      },
      "SectionedTrustMetadata": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-compatibility-sectioned-1.0.0"
          },
          "contract_type": {
            "$ref": "#/components/schemas/ContractType",
            "default": "sectioned_trust_first"
          },
          "truth_engine_name": {
            "type": "string",
            "title": "Truth Engine Name"
          },
          "truth_engine_version": {
            "type": "string",
            "title": "Truth Engine Version"
          },
          "compatibility_engine_name": {
            "type": "string",
            "title": "Compatibility Engine Name"
          },
          "compatibility_engine_version": {
            "type": "string",
            "title": "Compatibility Engine Version"
          },
          "ayanamsa": {
            "type": "string",
            "title": "Ayanamsa"
          },
          "house_system": {
            "type": "string",
            "title": "House System"
          },
          "ephemeris_provider": {
            "type": "string",
            "title": "Ephemeris Provider"
          },
          "ephemeris_path": {
            "type": "string",
            "title": "Ephemeris Path"
          },
          "generated_at": {
            "type": "string",
            "title": "Generated At",
            "description": "ISO-8601 UTC timestamp at which the sectioned contract was composed. Wall-clock; not part of the byte-comparable contract."
          },
          "determinism_guarantee": {
            "type": "string",
            "title": "Determinism Guarantee",
            "description": "Stable string describing the determinism guarantee of the underlying compatibility engine. Mirrored from the truth's metadata block."
          }
        },
        "type": "object",
        "required": [
          "truth_engine_name",
          "truth_engine_version",
          "compatibility_engine_name",
          "compatibility_engine_version",
          "ayanamsa",
          "house_system",
          "ephemeris_provider",
          "ephemeris_path",
          "generated_at",
          "determinism_guarantee"
        ],
        "title": "SectionedTrustMetadata",
        "description": "Identifies the engines and contract that produced this report.\n\nSurfaces both engine versions (the compatibility scorer and\nthe underlying Kundli truth engine) plus the determinism\nguarantee and the wall-clock generation timestamp. The\ntimestamp is the only non-deterministic field; everything\nelse is byte-comparable."
      },
      "SessionResponse": {
        "properties": {
          "user_id": {
            "type": "string",
            "title": "User Id"
          },
          "session_token": {
            "type": "string",
            "title": "Session Token"
          },
          "display_name": {
            "type": "string",
            "title": "Display Name"
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "consent_version": {
            "type": "string",
            "title": "Consent Version"
          },
          "consent_given": {
            "type": "boolean",
            "title": "Consent Given"
          },
          "consented_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Consented At"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "expires_at": {
            "type": "string",
            "title": "Expires At"
          },
          "access_tier": {
            "type": "string",
            "title": "Access Tier",
            "default": "trial"
          },
          "access_expires_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Expires At"
          },
          "trial_questions_limit": {
            "type": "integer",
            "title": "Trial Questions Limit",
            "default": 3
          },
          "trial_questions_used": {
            "type": "integer",
            "title": "Trial Questions Used",
            "default": 0
          },
          "trial_questions_remaining": {
            "type": "integer",
            "title": "Trial Questions Remaining",
            "default": 3
          },
          "trial_kundli_limit": {
            "type": "integer",
            "title": "Trial Kundli Limit",
            "default": 1
          },
          "trial_kundli_used": {
            "type": "integer",
            "title": "Trial Kundli Used",
            "default": 0
          },
          "trial_kundli_remaining": {
            "type": "integer",
            "title": "Trial Kundli Remaining",
            "default": 1
          },
          "acknowledgment_text": {
            "type": "string",
            "title": "Acknowledgment Text"
          },
          "auth_provider": {
            "type": "string",
            "title": "Auth Provider",
            "default": "legacy_session"
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "session_token",
          "display_name",
          "consent_version",
          "consent_given",
          "created_at",
          "expires_at",
          "acknowledgment_text"
        ],
        "title": "SessionResponse"
      },
      "SourceSignalRef": {
        "properties": {
          "signal_id": {
            "type": "string",
            "title": "Signal Id",
            "description": "Stable signal identifier (e.g. 'mars_house_p1', 'element_fit_relationship'). Render verbatim."
          },
          "readable": {
            "type": "boolean",
            "title": "Readable",
            "description": "True when the engine produced a non-None value for this signal. False when the signal is missing or could not be computed."
          },
          "summary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary",
            "description": "One-line deterministic human-readable summary of the signal. None when the signal is unreadable."
          }
        },
        "type": "object",
        "required": [
          "signal_id",
          "readable"
        ],
        "title": "SourceSignalRef",
        "description": "One deterministic signal reference inside a grounding block.\n\nA scenario or matrix cell may depend on more than one signal.\nEach reference carries the signal id (stable across calls)\nand a flag indicating whether the signal was readable on the\nengine's side. When a signal is unreadable the evidence\nblock must surface that \u2014 the renderer can then mark the\nrelated scenario as partial-grounding without guessing.\n\nThe ``signal_id`` is a closed set on the engine side. New\nsignals are an additive change inside the engine module \u2014\nthey do not require a wire-contract bump because the schema\naccepts any stable string."
      },
      "StageSignoffSubmission": {
        "properties": {
          "signer_token": {
            "type": "string",
            "title": "Signer Token"
          },
          "signer_role": {
            "type": "string",
            "enum": [
              "couples_counsellor",
              "psychologist",
              "psychometrician",
              "financial_planner",
              "sexual_health_or_consent_expert",
              "indian_arranged_marriage_lived_experience",
              "language_reviewer",
              "research_methodologist",
              "data_scientist",
              "ethics_or_safeguarding_reviewer",
              "other"
            ],
            "title": "Signer Role"
          },
          "stage": {
            "type": "string",
            "enum": [
              "content_validity",
              "cognitive_interviews",
              "pilot_item_analysis",
              "dyadic_validation",
              "longitudinal_fairness"
            ],
            "title": "Stage"
          },
          "decision": {
            "type": "string",
            "enum": [
              "approved",
              "changes_required",
              "rejected"
            ],
            "title": "Decision"
          },
          "evidence_snapshot_hash": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "title": "Evidence Snapshot Hash"
          },
          "rationale": {
            "type": "string",
            "maxLength": 5000,
            "minLength": 1,
            "title": "Rationale"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "signer_token",
          "signer_role",
          "stage",
          "decision",
          "evidence_snapshot_hash",
          "rationale"
        ],
        "title": "StageSignoffSubmission"
      },
      "StudyCreateRequest": {
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 200,
            "minLength": 4,
            "title": "Title"
          },
          "slug": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9-]{2,80}$",
            "title": "Slug"
          },
          "protocol": {
            "$ref": "#/components/schemas/StudyProtocolConfig"
          },
          "preregistration_uri": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Preregistration Uri"
          },
          "ethics_approval_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Ethics Approval Reference"
          },
          "consent_version": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Consent Version"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "title",
          "slug",
          "consent_version"
        ],
        "title": "StudyCreateRequest"
      },
      "StudyProtocolConfig": {
        "properties": {
          "required_expert_roles": {
            "items": {
              "type": "string",
              "enum": [
                "couples_counsellor",
                "psychologist",
                "psychometrician",
                "financial_planner",
                "sexual_health_or_consent_expert",
                "indian_arranged_marriage_lived_experience",
                "language_reviewer",
                "research_methodologist",
                "data_scientist",
                "ethics_or_safeguarding_reviewer",
                "other"
              ]
            },
            "type": "array",
            "title": "Required Expert Roles"
          },
          "required_signoff_roles": {
            "items": {
              "type": "string",
              "enum": [
                "couples_counsellor",
                "psychologist",
                "psychometrician",
                "financial_planner",
                "sexual_health_or_consent_expert",
                "indian_arranged_marriage_lived_experience",
                "language_reviewer",
                "research_methodologist",
                "data_scientist",
                "ethics_or_safeguarding_reviewer",
                "other"
              ]
            },
            "type": "array",
            "title": "Required Signoff Roles"
          },
          "expert_reviewers_min": {
            "type": "integer",
            "maximum": 50.0,
            "minimum": 3.0,
            "title": "Expert Reviewers Min",
            "default": 6
          },
          "item_cvi_min": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Item Cvi Min",
            "default": 0.78
          },
          "required_languages": {
            "items": {
              "type": "string",
              "enum": [
                "english",
                "hindi",
                "hinglish",
                "other"
              ]
            },
            "type": "array",
            "title": "Required Languages"
          },
          "cognitive_participants_per_language_min": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 1.0,
            "title": "Cognitive Participants Per Language Min",
            "default": 5
          },
          "cognitive_comprehension_min": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Cognitive Comprehension Min",
            "default": 0.8
          },
          "pilot_total_min": {
            "type": "integer",
            "maximum": 100000.0,
            "minimum": 20.0,
            "title": "Pilot Total Min",
            "default": 200
          },
          "pilot_per_language_min": {
            "type": "integer",
            "maximum": 10000.0,
            "minimum": 5.0,
            "title": "Pilot Per Language Min",
            "default": 50
          },
          "pilot_comprehension_min": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Pilot Comprehension Min",
            "default": 0.9
          },
          "pilot_max_option_share_review": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.25,
            "title": "Pilot Max Option Share Review",
            "default": 0.85
          },
          "pilot_too_fast_ms": {
            "type": "integer",
            "maximum": 120000.0,
            "minimum": 250.0,
            "title": "Pilot Too Fast Ms",
            "default": 2500
          },
          "pilot_too_fast_share_review": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Pilot Too Fast Share Review",
            "default": 0.2
          },
          "pilot_impression_management_share_review": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Pilot Impression Management Share Review",
            "default": 0.25
          },
          "complete_dyads_min": {
            "type": "integer",
            "maximum": 100000.0,
            "minimum": 10.0,
            "title": "Complete Dyads Min",
            "default": 100
          },
          "longitudinal_waves_min": {
            "type": "integer",
            "maximum": 20.0,
            "minimum": 2.0,
            "title": "Longitudinal Waves Min",
            "default": 2
          },
          "longitudinal_retention_min": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Longitudinal Retention Min",
            "default": 0.7
          },
          "longitudinal_participants_per_item_min": {
            "type": "integer",
            "maximum": 100000.0,
            "minimum": 10.0,
            "title": "Longitudinal Participants Per Item Min",
            "default": 100
          },
          "fairness_min_cell": {
            "type": "integer",
            "maximum": 10000.0,
            "minimum": 5.0,
            "title": "Fairness Min Cell",
            "default": 20
          },
          "disparity_review_threshold": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Disparity Review Threshold",
            "default": 0.2
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "StudyProtocolConfig",
        "description": "Pre-registered operational gates; defaults are not universal laws."
      },
      "StudyRecord": {
        "properties": {
          "study_id": {
            "type": "string",
            "title": "Study Id"
          },
          "title": {
            "type": "string",
            "title": "Title"
          },
          "slug": {
            "type": "string",
            "title": "Slug"
          },
          "protocol_version": {
            "type": "string",
            "title": "Protocol Version",
            "default": "compatibility-validation-1.0.0"
          },
          "bank_version": {
            "type": "string",
            "title": "Bank Version"
          },
          "bank_fingerprint": {
            "type": "string",
            "title": "Bank Fingerprint"
          },
          "protocol": {
            "$ref": "#/components/schemas/StudyProtocolConfig"
          },
          "preregistration_uri": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Preregistration Uri"
          },
          "ethics_approval_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ethics Approval Reference"
          },
          "consent_version": {
            "type": "string",
            "title": "Consent Version"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "study_id",
          "title",
          "slug",
          "bank_version",
          "bank_fingerprint",
          "protocol",
          "consent_version",
          "created_at"
        ],
        "title": "StudyRecord"
      },
      "SuggestThemesRequest": {
        "properties": {
          "person1": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BirthInput"
              },
              {
                "type": "null"
              }
            ],
            "description": "User's birth data. When absent, themes are suggested from the behavioral profile alone."
          },
          "person2": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BirthInput"
              },
              {
                "type": "null"
              }
            ],
            "description": "Partner's birth data. When present, synastry signals refine the suggestions."
          },
          "relationship_stage": {
            "type": "string",
            "title": "Relationship Stage",
            "description": "Relationship stage: considering, engaged, married, reconnecting, unsure.",
            "default": "considering"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "SuggestThemesRequest"
      },
      "SuggestedConcern": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable concern id (e.g. 'family_pressure')."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Human-readable label for the chip."
          },
          "rationale": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rationale",
            "description": "Short rationale for why this concern is suggested given the charts/context. Hidden from the UI by default; the UI may surface it as a tooltip."
          },
          "related_dimensions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Related Dimensions",
            "description": "Dimension keys this concern tends to address."
          }
        },
        "type": "object",
        "required": [
          "id",
          "label"
        ],
        "title": "SuggestedConcern",
        "description": "One suggested concern chip."
      },
      "SynastryRequest": {
        "properties": {
          "person1": {
            "$ref": "#/components/schemas/BirthInput"
          },
          "person2": {
            "$ref": "#/components/schemas/BirthInput"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "person1",
          "person2"
        ],
        "title": "SynastryRequest"
      },
      "TarotCard": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name"
          },
          "number": {
            "type": "integer",
            "title": "Number"
          },
          "keywords": {
            "type": "string",
            "title": "Keywords"
          },
          "position": {
            "type": "string",
            "title": "Position"
          },
          "is_reversed": {
            "type": "boolean",
            "title": "Is Reversed"
          },
          "meaning": {
            "type": "string",
            "title": "Meaning"
          }
        },
        "type": "object",
        "required": [
          "name",
          "number",
          "keywords",
          "position",
          "is_reversed",
          "meaning"
        ],
        "title": "TarotCard"
      },
      "TarotRequest": {
        "properties": {
          "question": {
            "type": "string",
            "maxLength": 500,
            "title": "Question",
            "default": ""
          },
          "spread": {
            "type": "string",
            "enum": [
              "single",
              "three_card",
              "celtic"
            ],
            "title": "Spread",
            "default": "three_card"
          },
          "seed": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Seed",
            "description": "Optional seed for deterministic draw"
          }
        },
        "type": "object",
        "title": "TarotRequest"
      },
      "TarotResponse": {
        "properties": {
          "question": {
            "type": "string",
            "title": "Question"
          },
          "spread": {
            "type": "string",
            "title": "Spread"
          },
          "cards": {
            "items": {
              "$ref": "#/components/schemas/TarotCard"
            },
            "type": "array",
            "title": "Cards"
          },
          "summary": {
            "type": "string",
            "title": "Summary"
          },
          "disclaimer": {
            "type": "string",
            "title": "Disclaimer"
          }
        },
        "type": "object",
        "required": [
          "question",
          "spread",
          "cards",
          "summary",
          "disclaimer"
        ],
        "title": "TarotResponse"
      },
      "UnlockCodeCreateRequest": {
        "properties": {
          "duration_days": {
            "type": "integer",
            "maximum": 365.0,
            "minimum": 1.0,
            "title": "Duration Days",
            "default": 30
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Note"
          }
        },
        "type": "object",
        "title": "UnlockCodeCreateRequest"
      },
      "UnlockCodeCreateResponse": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code"
          },
          "duration_days": {
            "type": "integer",
            "title": "Duration Days"
          },
          "created_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created By"
          },
          "created_at": {
            "type": "string",
            "title": "Created At"
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note"
          },
          "redeemed_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Redeemed By"
          },
          "redeemed_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Redeemed At"
          }
        },
        "type": "object",
        "required": [
          "code",
          "duration_days",
          "created_at"
        ],
        "title": "UnlockCodeCreateResponse"
      },
      "UploadAssessmentOut-Input": {
        "properties": {
          "status": {
            "$ref": "#/components/schemas/UploadStatus"
          },
          "error_code": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PalmistryErrorCode"
              },
              {
                "type": "null"
              }
            ],
            "description": "Machine-readable error / degraded-state code. Set when status is not 'acceptable'."
          },
          "quality": {
            "$ref": "#/components/schemas/QualityAssessmentOut"
          },
          "image_metadata": {
            "$ref": "#/components/schemas/ImageMetadataOut"
          },
          "assessed_at": {
            "type": "string",
            "title": "Assessed At",
            "description": "ISO-8601 UTC timestamp at which the assessment was made."
          },
          "can_retry": {
            "type": "boolean",
            "title": "Can Retry",
            "description": "True when the user can retry with a better upload."
          },
          "saveable": {
            "type": "boolean",
            "title": "Saveable",
            "description": "True when the assessment is save-ready for later history / reopen slices. Currently true for 'acceptable' uploads; later slices may broaden this."
          },
          "image_data_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Image Data Url",
            "description": "Base64 data URL of the processed palm image (a JPEG thumbnail, max 400px on the long side). Present for acceptable and weak uploads so the frontend can display the palm photo in the report and persist it with the saved reading. None for rejected uploads and when image processing fails before encoding."
          }
        },
        "type": "object",
        "required": [
          "status",
          "quality",
          "image_metadata",
          "assessed_at",
          "can_retry",
          "saveable"
        ],
        "title": "UploadAssessmentOut",
        "description": "The complete upload assessment block.\n\nThe :attr:`status` field is the source of truth for the\nupload verdict. When :attr:`status` is ``acceptable``, the\nresponse's :attr:`report` field is present. When\n:attr:`status` is ``weak`` or ``rejected``, the\n:attr:`report` field is ``None`` and this block carries\nthe typed weak / rejected reasons and retry guidance."
      },
      "UploadAssessmentOut-Output": {
        "properties": {
          "status": {
            "$ref": "#/components/schemas/UploadStatus"
          },
          "error_code": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PalmistryErrorCode"
              },
              {
                "type": "null"
              }
            ],
            "description": "Machine-readable error / degraded-state code. Set when status is not 'acceptable'."
          },
          "quality": {
            "$ref": "#/components/schemas/QualityAssessmentOut"
          },
          "image_metadata": {
            "$ref": "#/components/schemas/ImageMetadataOut"
          },
          "assessed_at": {
            "type": "string",
            "title": "Assessed At",
            "description": "ISO-8601 UTC timestamp at which the assessment was made."
          },
          "can_retry": {
            "type": "boolean",
            "title": "Can Retry",
            "description": "True when the user can retry with a better upload."
          },
          "saveable": {
            "type": "boolean",
            "title": "Saveable",
            "description": "True when the assessment is save-ready for later history / reopen slices. Currently true for 'acceptable' uploads; later slices may broaden this."
          },
          "image_data_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Image Data Url",
            "description": "Base64 data URL of the processed palm image (a JPEG thumbnail, max 400px on the long side). Present for acceptable and weak uploads so the frontend can display the palm photo in the report and persist it with the saved reading. None for rejected uploads and when image processing fails before encoding."
          }
        },
        "type": "object",
        "required": [
          "status",
          "quality",
          "image_metadata",
          "assessed_at",
          "can_retry",
          "saveable"
        ],
        "title": "UploadAssessmentOut",
        "description": "The complete upload assessment block.\n\nThe :attr:`status` field is the source of truth for the\nupload verdict. When :attr:`status` is ``acceptable``, the\nresponse's :attr:`report` field is present. When\n:attr:`status` is ``weak`` or ``rejected``, the\n:attr:`report` field is ``None`` and this block carries\nthe typed weak / rejected reasons and retry guidance."
      },
      "UploadStatus": {
        "type": "string",
        "enum": [
          "acceptable",
          "weak",
          "rejected"
        ],
        "title": "UploadStatus",
        "description": "High-level status of the upload assessment.\n\n* ``acceptable`` \u2014 every quality check passed; the full report\n  is present in the response. The ``report`` block is NOT None.\n* ``weak`` \u2014 the image is processable but does not meet one or\n  more quality thresholds. The ``report`` block is None; the\n  ``upload`` block carries the typed weak reasons and\n  retry guidance.\n* ``rejected`` \u2014 the image is processable but the content does\n  not contain a palm (e.g., it's a landscape, a face, a\n  drawing, or a back-of-hand photo). The ``report`` block is\n  None; the ``upload`` block carries the typed rejection\n  reason and retry guidance."
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "VarshphalRequest": {
        "properties": {
          "birth_date": {
            "type": "string",
            "title": "Birth Date",
            "description": "DD/MM/YYYY"
          },
          "birth_time": {
            "type": "string",
            "title": "Birth Time",
            "description": "HH:MM"
          },
          "latitude": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Latitude"
          },
          "longitude": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Longitude"
          },
          "timezone_offset": {
            "type": "number",
            "maximum": 14.0,
            "minimum": -14.0,
            "title": "Timezone Offset",
            "description": "Timezone offset supplied by the selected place."
          },
          "timezone_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone Id"
          },
          "target_year": {
            "type": "integer",
            "maximum": 2100.0,
            "minimum": 1900.0,
            "title": "Target Year",
            "default": 2026
          }
        },
        "type": "object",
        "required": [
          "birth_date",
          "birth_time",
          "latitude",
          "longitude",
          "timezone_offset"
        ],
        "title": "VarshphalRequest"
      },
      "VarshphalResponse": {
        "properties": {
          "target_year": {
            "type": "integer",
            "title": "Target Year"
          },
          "ascendant_rashi": {
            "type": "string",
            "title": "Ascendant Rashi"
          },
          "muntha_rashi": {
            "type": "string",
            "title": "Muntha Rashi"
          },
          "muntha_house": {
            "type": "integer",
            "title": "Muntha House"
          },
          "year_lord": {
            "type": "string",
            "title": "Year Lord"
          },
          "key_predictions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Key Predictions"
          },
          "favorable_periods": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Favorable Periods"
          },
          "caution_periods": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Caution Periods"
          },
          "disclaimer": {
            "type": "string",
            "title": "Disclaimer"
          }
        },
        "type": "object",
        "required": [
          "target_year",
          "ascendant_rashi",
          "muntha_rashi",
          "muntha_house",
          "year_lord",
          "key_predictions",
          "favorable_periods",
          "caution_periods",
          "disclaimer"
        ],
        "title": "VarshphalResponse"
      },
      "WaitlistUpdateRequest": {
        "properties": {
          "waitlisted": {
            "type": "boolean",
            "title": "Waitlisted",
            "default": true
          }
        },
        "type": "object",
        "title": "WaitlistUpdateRequest"
      },
      "WithdrawalSubmission": {
        "properties": {
          "participant_token": {
            "type": "string",
            "title": "Participant Token"
          },
          "reason_category": {
            "type": "string",
            "enum": [
              "participant_request",
              "consent_withdrawn",
              "data_quality",
              "protocol_violation",
              "other"
            ],
            "title": "Reason Category"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "participant_token",
          "reason_category"
        ],
        "title": "WithdrawalSubmission"
      },
      "YogaOut": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name"
          },
          "sanskrit_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sanskrit Name"
          },
          "strength": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Strength"
          },
          "description": {
            "type": "string",
            "title": "Description"
          }
        },
        "type": "object",
        "required": [
          "name",
          "description"
        ],
        "title": "YogaOut"
      },
      "app__schemas__compatibility__InputConfidenceOut": {
        "properties": {
          "source": {
            "type": "string",
            "title": "Source"
          },
          "time_precision_minutes": {
            "type": "integer",
            "title": "Time Precision Minutes"
          },
          "has_place_resolved": {
            "type": "boolean",
            "title": "Has Place Resolved"
          },
          "has_timezone_validated": {
            "type": "boolean",
            "title": "Has Timezone Validated"
          },
          "note": {
            "type": "string",
            "title": "Note"
          }
        },
        "type": "object",
        "required": [
          "source",
          "time_precision_minutes",
          "has_place_resolved",
          "has_timezone_validated",
          "note"
        ],
        "title": "InputConfidenceOut",
        "description": "Honest disclosure of input quality.\n\nMirrors the Kundli :class:`app.schemas.kundli.InputConfidenceOut`\nblock so the two schemas surface the same confidence language\non the wire."
      },
      "app__schemas__compatibility__InterpretationStatus": {
        "type": "string",
        "enum": [
          "complete",
          "partial",
          "unavailable"
        ],
        "title": "InterpretationStatus",
        "description": "Closed literal for the interpretation status field.\n\nIn M004 S01 the LLM narrative layer is not yet wired; the\ncompatibility report always emits ``unavailable``. The enum is\nclosed so the future narrative layer can fill ``complete`` or\n``partial`` without changing the wire shape."
      },
      "app__schemas__compatibility__ScenarioAnswer": {
        "properties": {
          "scenario_id": {
            "type": "string",
            "title": "Scenario Id"
          },
          "selected_option": {
            "type": "string",
            "title": "Selected Option"
          },
          "least_likely_option": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Least Likely Option"
          },
          "phase": {
            "type": "string",
            "enum": [
              "self",
              "partner"
            ],
            "title": "Phase",
            "description": "Assessment phase this answer belongs to. 'self' \u2014 Person 1 answers about their OWN likely behaviour. 'partner' \u2014 Person 1 answers about Person 2's likely behaviour."
          },
          "respondent_role": {
            "type": "string",
            "enum": [
              "person1",
              "person2"
            ],
            "title": "Respondent Role",
            "description": "Who personally selected this answer. This is deliberately separate from phase: phase describes the question perspective, while respondent_role proves whether the evidence came from person 1 or person 2. Legacy answers default to person1 so owner observations can never be upgraded into person2 self-report evidence.",
            "default": "person1"
          },
          "selected_option_text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Selected Option Text",
            "description": "Text of the selected option, retained so synthesis/reports can read the answer without the original scenario payload."
          },
          "observation": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "observed",
                  "guessed"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Observation",
            "description": "For partner-assessment answers: whether the behaviour was directly observed or guessed. Lets the synthesis weigh partner answers accordingly."
          },
          "observation_frequency": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "rarely",
                  "sometimes",
                  "often",
                  "always"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Observation Frequency",
            "description": "For partner-assessment answers (fixpartner.md \u00a72.3): how often the user has seen this behaviour. Used to downweight answers marked 'rarely' or 'guessed'."
          }
        },
        "type": "object",
        "required": [
          "scenario_id",
          "selected_option",
          "phase"
        ],
        "title": "ScenarioAnswer",
        "description": "A user's answer to a scenario question.\n\nThe ``phase``, ``selected_option_text`` and ``observation`` fields\nare additive and optional so already-saved answers still load.\nThey let the Dampatya synthesis interpret answers without\nre-deriving phase from scenario evidence themes and without\ncross-referencing the option label back to its text:\n\n* ``phase`` persists explicitly which assessment phase the answer\n  belongs to (``'self'`` or ``'partner'``). When absent the\n  synthesis falls back to inferring phase from the scenario\n  evidence theme for backward compatibility.\n* ``selected_option_text`` carries the text of the chosen option\n  so downstream synthesis and reports can read the answer without\n  the original scenario payload.\n* ``observation`` records whether a partner-assessment answer\n  reflects directly observed behaviour (``'observed'``) or a guess\n  (``'guessed'``), so the synthesis can weigh partner answers\n  accordingly. Mainly relevant for the ``'partner'`` phase."
      },
      "app__schemas__kundli__DisclaimerMetadataOut": {
        "properties": {
          "scope": {
            "type": "string",
            "title": "Scope",
            "description": "Scope of the disclaimer (which surface it applies to).",
            "default": "kundli_report"
          },
          "version": {
            "type": "string",
            "title": "Version"
          },
          "last_updated": {
            "type": "string",
            "title": "Last Updated"
          },
          "short_text": {
            "type": "string",
            "title": "Short Text",
            "description": "Plain-text summary suitable for inline UI display. Backend-owned; do not modify client-side."
          },
          "full_text_endpoint": {
            "type": "string",
            "title": "Full Text Endpoint",
            "description": "Endpoint that returns the full disclaimer text for this version.",
            "default": "/api/v1/legal/disclaimer"
          }
        },
        "type": "object",
        "required": [
          "version",
          "last_updated",
          "short_text"
        ],
        "title": "DisclaimerMetadataOut",
        "description": "Backend-owned disclaimer metadata.\n\nThe legal copy is owned by ``app.legal.disclaimer``; this block\nsurfaces its version, last-updated date, and a short summary so\nthe UI can show the right version without copying the full text\nclient-side. The full text remains fetchable from the\n``/api/v1/legal/disclaimer`` endpoint."
      },
      "app__schemas__kundli__InputConfidenceOut": {
        "properties": {
          "source": {
            "type": "string",
            "title": "Source"
          },
          "time_precision_minutes": {
            "type": "integer",
            "title": "Time Precision Minutes"
          },
          "has_place_resolved": {
            "type": "boolean",
            "title": "Has Place Resolved"
          },
          "has_timezone_validated": {
            "type": "boolean",
            "title": "Has Timezone Validated"
          },
          "note": {
            "type": "string",
            "title": "Note"
          }
        },
        "type": "object",
        "required": [
          "source",
          "time_precision_minutes",
          "has_place_resolved",
          "has_timezone_validated",
          "note"
        ],
        "title": "InputConfidenceOut"
      },
      "app__schemas__kundli__InterpretationStatus": {
        "type": "string",
        "enum": [
          "complete",
          "partial",
          "unavailable"
        ],
        "title": "InterpretationStatus",
        "description": "Honest disclosure of narrative interpretation availability.\n\nThe deterministic chart is always present in the response. The\ninterpretation is an optional narrative layer that the LLM may\nfail to deliver (rate limit, quota, transient outage). The status\nfield lets the frontend render a credible report in every state\nwithout inventing a chart or pretending interpretation succeeded\nwhen it did not.\n\n* ``complete``   \u2014 narrative interpretation succeeded and is fully\n  attached.\n* ``partial``    \u2014 at least one required narrative section is\n  missing or the LLM returned a degraded result. The structured\n  chart is still complete; the report flags the gap explicitly.\n* ``unavailable`` \u2014 the LLM call failed outright (no narrative\n  text returned). The deterministic chart is unchanged."
      },
      "app__schemas__kundli__TrustMetadataOut": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-report-flow-1.0.0"
          },
          "composed_at": {
            "type": "string",
            "title": "Composed At",
            "description": "ISO-8601 UTC timestamp at which the backend composed this report flow response."
          },
          "engine_name": {
            "type": "string",
            "title": "Engine Name"
          },
          "engine_version": {
            "type": "string",
            "title": "Engine Version"
          },
          "engine_implementation": {
            "type": "string",
            "title": "Engine Implementation"
          },
          "calculation_standard": {
            "type": "string",
            "title": "Calculation Standard",
            "description": "Ayanamsa + house system declared by the engine, e.g. 'Lahiri / Whole Sign'."
          },
          "ephemeris_provider": {
            "type": "string",
            "title": "Ephemeris Provider"
          },
          "determinism_guarantee": {
            "type": "string",
            "title": "Determinism Guarantee"
          },
          "input_source": {
            "type": "string",
            "title": "Input Source",
            "description": "Origin of the birth input \u2014 passed through from the engine's InputConfidence.source (e.g. 'user_asserted')."
          },
          "truth_provenance": {
            "type": "string",
            "title": "Truth Provenance",
            "description": "Stable identifier for the chart-provenance chain. Clients should compare this string for cache invalidation.",
            "default": "deterministic_engine_v2"
          }
        },
        "type": "object",
        "required": [
          "composed_at",
          "engine_name",
          "engine_version",
          "engine_implementation",
          "calculation_standard",
          "ephemeris_provider",
          "determinism_guarantee",
          "input_source"
        ],
        "title": "TrustMetadataOut",
        "description": "Backend-owned trust metadata for the report-flow surface.\n\nDistinct from :class:`EngineMetadataOut` (which describes the\ncalculation engine) and from :class:`InputConfidenceOut` (which\ndescribes the input). This block tells the client what to trust\nabout *this* report, end-to-end. It is composed by the backend\nso the UI cannot drift the wording."
      },
      "app__schemas__palmistry__DisclaimerMetadataOut": {
        "properties": {
          "scope": {
            "type": "string",
            "title": "Scope",
            "description": "Scope of the disclaimer (which surface it applies to).",
            "default": "palmistry_report"
          },
          "version": {
            "type": "string",
            "title": "Version"
          },
          "last_updated": {
            "type": "string",
            "title": "Last Updated"
          },
          "short_text": {
            "type": "string",
            "title": "Short Text",
            "description": "Plain-text summary suitable for inline UI display. Backend-owned; do not modify client-side."
          },
          "full_text_endpoint": {
            "type": "string",
            "title": "Full Text Endpoint",
            "description": "Endpoint that returns the full disclaimer text for this version.",
            "default": "/api/v1/legal/disclaimer"
          }
        },
        "type": "object",
        "required": [
          "version",
          "last_updated",
          "short_text"
        ],
        "title": "DisclaimerMetadataOut",
        "description": "Backend-owned disclaimer metadata.\n\nThe full disclaimer copy is owned by\n``app.legal.disclaimer``; this block surfaces its version,\nlast-updated date, and a short summary so the UI can show\nthe right version without copying the full text client-side.\nThe full text remains fetchable from\n``/api/v1/legal/disclaimer``."
      },
      "app__schemas__palmistry__TrustMetadataOut": {
        "properties": {
          "schema_version": {
            "type": "string",
            "title": "Schema Version",
            "default": "v2-palmistry-report-flow-1.0.0"
          },
          "composed_at": {
            "type": "string",
            "title": "Composed At",
            "description": "ISO-8601 UTC timestamp at which the backend composed this report-flow response."
          },
          "service_name": {
            "type": "string",
            "title": "Service Name",
            "description": "Stable service identifier. Bumped on breaking interpretation changes.",
            "default": "palmistry.vision_service"
          },
          "service_version": {
            "type": "string",
            "title": "Service Version",
            "description": "Service version. Bumped on breaking changes to the interpretation pipeline.",
            "default": "1.0.0"
          },
          "vision_model": {
            "type": "string",
            "title": "Vision Model",
            "description": "The vision model used for the interpretation call."
          },
          "vision_provider": {
            "type": "string",
            "title": "Vision Provider",
            "description": "The vision provider used for the interpretation call.",
            "default": "minimax_vision"
          },
          "image_quality_assessment": {
            "type": "string",
            "title": "Image Quality Assessment",
            "description": "Provenance of the image quality assessment. 'backend_local' means the quality grade and score were computed from the upload bytes alone, with no VLM call. This is the deterministic part of the response.",
            "default": "backend_local"
          },
          "interpretation_provenance": {
            "type": "string",
            "title": "Interpretation Provenance",
            "description": "Stable identifier for the interpretation chain. Clients compare this string for cache invalidation.",
            "default": "vision_model_v1"
          },
          "determinism_guarantee": {
            "type": "string",
            "title": "Determinism Guarantee",
            "description": "Palmistry interpretation is best-effort vision-model output, not deterministic. The image quality assessment IS deterministic; the interpretation is not.",
            "default": "best_effort_vision_model"
          }
        },
        "type": "object",
        "required": [
          "composed_at",
          "vision_model"
        ],
        "title": "TrustMetadataOut",
        "description": "Backend-owned trust metadata for the palmistry report flow.\n\nDistinct from the Kundli ``TrustMetadataOut`` (which describes\na deterministic engine). Palmistry interpretation is\nbest-effort vision-model output; the trust block is honest\nabout that. The :attr:`image_quality_assessment` field is\nthe only deterministic piece \u2014 the quality grade and score\nare computed from the upload bytes alone, before the VLM\nruns."
      },
      "app__schemas__scenario_builder__ScenarioAnswer": {
        "properties": {
          "question_id": {
            "type": "string",
            "title": "Question Id"
          },
          "selected_label": {
            "type": "string",
            "title": "Selected Label",
            "description": "The label of the selected option (e.g. 'A')."
          },
          "selected_text": {
            "type": "string",
            "title": "Selected Text",
            "description": "The text of the selected option."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Optional free-text notes the user added."
          },
          "confidence": {
            "type": "integer",
            "maximum": 5.0,
            "minimum": 1.0,
            "title": "Confidence",
            "description": "How sure the user is about this answer, 1-5.",
            "default": 3
          },
          "least_likely_option": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Least Likely Option",
            "description": "Optional second signal; useful for forced-choice scoring to reduce socially desirable answering."
          }
        },
        "type": "object",
        "required": [
          "question_id",
          "selected_label",
          "selected_text"
        ],
        "title": "ScenarioAnswer",
        "description": "A user's answer to a scenario question."
      }
    }
  }
}